Skip to content

Commit

Permalink
fix: prefix bug in MockDirectory.EnumerateDirectories (#815) (#1046)
Browse files Browse the repository at this point in the history
Fixes #815 

`System.IO.Directory.EnumerateDirectories(path)` guarantees that returned paths are always prefixed with the value provided in the `path` parameter. However, `MockDirectory.EnumerateDirectories` always returned absolute paths, leading to an inconsistent behavior (e.g. when using relative paths).

We now check returned paths from `MockDirectory.EnumerateDirectories` and provide the proper prefix path.
  • Loading branch information
Phoenox authored Dec 5, 2023
1 parent ef9d4d1 commit 1d67fb1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -627,39 +627,41 @@ public override void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc)
/// <inheritdoc />
public override IEnumerable<string> EnumerateDirectories(string path)
{
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");

return EnumerateDirectories(path, "*");
}

/// <inheritdoc />
public override IEnumerable<string> EnumerateDirectories(string path, string searchPattern)
{
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");

return EnumerateDirectories(path, searchPattern, SearchOption.TopDirectoryOnly);
}

/// <inheritdoc />
public override IEnumerable<string> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption)
{
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
var originalPath = path;
path = path.TrimSlashes();
path = mockFileDataAccessor.Path.GetFullPath(path);
return GetFilesInternal(mockFileDataAccessor.AllDirectories, path, searchPattern, searchOption)
.Where(p => !mockFileDataAccessor.StringOperations.Equals(p, path));
.Where(p => !mockFileDataAccessor.StringOperations.Equals(p, path))
.Select(p => FixPrefix(p, originalPath));
}


private string FixPrefix(string path, string originalPath)
{
var normalizedOriginalPath = mockFileDataAccessor.Path.GetFullPath(originalPath);
var pathWithoutOriginalPath = path.Substring(normalizedOriginalPath.Length)
.TrimStart(mockFileDataAccessor.Path.DirectorySeparatorChar);
return mockFileDataAccessor.Path.Combine(originalPath, pathWithoutOriginalPath);
}

#if FEATURE_ENUMERATION_OPTIONS
/// <inheritdoc />
public override IEnumerable<string> EnumerateDirectories(string path, string searchPattern, EnumerationOptions enumerationOptions)
{
var searchOption = enumerationOptions.RecurseSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
path = path.TrimSlashes();
path = mockFileDataAccessor.Path.GetFullPath(path);
return GetFilesInternal(mockFileDataAccessor.AllDirectories, path, searchPattern, searchOption)
.Where(p => !mockFileDataAccessor.StringOperations.Equals(p, path));
return EnumerateDirectories(path, searchPattern, searchOption);
}
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ public void MockDirectory_GetDirectories_WithTopDirectories_ShouldOnlyReturnTopD
fileSystem.AddFile(XFS.Path(@"C:\Folder\.foo\bar"), new MockFileData(string.Empty));

