469 lines
24 KiB
C#
469 lines
24 KiB
C#
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Microsoft.DotNet.ProjectModel.FileSystemGlobbing.Abstractions;
|
|
using Microsoft.DotNet.ProjectModel.FileSystemGlobbing.Tests.TestUtility;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.DotNet.ProjectModel.FileSystemGlobbing.Tests
|
|
{
|
|
public class FunctionalTests : IDisposable
|
|
{
|
|
private readonly DisposableFileSystem _context;
|
|
|
|
public FunctionalTests()
|
|
{
|
|
_context = CreateContext();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_context.Dispose();
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("sub/source2.cs", "sub/source2.cs")]
|
|
[InlineData("sub\\source2.cs", "sub\\source2.cs")]
|
|
[InlineData("sub/source2.cs", "sub\\source2.cs")]
|
|
public void DuplicatePatterns(string pattern1, string pattern2)
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(pattern1);
|
|
matcher.AddInclude(pattern2);
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project/sub/source2.cs");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("src/project", "source1.cs", new string[] { "source1.cs" })]
|
|
[InlineData("src/project", "Source1.cs", new string[] { })]
|
|
[InlineData("src/project", "compiler/preprocess/**/*.cs", new string[] { "compiler/preprocess/preprocess-source1.cs",
|
|
"compiler/preprocess/sub/preprocess-source2.cs",
|
|
"compiler/preprocess/sub/sub/preprocess-source3.cs" })]
|
|
[InlineData("src/project", "compiler/Preprocess/**.cs", new string[] { })]
|
|
public void IncludeCaseSensitive(string root, string includePattern, string[] expectedFiles)
|
|
{
|
|
var matcher = new Matcher(StringComparison.Ordinal);
|
|
matcher.AddInclude(includePattern);
|
|
|
|
ExecuteAndVerify(matcher, root, expectedFiles.Select(f => root + "/" + f).ToArray());
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("src/project", "source1.cs", new string[] { "source1.cs" })]
|
|
[InlineData("src/project", "Source1.cs", new string[] { "Source1.cs" })]
|
|
[InlineData("src/project", "compiler/preprocess/**/*.cs", new string[] { "compiler/preprocess/preprocess-source1.cs",
|
|
"compiler/preprocess/sub/preprocess-source2.cs",
|
|
"compiler/preprocess/sub/sub/preprocess-source3.cs" })]
|
|
[InlineData("src/project", "compiler/Preprocess/**.cs", new string[] { "compiler/Preprocess/preprocess-source1.cs",
|
|
"compiler/Preprocess/sub/preprocess-source2.cs",
|
|
"compiler/Preprocess/sub/sub/preprocess-source3.cs" })]
|
|
public void IncludeCaseInsensitive(string root, string includePattern, string[] expectedFiles)
|
|
{
|
|
var matcher = new Matcher(StringComparison.OrdinalIgnoreCase);
|
|
matcher.AddInclude(includePattern);
|
|
|
|
ExecuteAndVerify(matcher, root, expectedFiles.Select(f => root + "/" + f).ToArray());
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("src/project/compiler/preprocess/", "source.cs", new string[] { "preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "preprocess-source1.cs", new string[] {
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "preprocesS-source1.cs", new string[] {
|
|
"preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "**/Preprocess*", new string[] { "preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "**/preprocess*", new string[] { })]
|
|
[InlineData("src/project/compiler/preprocess/", "**/*source*.cs", new string[] { "sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "**/*Source*.cs", new string[] {
|
|
"preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "sub/sub/*", new string[] { "preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs" })]
|
|
[InlineData("src/project/compiler/preprocess/", "sub/Sub/*", new string[] { "preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
public void ExcludeCaseSensitive(string root, string excludePattern, string[] expectedFiles)
|
|
{
|
|
var matcher = new Matcher(StringComparison.Ordinal);
|
|
matcher.AddInclude("**/*.*");
|
|
matcher.AddExclude(excludePattern);
|
|
|
|
ExecuteAndVerify(matcher, root, expectedFiles.Select(f => root + "/" + f).ToArray());
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("src/project/compiler/preprocess/", "source.cs", new string[] { "preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "preprocess-source1.cs", new string[] {
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "preprocesS-source1.cs", new string[] {
|
|
"sub/preprocess-source2.cs",
|
|
"sub/sub/preprocess-source3.cs",
|
|
"sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "**/Preprocess*", new string[] { })]
|
|
[InlineData("src/project/compiler/preprocess/", "**/preprocess*", new string[] { })]
|
|
[InlineData("src/project/compiler/preprocess/", "**/*source*.cs", new string[] { "sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "**/*Source*.cs", new string[] { "sub/sub/preprocess-source3.txt" })]
|
|
[InlineData("src/project/compiler/preprocess/", "sub/sub/*", new string[] { "preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs" })]
|
|
[InlineData("src/project/compiler/preprocess/", "sub/Sub/*", new string[] { "preprocess-source1.cs",
|
|
"sub/preprocess-source2.cs" })]
|
|
public void ExcludeCaseInsensitive(string root, string excludePattern, string[] expectedFiles)
|
|
{
|
|
var matcher = new Matcher(StringComparison.OrdinalIgnoreCase);
|
|
matcher.AddInclude("**/*.*");
|
|
matcher.AddExclude(excludePattern);
|
|
|
|
ExecuteAndVerify(matcher, root, expectedFiles.Select(f => root + "/" + f).ToArray());
|
|
}
|
|
|
|
[Fact]
|
|
public void RecursiveAndDoubleParentsWithRecursiveSearch()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude("**/*.cs")
|
|
.AddInclude(@"../../lib/**/*.cs");
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project/source1.cs",
|
|
"src/project/sub/source2.cs",
|
|
"src/project/sub/source3.cs",
|
|
"src/project/sub2/source4.cs",
|
|
"src/project/sub2/source5.cs",
|
|
"src/project/compiler/preprocess/preprocess-source1.cs",
|
|
"src/project/compiler/preprocess/sub/preprocess-source2.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"src/project/compiler/shared/shared1.cs",
|
|
"src/project/compiler/shared/sub/shared2.cs",
|
|
"src/project/compiler/shared/sub/sub/sharedsub.cs",
|
|
"lib/source6.cs",
|
|
"lib/sub3/source7.cs",
|
|
"lib/sub4/source8.cs");
|
|
}
|
|
|
|
[Fact]
|
|
public void RecursiveAndDoubleParentsSearch()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude("**/*.cs")
|
|
.AddInclude(@"../../lib/*.cs");
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project/source1.cs",
|
|
"src/project/sub/source2.cs",
|
|
"src/project/sub/source3.cs",
|
|
"src/project/sub2/source4.cs",
|
|
"src/project/sub2/source5.cs",
|
|
"src/project/compiler/preprocess/preprocess-source1.cs",
|
|
"src/project/compiler/preprocess/sub/preprocess-source2.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"src/project/compiler/shared/shared1.cs",
|
|
"src/project/compiler/shared/sub/shared2.cs",
|
|
"src/project/compiler/shared/sub/sub/sharedsub.cs",
|
|
"lib/source6.cs");
|
|
}
|
|
|
|
[Fact]
|
|
public void WildcardAndDoubleParentWithRecursiveSearch()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(@"..\..\lib\**\*.cs");
|
|
matcher.AddInclude(@"*.cs");
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project/source1.cs",
|
|
"lib/source6.cs",
|
|
"lib/sub3/source7.cs",
|
|
"lib/sub4/source8.cs");
|
|
}
|
|
|
|
[Fact]
|
|
public void WildcardAndDoubleParentsSearch()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(@"..\..\lib\*.cs");
|
|
matcher.AddInclude(@"*.cs");
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project/source1.cs",
|
|
"lib/source6.cs");
|
|
}
|
|
|
|
[Fact]
|
|
public void DoubleParentsWithRecursiveSearch()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(@"..\..\lib\**\*.cs");
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"lib/source6.cs",
|
|
"lib/sub3/source7.cs",
|
|
"lib/sub4/source8.cs");
|
|
}
|
|
|
|
[Fact]
|
|
public void OneLevelParentAndRecursiveSearch()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(@"../project2/**/*.cs");
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project2/source1.cs",
|
|
"src/project2/sub/source2.cs",
|
|
"src/project2/sub/source3.cs",
|
|
"src/project2/sub2/source4.cs",
|
|
"src/project2/sub2/source5.cs",
|
|
"src/project2/compiler/preprocess/preprocess-source1.cs",
|
|
"src/project2/compiler/preprocess/sub/preprocess-source2.cs",
|
|
"src/project2/compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"src/project2/compiler/shared/shared1.cs",
|
|
"src/project2/compiler/shared/sub/shared2.cs",
|
|
"src/project2/compiler/shared/sub/sub/sharedsub.cs");
|
|
}
|
|
|
|
[Fact]
|
|
public void RecursiveSuffixSearch()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(@"**.txt");
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.txt",
|
|
"src/project/compiler/shared/shared1.txt",
|
|
"src/project/compiler/shared/sub/shared2.txt",
|
|
"src/project/content1.txt");
|
|
}
|
|
|
|
[Fact]
|
|
public void FolderExclude()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(@"**/*.*");
|
|
matcher.AddExclude(@"obj");
|
|
matcher.AddExclude(@"bin");
|
|
matcher.AddExclude(@".*");
|
|
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project/source1.cs",
|
|
"src/project/sub/source2.cs",
|
|
"src/project/sub/source3.cs",
|
|
"src/project/sub2/source4.cs",
|
|
"src/project/sub2/source5.cs",
|
|
"src/project/compiler/preprocess/preprocess-source1.cs",
|
|
"src/project/compiler/preprocess/sub/preprocess-source2.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.txt",
|
|
"src/project/compiler/shared/shared1.cs",
|
|
"src/project/compiler/shared/shared1.txt",
|
|
"src/project/compiler/shared/sub/shared2.cs",
|
|
"src/project/compiler/shared/sub/shared2.txt",
|
|
"src/project/compiler/shared/sub/sub/sharedsub.cs",
|
|
"src/project/compiler/resources/resource.res",
|
|
"src/project/compiler/resources/sub/resource2.res",
|
|
"src/project/compiler/resources/sub/sub/resource3.res",
|
|
"src/project/content1.txt");
|
|
}
|
|
|
|
[Fact]
|
|
public void FolderInclude()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(@"compiler/");
|
|
ExecuteAndVerify(matcher, @"src/project",
|
|
"src/project/compiler/preprocess/preprocess-source1.cs",
|
|
"src/project/compiler/preprocess/sub/preprocess-source2.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.txt",
|
|
"src/project/compiler/shared/shared1.cs",
|
|
"src/project/compiler/shared/shared1.txt",
|
|
"src/project/compiler/shared/sub/shared2.cs",
|
|
"src/project/compiler/shared/sub/shared2.txt",
|
|
"src/project/compiler/shared/sub/sub/sharedsub.cs",
|
|
"src/project/compiler/resources/resource.res",
|
|
"src/project/compiler/resources/sub/resource2.res",
|
|
"src/project/compiler/resources/sub/sub/resource3.res");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("source1.cs", "src/project/source1.cs")]
|
|
[InlineData("../project2/source1.cs", "src/project2/source1.cs")]
|
|
public void SingleFile(string pattern, string expect)
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude(pattern);
|
|
ExecuteAndVerify(matcher, "src/project", expect);
|
|
}
|
|
|
|
[Fact]
|
|
public void SingleFileAndRecursive()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude("**/*.cs");
|
|
matcher.AddInclude("../project2/source1.cs");
|
|
ExecuteAndVerify(matcher, "src/project",
|
|
"src/project/source1.cs",
|
|
"src/project/sub/source2.cs",
|
|
"src/project/sub/source3.cs",
|
|
"src/project/sub2/source4.cs",
|
|
"src/project/sub2/source5.cs",
|
|
"src/project/compiler/preprocess/preprocess-source1.cs",
|
|
"src/project/compiler/preprocess/sub/preprocess-source2.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"src/project/compiler/shared/shared1.cs",
|
|
"src/project/compiler/shared/sub/shared2.cs",
|
|
"src/project/compiler/shared/sub/sub/sharedsub.cs",
|
|
"src/project2/source1.cs");
|
|
}
|
|
|
|
[Fact]
|
|
public void StemCorrectWithDifferentWildCards()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude("sub/*.cs");
|
|
matcher.AddInclude("**/*.cs");
|
|
|
|
var directoryPath = Path.Combine(_context.RootPath, "src/project");
|
|
var results = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directoryPath)));
|
|
|
|
var actual = results.Files.Select(match => match.Stem);
|
|
var expected = new string[] {
|
|
"source1.cs",
|
|
"source2.cs",
|
|
"source3.cs",
|
|
"sub2/source4.cs",
|
|
"sub2/source5.cs",
|
|
"compiler/preprocess/preprocess-source1.cs",
|
|
"compiler/preprocess/sub/preprocess-source2.cs",
|
|
"compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"compiler/shared/shared1.cs",
|
|
"compiler/shared/sub/shared2.cs",
|
|
"compiler/shared/sub/sub/sharedsub.cs"
|
|
};
|
|
|
|
Assert.Equal(
|
|
expected.OrderBy(e => e),
|
|
actual.OrderBy(e => e),
|
|
StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
[Fact]
|
|
public void MultipleSubDirsAfterFirstWildcardMatch_HasCorrectStem()
|
|
{
|
|
var matcher = new Matcher();
|
|
matcher.AddInclude("compiler/**/*.cs");
|
|
|
|
var directoryPath = Path.Combine(_context.RootPath, "src/project");
|
|
var results = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directoryPath)));
|
|
|
|
var actual = results.Files.Select(match => match.Stem);
|
|
var expected = new string[] {
|
|
"preprocess/preprocess-source1.cs",
|
|
"preprocess/sub/preprocess-source2.cs",
|
|
"preprocess/sub/sub/preprocess-source3.cs",
|
|
"shared/shared1.cs",
|
|
"shared/sub/shared2.cs",
|
|
"shared/sub/sub/sharedsub.cs"
|
|
};
|
|
|
|
Assert.Equal(
|
|
expected.OrderBy(e => e),
|
|
actual.OrderBy(e => e),
|
|
StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
private DisposableFileSystem CreateContext()
|
|
{
|
|
var context = new DisposableFileSystem();
|
|
context.CreateFiles(
|
|
"src/project/source1.cs",
|
|
"src/project/sub/source2.cs",
|
|
"src/project/sub/source3.cs",
|
|
"src/project/sub2/source4.cs",
|
|
"src/project/sub2/source5.cs",
|
|
"src/project/compiler/preprocess/preprocess-source1.cs",
|
|
"src/project/compiler/preprocess/sub/preprocess-source2.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"src/project/compiler/preprocess/sub/sub/preprocess-source3.txt",
|
|
"src/project/compiler/shared/shared1.cs",
|
|
"src/project/compiler/shared/shared1.txt",
|
|
"src/project/compiler/shared/sub/shared2.cs",
|
|
"src/project/compiler/shared/sub/shared2.txt",
|
|
"src/project/compiler/shared/sub/sub/sharedsub.cs",
|
|
"src/project/compiler/resources/resource.res",
|
|
"src/project/compiler/resources/sub/resource2.res",
|
|
"src/project/compiler/resources/sub/sub/resource3.res",
|
|
"src/project/content1.txt",
|
|
"src/project/obj/object.o",
|
|
"src/project/bin/object",
|
|
"src/project/.hidden/file1.hid",
|
|
"src/project/.hidden/sub/file2.hid",
|
|
"src/project2/source1.cs",
|
|
"src/project2/sub/source2.cs",
|
|
"src/project2/sub/source3.cs",
|
|
"src/project2/sub2/source4.cs",
|
|
"src/project2/sub2/source5.cs",
|
|
"src/project2/compiler/preprocess/preprocess-source1.cs",
|
|
"src/project2/compiler/preprocess/sub/preprocess-source2.cs",
|
|
"src/project2/compiler/preprocess/sub/sub/preprocess-source3.cs",
|
|
"src/project2/compiler/preprocess/sub/sub/preprocess-source3.txt",
|
|
"src/project2/compiler/shared/shared1.cs",
|
|
"src/project2/compiler/shared/shared1.txt",
|
|
"src/project2/compiler/shared/sub/shared2.cs",
|
|
"src/project2/compiler/shared/sub/shared2.txt",
|
|
"src/project2/compiler/shared/sub/sub/sharedsub.cs",
|
|
"src/project2/compiler/resources/resource.res",
|
|
"src/project2/compiler/resources/sub/resource2.res",
|
|
"src/project2/compiler/resources/sub/sub/resource3.res",
|
|
"src/project2/content1.txt",
|
|
"src/project2/obj/object.o",
|
|
"src/project2/bin/object",
|
|
"lib/source6.cs",
|
|
"lib/sub3/source7.cs",
|
|
"lib/sub4/source8.cs",
|
|
"res/resource1.text",
|
|
"res/resource2.text",
|
|
"res/resource3.text",
|
|
".hidden/file1.hid",
|
|
".hidden/sub/file2.hid");
|
|
|
|
return context;
|
|
}
|
|
|
|
private void ExecuteAndVerify(Matcher matcher, string directoryPath, params string[] expectFiles)
|
|
{
|
|
directoryPath = Path.Combine(_context.RootPath, directoryPath);
|
|
var results = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directoryPath)));
|
|
|
|
var actual = results.Files.Select(match => Path.GetFullPath(Path.Combine(_context.RootPath, directoryPath, match.Path)));
|
|
var expected = expectFiles.Select(relativePath => Path.GetFullPath(Path.Combine(_context.RootPath, relativePath)));
|
|
|
|
Assert.Equal(
|
|
expected.OrderBy(e => e),
|
|
actual.OrderBy(e => e),
|
|
StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
}
|
|
}
|