File: StaticWebAssets\Globbing\StaticWebAssetGlobMatcherTest.Compatibility.cs
Web Access
Project: ..\..\..\test\Microsoft.NET.Sdk.StaticWebAssets.Tests\Microsoft.NET.Sdk.StaticWebAssets.Tests.csproj (Microsoft.NET.Sdk.StaticWebAssets.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
namespace Microsoft.AspNetCore.StaticWebAssets.Tasks.Test;
 
public partial class StaticWebAssetGlobMatcherTest
{
    [Fact]
    public void MatchingFileIsFound()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("alpha.txt");
        var globMatcher = matcher.Build();
 
        var match = globMatcher.Match("alpha.txt");
        Assert.True(match.IsMatch);
        Assert.Equal("alpha.txt", match.Pattern);
    }
 
    [Fact]
    public void MismatchedFileIsIgnored()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("alpha.txt");
        var globMatcher = matcher.Build();
 
        var match = globMatcher.Match("omega.txt");
        Assert.False(match.IsMatch);
    }
 
    [Fact]
    public void FolderNamesAreTraversed()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("beta/alpha.txt");
        var globMatcher = matcher.Build();
 
        var match = globMatcher.Match("beta/alpha.txt");
        Assert.True(match.IsMatch);
        Assert.Equal("beta/alpha.txt", match.Pattern);
    }
 
    [Theory]
    [InlineData(@"beta/alpha.txt", @"beta/alpha.txt")]
    [InlineData(@"beta\alpha.txt", @"beta/alpha.txt")]
    [InlineData(@"beta/alpha.txt", @"beta\alpha.txt")]
    [InlineData(@"beta\alpha.txt", @"beta\alpha.txt")]
    [InlineData(@"\beta\alpha.txt", @"beta/alpha.txt")]
    public void SlashPolarityIsIgnored(string includePattern, string filePath)
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns(includePattern);
        var globMatcher = matcher.Build();
 
        var match = globMatcher.Match(filePath);
        Assert.True(match.IsMatch);
        //Assert.Equal("beta/alpha.txt", match.Pattern);
    }
 
    [Theory]
    [InlineData(@"alpha.*", new[] { "alpha.txt" })]
    [InlineData(@"*", new[] { "alpha.txt", "beta.txt", "gamma.dat" })]
    [InlineData(@"*et*", new[] { "beta.txt" })]
    [InlineData(@"*.*", new[] { "alpha.txt", "beta.txt", "gamma.dat" })]
    [InlineData(@"b*et*x", new string[0])]
    [InlineData(@"*.txt", new[] { "alpha.txt", "beta.txt" })]
    [InlineData(@"b*et*t", new[] { "beta.txt" })]
    public void CanPatternMatch(string includes, string[] expected)
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns(includes);
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "alpha.txt", "beta.txt", "gamma.dat" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(expected, matches);
    }
 
    [Theory]
    [InlineData(@"12345*5678", new string[0])]
    [InlineData(@"1234*5678", new[] { "12345678" })]
    [InlineData(@"12*23*", new string[0])]
    [InlineData(@"12*3456*78", new[] { "12345678" })]
    [InlineData(@"*45*56", new string[0])]
    [InlineData(@"*67*78", new string[0])]
    public void PatternBeginAndEndCantOverlap(string includes, string[] expected)
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns(includes);
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "12345678" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(expected, matches);
    }
 
    [Theory]
    [InlineData(@"*alpha*/*", new[] { "alpha/hello.txt" })]
    [InlineData(@"/*/*", new[] { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" })]
    [InlineData(@"*/*", new[] { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" })]
    [InlineData(@"/*.*/*", new string[] { })]
    [InlineData(@"*.*/*", new string[] { })]
    [InlineData(@"/*mm*/*", new[] { "gamma/hello.txt" })]
    [InlineData(@"*mm*/*", new[] { "gamma/hello.txt" })]
    [InlineData(@"/*alpha*/*", new[] { "alpha/hello.txt" })]
    public void PatternMatchingWorksInFolders(string includes, string[] expected)
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns(includes);
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(expected, matches);
    }
 
    [Theory]
    [InlineData(@"", new string[] { })]
    [InlineData(@"./", new string[] { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" })]
    [InlineData(@"./alpha/hello.txt", new string[] { "alpha/hello.txt" })]
    [InlineData(@"./**/hello.txt", new string[] { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" })]
    [InlineData(@"././**/hello.txt", new string[] { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" })]
    [InlineData(@"././**/./hello.txt", new string[] { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" })]
    [InlineData(@"././**/./**/hello.txt", new string[] { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" })]
    [InlineData(@"./*mm*/hello.txt", new string[] { "gamma/hello.txt" })]
    [InlineData(@"./*mm*/*", new string[] { "gamma/hello.txt" })]
    public void PatternMatchingCurrent(string includePattern, string[] matchesExpected)
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns(includePattern);
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "alpha/hello.txt", "beta/hello.txt", "gamma/hello.txt" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(matchesExpected, matches);
    }
 
    [Fact]
    public void StarDotStarIsSameAsStar()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("*.*");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "alpha.txt", "alpha.", ".txt", ".", "alpha", "txt" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "alpha.txt", "alpha.", ".txt" }, matches);
    }
 
    [Fact]
    public void IncompletePatternsDoNotInclude()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("*/*.txt");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "one/x.txt", "two/x.txt", "x.txt" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "one/x.txt", "two/x.txt" }, matches);
    }
 
    [Fact]
    public void IncompletePatternsDoNotExclude()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("*/*.txt");
        matcher.AddExcludePatterns("one/hello.txt");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "one/x.txt", "two/x.txt" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "one/x.txt", "two/x.txt" }, matches);
    }
 
    [Fact]
    public void TrailingRecursiveWildcardMatchesAllFiles()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("one/**");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "one/x.txt", "two/x.txt", "one/x/y.txt" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "one/x.txt", "one/x/y.txt" }, matches);
    }
 
    [Fact]
    public void LeadingRecursiveWildcardMatchesAllLeadingPaths()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("**/*.cs");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "one/x.cs", "two/x.cs", "one/two/x.cs", "x.cs", "one/x.txt", "two/x.txt", "one/two/x.txt", "x.txt" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "one/x.cs", "two/x.cs", "one/two/x.cs", "x.cs" }, matches);
    }
 
    [Fact]
    public void InnerRecursiveWildcardMustStartWithAndEndWith()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("one/**/*.cs");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "one/x.cs", "two/x.cs", "one/two/x.cs", "x.cs", "one/x.txt", "two/x.txt", "one/two/x.txt", "x.txt" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "one/x.cs", "one/two/x.cs" }, matches);
    }
 
    [Fact]
    public void ExcludeMayEndInDirectoryName()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("*.cs", "*/*.cs", "*/*/*.cs");
        matcher.AddExcludePatterns("bin/", "one/two/");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "one/x.cs", "two/x.cs", "one/two/x.cs", "x.cs", "bin/x.cs", "bin/two/x.cs" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "one/x.cs", "two/x.cs", "x.cs" }, matches);
    }
 
    [Fact]
    public void RecursiveWildcardSurroundingContainsWith()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("**/x/**");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "x/1", "1/x/2", "1/x", "x", "1", "1/2" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "x/1", "1/x/2", "1/x", "x" }, matches);
    }
 
    [Fact]
    public void SequentialFoldersMayBeRequired()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("a/b/**/1/2/**/2/3/**");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "1/2/2/3/x", "1/2/3/y", "a/1/2/4/2/3/b", "a/2/3/1/2/b", "a/b/1/2/2/3/x", "a/b/1/2/3/y", "a/b/a/1/2/4/2/3/b", "a/b/a/2/3/1/2/b" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "a/b/1/2/2/3/x", "a/b/a/1/2/4/2/3/b" }, matches);
    }
 
    [Fact]
    public void RecursiveAloneIncludesEverything()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("**");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "1/2/2/3/x", "1/2/3/y" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "1/2/2/3/x", "1/2/3/y" }, matches);
    }
 
    [Fact]
    public void ExcludeCanHaveSurroundingRecursiveWildcards()
    {
        var matcher = new StaticWebAssetGlobMatcherBuilder();
        matcher.AddIncludePatterns("**");
        matcher.AddExcludePatterns("**/x/**");
        var globMatcher = matcher.Build();
 
        var matches = new List<string> { "x/1", "1/x/2", "1/x", "x", "1", "1/2" }
            .Where(file => globMatcher.Match(file).IsMatch)
            .ToArray();
 
        Assert.Equal(new[] { "1", "1/2" }, matches);
    }
}