// Act
var actualResult = fileSystem.Directory.GetDirectories(XFS.Path(@"c:\Folder\"), "*.foo");
var actualResult = fileSystem.Directory.GetDirectories(XFS.Path(@"C:\Folder\"), "*.foo");

// Assert
Assert.That(actualResult, Is.EquivalentTo(new[] { XFS.Path(@"C:\Folder\.foo"), XFS.Path(@"C:\Folder\foo.foo") }));
Expand Down Expand Up @@ -1321,7 +1321,7 @@ public void MockDirectory_GetDirectories_RelativeDirectory_WithChildren_ShouldRe

// Assert
CollectionAssert.AreEqual(
new[] { XFS.Path(currentDirectory + @"\" + relativeDirPath + @"\child") },
new[] { XFS.Path(relativeDirPath + @"\child") },
actualResult
);
}
Expand Down Expand Up @@ -1353,7 +1353,7 @@ public void MockDirectory_GetDirectories_WithAllDirectories_ShouldReturnsAllMatc
fileSystem.AddFile(XFS.Path(@"C:\Folder\.foo\bar"), new MockFileData(string.Empty));

// Act
var actualResult = fileSystem.Directory.GetDirectories(XFS.Path(@"c:\Folder\"), "*.foo", SearchOption.AllDirectories);
var actualResult = fileSystem.Directory.GetDirectories(XFS.Path(@"C:\Folder\"), "*.foo", SearchOption.AllDirectories);

// Assert
Assert.That(actualResult, Is.EquivalentTo(new[] { XFS.Path(@"C:\Folder\.foo"), XFS.Path(@"C:\Folder\foo.foo"), XFS.Path(@"C:\Folder\.foo\.foo") }));
Expand Down Expand Up @@ -1415,7 +1415,7 @@ public void MockDirectory_EnumerateDirectories_WithTopDirectories_ShouldOnlyRetu
fileSystem.AddFile(XFS.Path(@"C:\Folder\.foo\bar"), new MockFileData(string.Empty));

// Act
var actualResult = fileSystem.Directory.EnumerateDirectories(XFS.Path(@"c:\Folder\"), "*.foo");
var actualResult = fileSystem.Directory.EnumerateDirectories(XFS.Path(@"C:\Folder\"), "*.foo");

// Assert
Assert.That(actualResult, Is.EquivalentTo(new[] { XFS.Path(@"C:\Folder\.foo"), XFS.Path(@"C:\Folder\foo.foo") }));
Expand All @@ -1439,7 +1439,7 @@ public void MockDirectory_EnumerateDirectories_WithEnumerationOptionsTopDirector
};

// Act
var actualResult = fileSystem.Directory.EnumerateDirectories(XFS.Path(@"c:\Folder\"), "*.foo", enumerationOptions);
var actualResult = fileSystem.Directory.EnumerateDirectories(XFS.Path(@"C:\Folder\"), "*.foo", enumerationOptions);

// Assert
Assert.That(actualResult, Is.EquivalentTo(new[] { XFS.Path(@"C:\Folder\.foo"), XFS.Path(@"C:\Folder\foo.foo") }));
Expand All @@ -1457,7 +1457,7 @@ public void MockDirectory_EnumerateDirectories_WithAllDirectories_ShouldReturnsA
fileSystem.AddFile(XFS.Path(@"C:\Folder\.foo\bar"), new MockFileData(string.Empty));

// Act
var actualResult = fileSystem.Directory.EnumerateDirectories(XFS.Path(@"c:\Folder\"), "*.foo", SearchOption.AllDirectories);
var actualResult = fileSystem.Directory.EnumerateDirectories(XFS.Path(@"C:\Folder\"), "*.foo", SearchOption.AllDirectories);

// Assert
Assert.That(actualResult, Is.EquivalentTo(new[] { XFS.Path(@"C:\Folder\.foo"), XFS.Path(@"C:\Folder\foo.foo"), XFS.Path(@"C:\Folder\.foo\.foo") }));
Expand Down Expand Up @@ -1486,6 +1486,26 @@ public void MockDirectory_EnumerateDirectories_ShouldThrowWhenPathIsNotMocked()
// Assert
Assert.Throws<DirectoryNotFoundException>(action);
}

[TestCaseSource(nameof(GetPrefixTestPaths))]
public void MockDirectory_EnumerateDirectories_ShouldReturnPathsPrefixedWithQueryPath(
string queryPath, string expectedPath)
{
var fileSystem = new MockFileSystem();
fileSystem.Directory.CreateDirectory("Folder/SubFolder");

var actualResult = fileSystem.Directory.EnumerateDirectories(queryPath);

CollectionAssert.AreEqual(new[] { expectedPath }, actualResult);
}

private static IEnumerable<object[]> GetPrefixTestPaths()
{
var sep = Path.DirectorySeparatorChar;
yield return new object[] { "Folder", $"Folder{sep}SubFolder" };
yield return new object[] { $"Folder{sep}", $"Folder{sep}SubFolder" };
yield return new object[] { $"Folder{sep}..{sep}.{sep}Folder", $"Folder{sep}..{sep}.{sep}Folder{sep}SubFolder" };
}

public static IEnumerable<object[]> GetPathsForMoving()
{
Expand Down

0 comments on commit 1d67fb1

Please sign in to comment.