Skip to content

Commit

Permalink
refactor: reduce method complexity in InMemoryStorage (#592)
Browse files Browse the repository at this point in the history
* Use StringComparison.Ordinal for checking friendlyName
* Refactor InMemoryStorage to reduce method complexity
* Remove pragma warning for MA0051 (Method is too long) because this rule is disabled in .editorconfig
  • Loading branch information
vbreuss authored May 5, 2024
1 parent d0d0039 commit 09aaaf3
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ internal static void CreateFromDirectory(IFileSystem fileSystem,
/// <see
/// href="https://github.com/dotnet/runtime/blob/v6.0.10/src/libraries/System.IO.Compression.ZipFile/src/System/IO/Compression/ZipFile.Create.cs#L354" />
/// </remarks>
#pragma warning disable MA0051 // Method is too long
internal static void CreateFromDirectory(
IFileSystem fileSystem,
string sourceDirectoryName,
Expand Down Expand Up @@ -192,7 +191,6 @@ internal static void CreateFromDirectory(
}
}
}
#pragma warning restore MA0051 // Method is too long
#endif

internal static void ExtractRelativeToDirectory(this IZipArchiveEntry source,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ internal static string GetSubdirectoryPath(this MockFileSystem fileSystem,
{
if (fileSystem.Execute.Path.IsPathRooted(givenPath))
{
if (friendlyName is "/." or "/..")
if (friendlyName.Equals("/.", StringComparison.Ordinal) ||
friendlyName.Equals("/..", StringComparison.Ordinal))
{
return friendlyName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ public static string TranslateWin32Expression(string? expression)
// set of contiguous DOS_QMs.
// DOS_DOT matches either a . or zero characters beyond name string.

#pragma warning disable MA0051 // Method is too long
private static bool MatchPattern(string expression, string name, bool ignoreCase,
bool useExtendedWildcards)
{
Expand Down Expand Up @@ -462,6 +461,5 @@ private static bool MatchPattern(string expression, string name, bool ignoreCase

return currentState == maxState;
}
#pragma warning restore MA0051 // Method is too long
}
#endif
163 changes: 107 additions & 56 deletions Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,58 +226,8 @@ public IEnumerable<IStorageLocation> EnumerateLocations(
_fileSystem.Execute.StringComparisonMode) &&
!x.Key.Equals(location)))
{
string? parentPath =
_fileSystem.Execute.Path.GetDirectoryName(
item.Key.FullPath.TrimEnd(_fileSystem.Execute.Path
.DirectorySeparatorChar));
if (parentPath == null)
{
continue;
}

if (!parentPath.Equals(fullPathWithoutTrailingSlash,
_fileSystem.Execute.StringComparisonMode))
{
#if NETSTANDARD2_1
if (!enumerationOptions.RecurseSubdirectories)
{
continue;
}
#else
int recursionDepth = parentPath
.Substring(fullPathWithoutTrailingSlash.Length)
.Count(x => x == _fileSystem.Execute.Path.DirectorySeparatorChar);
if (!enumerationOptions.RecurseSubdirectories ||
recursionDepth > enumerationOptions.MaxRecursionDepth)
{
continue;
}
#endif
}

#if NET8_0_OR_GREATER
FileAttributes defaultAttributeToSkip = FileAttributes.None;
#else
FileAttributes defaultAttributeToSkip = 0;
#endif
if (enumerationOptions.AttributesToSkip != defaultAttributeToSkip &&
item.Value.Attributes.HasFlag(enumerationOptions.AttributesToSkip))
{
continue;
}

if (!_fileSystem.AccessControlStrategy
.IsAccessGranted(item.Key.FullPath, item.Value.Extensibility))
{
if (!enumerationOptions.IgnoreInaccessible)
{
throw ExceptionFactory.AccessToPathDenied(item.Key.FullPath);
}

continue;
}

if (type.HasFlag(item.Value.Type))
if (type.HasFlag(item.Value.Type) &&
IncludeItemInEnumeration(item, fullPathWithoutTrailingSlash, enumerationOptions))
{
string name = _fileSystem.Execute.Path.GetFileName(item.Key.FullPath);
if (EnumerationOptionsHelper.MatchesPattern(
Expand Down Expand Up @@ -443,7 +393,6 @@ public IStorageContainer GetOrCreateContainer(
}

/// <inheritdoc cref="IStorage.Replace(IStorageLocation, IStorageLocation, IStorageLocation?, bool)" />
#pragma warning disable MA0051 // Method is too long
public IStorageLocation? Replace(IStorageLocation source,
IStorageLocation destination,
IStorageLocation? backup,
Expand Down Expand Up @@ -535,7 +484,6 @@ public IStorageContainer GetOrCreateContainer(
}
}
}
#pragma warning restore MA0051 // Method is too long

#if FEATURE_FILESYSTEM_LINK
/// <inheritdoc cref="IStorage.ResolveLinkTarget(IStorageLocation, bool)" />
Expand Down Expand Up @@ -702,7 +650,111 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location)
}
}

#pragma warning disable MA0051 // Method is too long
#if NETSTANDARD2_1
/// <summary>
/// Checks, if the <paramref name="item" /> should be included during enumeration, depending on the
/// <paramref name="directoryPath" /> to enumerate and the <paramref name="enumerationOptions" />.
/// </summary>
/// <remarks>
/// <see cref="EnumerationOptions.RecurseSubdirectories" />:<br />
/// If not set, only items directly in <paramref name="directoryPath" /> are included
/// <para />
/// <see cref="EnumerationOptions.AttributesToSkip" />:<br />
/// If set, only items with the given attributes are included
/// <para />
/// If the item is not granted access by the <see cref="IAccessControlStrategy" />:<br />
/// When <see cref="EnumerationOptions.IgnoreInaccessible" /> is set, the item is ignored, otherwise this method throws
/// an <see cref="UnauthorizedAccessException" />.
/// </remarks>
/// <exception cref="UnauthorizedAccessException">
/// When an item is not granted access by the
/// <see cref="IAccessControlStrategy" /> and <see cref="EnumerationOptions.IgnoreInaccessible" /> is not set to
/// <see langword="true" />.
/// </exception>
#else
/// <summary>
/// Checks, if the <paramref name="item" /> should be included during enumeration, depending on the
/// <paramref name="directoryPath" /> to enumerate and the <paramref name="enumerationOptions" />.
/// </summary>
/// <remarks>
/// <see cref="EnumerationOptions.RecurseSubdirectories" />:<br />
/// If not set, only items directly in <paramref name="directoryPath" /> are included
/// <para />
/// <see cref="EnumerationOptions.MaxRecursionDepth" />:<br />
/// If set, only items within the given value of recursion are included
/// <para />
/// <see cref="EnumerationOptions.AttributesToSkip" />:<br />
/// If set, only items with the given attributes are included
/// <para />
/// If the item is not granted access by the <see cref="IAccessControlStrategy" />:<br />
/// When <see cref="EnumerationOptions.IgnoreInaccessible" /> is set, the item is ignored, otherwise this method throws
/// an <see cref="UnauthorizedAccessException" />.
/// </remarks>
/// <exception cref="UnauthorizedAccessException">
/// When an item is not granted access by the
/// <see cref="IAccessControlStrategy" /> and <see cref="EnumerationOptions.IgnoreInaccessible" /> is not set to
/// <see langword="true" />.
/// </exception>
#endif
private bool IncludeItemInEnumeration(
KeyValuePair<IStorageLocation, IStorageContainer> item,
string directoryPath,
EnumerationOptions enumerationOptions)
{
string? parentPath =
_fileSystem.Execute.Path.GetDirectoryName(
item.Key.FullPath.TrimEnd(_fileSystem.Execute.Path
.DirectorySeparatorChar));
if (parentPath == null)
{
return false;
}

if (!parentPath.Equals(directoryPath,
_fileSystem.Execute.StringComparisonMode))
{
#if NETSTANDARD2_1
if (!enumerationOptions.RecurseSubdirectories)
{
return false;
}
#else
int recursionDepth = parentPath
.Substring(directoryPath.Length)
.Count(x => x == _fileSystem.Execute.Path.DirectorySeparatorChar);
if (!enumerationOptions.RecurseSubdirectories ||
recursionDepth > enumerationOptions.MaxRecursionDepth)
{
return false;
}
#endif
}

#if NET8_0_OR_GREATER
FileAttributes defaultAttributeToSkip = FileAttributes.None;
#else
FileAttributes defaultAttributeToSkip = 0;
#endif
if (enumerationOptions.AttributesToSkip != defaultAttributeToSkip &&
item.Value.Attributes.HasFlag(enumerationOptions.AttributesToSkip))
{
return false;
}

if (!_fileSystem.AccessControlStrategy
.IsAccessGranted(item.Key.FullPath, item.Value.Extensibility))
{
if (!enumerationOptions.IgnoreInaccessible)
{
throw ExceptionFactory.AccessToPathDenied(item.Key.FullPath);
}

return false;
}

return true;
}

private IStorageLocation? MoveInternal(IStorageLocation source,
IStorageLocation destination,
bool overwrite,
Expand Down Expand Up @@ -791,7 +843,6 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location)

return source;
}
#pragma warning restore MA0051 // Method is too long

#if FEATURE_FILESYSTEM_LINK
private IStorageLocation? ResolveFinalLinkTarget(IStorageContainer container,
Expand Down
2 changes: 0 additions & 2 deletions Tests/Testably.Abstractions.Parity.Tests/Net48ParityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public class Net48ParityTests : ParityTests
/// <para />
/// As we only support .NET Standard 2.0 these are blacklisted.
/// </summary>
#pragma warning disable MA0051 // Method is too long
public Net48ParityTests(ITestOutputHelper testOutputHelper)
: base(new TestHelpers.Parity(), testOutputHelper)
{
Expand Down Expand Up @@ -178,6 +177,5 @@ public Net48ParityTests(ITestOutputHelper testOutputHelper)

#endregion
}
#pragma warning restore MA0051 // Method is too long
}
#endif

0 comments on commit 09aaaf3

Please sign in to comment.