Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,38 @@ public class InMemoryDirectoryInfo : DirectoryInfoBase
{
private static readonly char[] DirectorySeparators = new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
private readonly IEnumerable<string> _files;
private readonly StringComparison _comparisonType;

/// <summary>
/// Creates a new InMemoryDirectoryInfo with the root directory and files given.
/// Creates a new case-sensitive InMemoryDirectoryInfo with the root directory and files given.
/// </summary>
/// <param name="rootDir">The root directory that this FileSystem will use.</param>
/// <param name="files">Collection of file names. If relative paths <paramref name="rootDir"/> will be prepended to the paths.</param>
public InMemoryDirectoryInfo(string rootDir, IEnumerable<string>? files)
: this(rootDir, files, false)
: this(rootDir, files, false, StringComparison.Ordinal)
{
}

/// <summary>
/// Creates a new InMemoryDirectoryInfo with the root directory and files given.
/// </summary>
/// <param name="rootDir">The root directory that this FileSystem will use.</param>
/// <param name="files">Collection of file names. If relative paths <paramref name="rootDir"/> will be prepended to the paths.</param>
/// <param name="comparisonType">The comparison type for the root directory. When files are enumerated they will be compared with the root directory using this comparison type.</param>
internal InMemoryDirectoryInfo(string rootDir, IEnumerable<string>? files, StringComparison comparisonType)
: this(rootDir, files, false, comparisonType)
{
}

private InMemoryDirectoryInfo(string rootDir, IEnumerable<string>? files, bool normalized)
private InMemoryDirectoryInfo(string rootDir, IEnumerable<string>? files, bool normalized, StringComparison comparisonType)
{
if (string.IsNullOrEmpty(rootDir))
{
throw new ArgumentNullException(nameof(rootDir));
}

_comparisonType = comparisonType;

files ??= new List<string>();

Name = Path.GetFileName(rootDir);
Expand Down Expand Up @@ -76,7 +90,7 @@ private InMemoryDirectoryInfo(string rootDir, IEnumerable<string>? files, bool n

/// <inheritdoc />
public override DirectoryInfoBase? ParentDirectory =>
new InMemoryDirectoryInfo(Path.GetDirectoryName(FullName)!, _files, true);
new InMemoryDirectoryInfo(Path.GetDirectoryName(FullName)!, _files, true, _comparisonType);

/// <inheritdoc />
public override IEnumerable<FileSystemInfoBase> EnumerateFileSystemInfos()
Expand Down Expand Up @@ -113,15 +127,15 @@ public override IEnumerable<FileSystemInfoBase> EnumerateFileSystemInfos()

foreach (KeyValuePair<string, List<string>> item in dict)
{
yield return new InMemoryDirectoryInfo(item.Key, item.Value, true);
yield return new InMemoryDirectoryInfo(item.Key, item.Value, true, _comparisonType);
}
}

private static bool IsRootDirectory(string rootDir, string filePath)
private bool IsRootDirectory(string rootDir, string filePath)
{
int rootDirLength = rootDir.Length;

return filePath.StartsWith(rootDir, StringComparison.Ordinal) &&
return filePath.StartsWith(rootDir, _comparisonType) &&
(rootDir[rootDirLength - 1] == Path.DirectorySeparatorChar ||
filePath.IndexOf(Path.DirectorySeparatorChar, rootDirLength) == rootDirLength);
}
Expand All @@ -131,12 +145,12 @@ public override DirectoryInfoBase GetDirectory(string path)
{
if (string.Equals(path, "..", StringComparison.Ordinal))
{
return new InMemoryDirectoryInfo(Path.Combine(FullName, path), _files, true);
return new InMemoryDirectoryInfo(Path.Combine(FullName, path), _files, true, _comparisonType);
}
else
{
string normPath = Path.GetFullPath(path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar));
return new InMemoryDirectoryInfo(normPath, _files, true);
return new InMemoryDirectoryInfo(normPath, _files, true, _comparisonType);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@ public class Matcher
private readonly List<IPattern>? _excludePatterns;
private readonly List<IncludeOrExcludeValue<IPattern>>? _includeOrExcludePatterns;
private readonly PatternBuilder _builder;
private readonly StringComparison _comparison;
private readonly bool _preserveFilterOrder;

internal StringComparison ComparisonType { get; }

/// <summary>
/// Initializes an instance of <see cref="Matcher" /> using case-insensitive matching
/// </summary>
Expand Down Expand Up @@ -130,7 +131,7 @@ public Matcher(StringComparison comparisonType)
/// </param>
public Matcher(StringComparison comparisonType = StringComparison.OrdinalIgnoreCase, bool preserveFilterOrder = false)
{
_comparison = comparisonType;
ComparisonType = comparisonType;
_builder = new PatternBuilder(comparisonType);
_preserveFilterOrder = preserveFilterOrder;

Expand Down Expand Up @@ -199,8 +200,8 @@ public virtual PatternMatchingResult Execute(DirectoryInfoBase directoryInfo)
ArgumentNullException.ThrowIfNull(directoryInfo);

return _preserveFilterOrder ?
new MatcherContext(_includeOrExcludePatterns!, directoryInfo, _comparison).Execute() :
new MatcherContext(_includePatterns!, _excludePatterns!, directoryInfo, _comparison).Execute();
new MatcherContext(_includeOrExcludePatterns!, directoryInfo, ComparisonType).Execute() :
new MatcherContext(_includePatterns!, _excludePatterns!, directoryInfo, ComparisonType).Execute();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public static PatternMatchingResult Match(this Matcher matcher, string rootDir,
{
ArgumentNullException.ThrowIfNull(matcher);

return matcher.Execute(new InMemoryDirectoryInfo(rootDir, files));
return matcher.Execute(new InMemoryDirectoryInfo(rootDir, files, matcher.ComparisonType));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -901,5 +901,50 @@ public void VerifyFiles_ParentRedundantSegment_CurrentDirectory_HasMatches()
Assert.True(matcher.Match([$"../{cwdFolderName}/{file}"]).HasMatches);
}
}

[Theory]
[InlineData(@"/this/example/root", @"/this/EXAMPLE/root", "**/*", new[] { "some/test/file.txt" })]
[InlineData(@"/this/example/root", @"/this/example/root", "**/*", new[] { "some/test/file.txt" })]
[InlineData(@"/this/EXAMPLE/root", @"/this/example/root", "**/*", new[] { "some/test/file.txt" })]
public void VerifyFiles_InMemory_HasCaseInsensitiveRootMatches(string matchRoot, string filesRoot, string pattern, string[] expectedSubPaths)
{
Matcher matcher = new(StringComparison.OrdinalIgnoreCase);
matcher.AddInclude(pattern);

PatternMatchingResult patternMatchingResult = matcher.Match(matchRoot,
expectedSubPaths.Select(expectedSubPath => Path.Combine(filesRoot, expectedSubPath)));

Assert.True(patternMatchingResult.HasMatches);
Assert.Equal(expectedSubPaths.Length, patternMatchingResult.Files.Count());
}

[Theory]
[InlineData(@"/this/example/root", @"/this/example/root", "**/*", new[] { "some/test/file.txt" })]
public void VerifyFiles_InMemory_HasCaseSensitiveRootMatches(string matchRoot, string filesRoot, string pattern, string[] expectedSubPaths)
{
Matcher matcher = new(StringComparison.Ordinal);
matcher.AddInclude(pattern);

PatternMatchingResult patternMatchingResult = matcher.Match(matchRoot,
expectedSubPaths.Select(expectedSubPath => Path.Combine(filesRoot, expectedSubPath)));

Assert.True(patternMatchingResult.HasMatches);
Assert.Equal(expectedSubPaths.Length, patternMatchingResult.Files.Count());
}

[Theory]
[InlineData(@"/this/example/root", @"/this/EXAMPLE/root", "**/*", new[] { "some/test/file.txt" })]
[InlineData(@"/this/EXAMPLE/root", @"/this/example/root", "**/*", new[] { "some/test/file.txt" })]
public void VerifyFiles_InMemory_HasCaseSensitiveRootMisses(string matchRoot, string filesRoot, string pattern, string[] expectedSubPaths)
{
Matcher matcher = new(StringComparison.Ordinal);
matcher.AddInclude(pattern);

PatternMatchingResult patternMatchingResult = matcher.Match(matchRoot,
expectedSubPaths.Select(expectedSubPath => Path.Combine(filesRoot, expectedSubPath)));

Assert.False(patternMatchingResult.HasMatches);
Assert.Equal(0, patternMatchingResult.Files.Count());
}
}
}
Loading