diff --git a/tools/code-owners-parser/Azure.Sdk.Tools.CodeOwnersParser.Tests/CodeownersFileTests.cs b/tools/code-owners-parser/Azure.Sdk.Tools.CodeOwnersParser.Tests/CodeownersFileTests.cs
index e13bbc776b9..559e3bfde44 100644
--- a/tools/code-owners-parser/Azure.Sdk.Tools.CodeOwnersParser.Tests/CodeownersFileTests.cs
+++ b/tools/code-owners-parser/Azure.Sdk.Tools.CodeOwnersParser.Tests/CodeownersFileTests.cs
@@ -4,8 +4,7 @@
namespace Azure.Sdk.Tools.CodeOwnersParser.Tests;
///
-/// Please see the comment on:
-/// - Azure.Sdk.Tools.CodeOwnersParser.Tests.CodeownersFileTests.testCases
+/// Please see the comment on CodeownersFileTests.testCases
///
[TestFixture]
public class CodeownersFileTests
@@ -23,176 +22,175 @@ public class CodeownersFileTests
private static readonly TestCase[] testCases =
{
// @formatter:off
- // Path: Expected match:
- // Codeowners , Target , |
- new( "/**" , "a" , true ),
- new( "/**" , "A" , true ),
- new( "/**" , "/a" , true ),
- new( "/**" , "a/" , true ),
- new( "/**" , "/a/" , true ),
- new( "/**" , "/a/b" , true ),
- new( "/**" , "/a/b/" , true ),
- new( "/**" , "/a/b/c" , true ),
- new( "/**" , "[" , true ),
- new( "/**" , "]" , true ),
- new( "/" , "a" , false ),
- new( "/" , "A" , false ),
- new( "/" , "/a" , false ),
- new( "/" , "a/" , false ),
- new( "/" , "/a/" , false ),
- new( "/" , "/a/b" , false ),
- new( "/a" , "a" , true ),
- new( "/a" , "A" , false ),
- new( "/a" , "/a" , true ),
- new( "/a" , "a/" , false ),
- new( "/a" , "/a/" , false ),
- new( "/a" , "/a/b" , false ),
- new( "/a" , "/a/b/" , false ),
- new( "/a" , "/a\\ b" , false ),
- new( "/a" , "/x/a/b" , false ),
- new( "a" , "a" , false ),
- new( "a" , "ab" , false ),
- new( "a" , "ab/" , false ),
- new( "a" , "/ab/" , false ),
- new( "a" , "A" , false ),
- new( "a" , "/a" , false ),
- new( "a" , "a/" , false ),
- new( "a" , "/a/" , false ),
- new( "a" , "/a/b" , false ),
- new( "a" , "/a/b/" , false ),
- new( "a" , "/x/a/b" , false ),
- new( "/a/" , "a" , false ),
- new( "/a/" , "/a" , false ),
- new( "/a/" , "a/" , true ),
- new( "/a/" , "/a/" , true ),
- new( "/a/" , "/a/b" , true ),
- new( "/a/" , "/a\\ b" , false ),
- new( "/a/" , "/a\\ b/" , false ),
- new( "/a/" , "/a/a\\ b/" , true ),
- new( "/a/" , "/a/b/" , true ),
- new( "/a/" , "/A/b/" , false ),
- new( "/a/" , "/x/a/b" , false ),
- new( "/a/b/" , "/a" , false ),
- new( "/a/b/" , "/a/" , false ),
- new( "/a/b/" , "/a/b" , false ),
- new( "/a/b/" , "/a/b/" , true ),
- new( "/a/b/" , "/a/b/c" , true ),
- new( "/a/b/" , "/a/b/c/" , true ),
- new( "/a/b/" , "/a/b/c/d" , true ),
- new( "/a/b" , "/a" , false ),
- new( "/a/b" , "/a/" , false ),
- new( "/a/b" , "/a/b" , true ),
- new( "/a/b" , "/a/b/" , false ),
- new( "/a/b" , "/a/bc" , false ),
- new( "/a/b" , "/a/bc/" , false ),
- new( "/a/b" , "/a/b/c" , false ),
- new( "/a/b" , "/a/b/c/" , false ),
- new( "/a/b" , "/a/b/c/d" , false ),
- new( "/!a" , "!a" , false ),
- new( "/!a" , "b" , false ),
- new( "/a[b" , "a[b" , false ),
- new( "/a]b" , "a]b" , false ),
- new( "/a?b" , "a?b" , false ),
- new( "/a?b" , "axb" , false ),
- new( "/a" , "*" , false ),
- new( "/*" , "*" , false ),
- new( "/*" , "a" , true ),
- new( "/*" , "a/" , false ),
- new( "/*" , "/a" , true ),
- new( "/*" , "/a/" , false ),
- new( "/*" , "a/b" , false ),
- new( "/*" , "/a/b" , false ),
- new( "/*" , "[" , true ),
- new( "/*" , "]" , true ),
- new( "/*" , "!" , true ),
- new( "/**" , "!" , true ),
- new( "/a*" , "a" , true ),
- new( "/a*" , "a/x" , true ),
- new( "/a*" , "a/x/d" , true ),
- new( "/a*" , "ab" , true ),
- new( "/a*" , "ab/x" , true ),
- new( "/a*" , "ab/x/d" , true ),
- new( "/a/**" , "a" , false ),
- new( "/*/**" , "a" , false ),
- new( "/*/**" , "a/" , false ),
- new( "/*/**" , "a/b" , false ),
- new( "/*/" , "a" , false ),
- new( "/*/" , "a/" , true ),
- new( "/*/b" , "a/b" , true ),
- new( "/**/a" , "a" , true ),
- new( "/**/a" , "x/ba" , false ),
- new( "/a/*" , "a" , false ),
- new( "/a/*" , "a/" , true ),
- new( "/a/*" , "a/b" , true ),
- new( "/a/*" , "a/b/" , false ),
- new( "/a/*" , "a/b/c" , false ),
- new( "/a/*/" , "a" , false ),
- new( "/a/*/" , "a/" , false ),
- new( "/a/*/" , "a/b" , false ),
- new( "/a/*/" , "a/b/" , true ),
- new( "/a/*/" , "a/b/c" , true ),
- new( "/a/**" , "a" , false ),
- new( "/a/**" , "a/" , false ),
- new( "/a/**" , "a/b" , false ),
- new( "/a/**" , "a/b/" , false ),
- new( "/a/**" , "a/b/c" , false ),
- new( "/a/**/" , "a" , false ),
- new( "/a/**/" , "a/" , false ),
- new( "/a/**/" , "a/b" , false ),
- new( "/a/**/" , "a/b/" , false ),
- new( "/a/**/" , "a/b/c" , false ),
- new( "/**/a/" , "a" , false ),
- new( "/**/a/" , "a/" , true ),
- new( "/**/a/" , "a/b" , true ),
- new( "/**/b/" , "a/b" , false ),
- new( "/**/b/" , "a/b/" , true ),
- new( "/**/b/" , "a/c/" , false ),
- new( "/a/*/b/" , "a/b/" , false ),
- new( "/a/*/b/" , "a/x/b/" , true ),
- new( "/a/*/b/" , "a/x/b/c" , true ),
- new( "/a/*/b/" , "a/x/c" , false ),
- new( "/a/*/b/" , "a/x/y/b" , false ),
- new( "/a**b/" , "a/x/y/b" , false ),
- new( "/a/**/b/" , "a/b" , false ),
- new( "/a/**/b/" , "a/b/" , true ),
- new( "/a/**/b/" , "a/x/b/" , true ),
- new( "/a/**/b/" , "a/x/y/b/" , true ),
- new( "/a/**/b/" , "a/x/y/c" , false ),
- new( "/a/**/b/" , "a-b/" , false ),
- new( "a/*/*" , "a/b" , false ),
- new( "/a/*/*/d" , "a/b/c/d" , true ),
- new( "/a/*/*/d" , "a/b/x/c/d" , false ),
- new( "/a/**/*/d" , "a/b/x/c/d" , true ),
- new( "*/*/b" , "a/b" , false ),
- new( "/a*/" , "abc/" , true ),
- new( "/a*/" , "ab/c/" , true ),
- new( "/*b*/" , "axbyc/" , true ),
- new( "/*c/" , "abc/" , true ),
- new( "/*c/" , "a/abc/" , false ),
- new( "/a*c/" , "axbyc/" , true ),
- new( "/a*c/" , "axb/yc/" , false ),
- new( "/**/*x*/" , "a/b/cxy/d" , true ),
- new( "/a/*.md" , "a/x.md" , true ),
- new( "/*/*/*.md" , "a/b/x.md" , true ),
- new( "/**/*.md" , "a/b.md/x.md" , true ),
- new( "**/*.md" , "a/b.md/x.md" , false ),
- new( "/*.md" , "a/md" , false ),
- new( "/a.*" , "a.b" , true ),
- new( "/a.*" , "a.b/" , true ),
- new( "/a.*" , "x/a.b/" , false ),
- new( "/a.*/" , "a.b" , false ),
- new( "/a.*/" , "a.b/" , true ),
- new( "/**/*x*/AB/*/CD" , "a/b/cxy/AB/fff/CD" , true ),
- new( "/**/*x*/AB/*/CD" , "a/b/cxy/AB/ff/ff/CD" , false ),
- new( "/**/*x*/AB/**/CD/*" , "a/b/cxy/AB/ff/ff/CD" , false ),
- new( "/**/*x*/AB/**/CD/*" , "a/b/cxy/AB/ff/ff/CD/" , true ),
- new( "/**/*x*/AB/**/CD/*" , "a/b/cxy/AB/[]/!!/CD/h" , true ),
-
+ // Path: Expected match:
+ // Codeowners , Target , |
+ new ( "/**" , "a" , true ),
+ new ( "/**" , "A" , true ),
+ new ( "/**" , "/a" , true ),
+ new ( "/**" , "a/" , true ),
+ new ( "/**" , "/a/" , true ),
+ new ( "/**" , "/a/b" , true ),
+ new ( "/**" , "/a/b/" , true ),
+ new ( "/**" , "/a/b/c" , true ),
+ new ( "/**" , "[" , true ),
+ new ( "/**" , "]" , true ),
+ new ( "/" , "a" , false ),
+ new ( "/" , "A" , false ),
+ new ( "/" , "/a" , false ),
+ new ( "/" , "a/" , false ),
+ new ( "/" , "/a/" , false ),
+ new ( "/" , "/a/b" , false ),
+ new ( "/a" , "a" , true ),
+ new ( "/a" , "A" , false ),
+ new ( "/a" , "/a" , true ),
+ new ( "/a" , "a/" , false ),
+ new ( "/a" , "/a/" , false ),
+ new ( "/a" , "/a/b" , false ),
+ new ( "/a" , "/a/b/" , false ),
+ new ( "/a" , "/a\\ b" , false ),
+ new ( "/a" , "/x/a/b" , false ),
+ new ( "a" , "a" , false ),
+ new ( "a" , "ab" , false ),
+ new ( "a" , "ab/" , false ),
+ new ( "a" , "/ab/" , false ),
+ new ( "a" , "A" , false ),
+ new ( "a" , "/a" , false ),
+ new ( "a" , "a/" , false ),
+ new ( "a" , "/a/" , false ),
+ new ( "a" , "/a/b" , false ),
+ new ( "a" , "/a/b/" , false ),
+ new ( "a" , "/x/a/b" , false ),
+ new ( "/a/" , "a" , false ),
+ new ( "/a/" , "/a" , false ),
+ new ( "/a/" , "a/" , true ),
+ new ( "/a/" , "/a/" , true ),
+ new ( "/a/" , "/a/b" , true ),
+ new ( "/a/" , "/a\\ b" , false ),
+ new ( "/a/" , "/a\\ b/" , false ),
+ new ( "/a/" , "/a/a\\ b/" , true ),
+ new ( "/a/" , "/a/b/" , true ),
+ new ( "/a/" , "/A/b/" , false ),
+ new ( "/a/" , "/x/a/b" , false ),
+ new ( "/a/b/" , "/a" , false ),
+ new ( "/a/b/" , "/a/" , false ),
+ new ( "/a/b/" , "/a/b" , false ),
+ new ( "/a/b/" , "/a/b/" , true ),
+ new ( "/a/b/" , "/a/b/c" , true ),
+ new ( "/a/b/" , "/a/b/c/" , true ),
+ new ( "/a/b/" , "/a/b/c/d" , true ),
+ new ( "/a/b" , "/a" , false ),
+ new ( "/a/b" , "/a/" , false ),
+ new ( "/a/b" , "/a/b" , true ),
+ new ( "/a/b" , "/a/b/" , false ),
+ new ( "/a/b" , "/a/bc" , false ),
+ new ( "/a/b" , "/a/bc/" , false ),
+ new ( "/a/b" , "/a/b/c" , false ),
+ new ( "/a/b" , "/a/b/c/" , false ),
+ new ( "/a/b" , "/a/b/c/d" , false ),
+ new ( "/!a" , "!a" , false ),
+ new ( "/!a" , "b" , false ),
+ new ( "/a[b" , "a[b" , false ),
+ new ( "/a]b" , "a]b" , false ),
+ new ( "/a?b" , "a?b" , false ),
+ new ( "/a?b" , "axb" , false ),
+ new ( "/a" , "*" , false ),
+ new ( "/*" , "*" , false ),
+ new ( "/*" , "a" , true ),
+ new ( "/*" , "a/" , false ),
+ new ( "/*" , "/a" , true ),
+ new ( "/*" , "/a/" , false ),
+ new ( "/*" , "a/b" , false ),
+ new ( "/*" , "/a/b" , false ),
+ new ( "/*" , "[" , true ),
+ new ( "/*" , "]" , true ),
+ new ( "/*" , "!" , true ),
+ new ( "/**" , "!" , true ),
+ new ( "/a*" , "a" , true ),
+ new ( "/a*" , "a/x" , true ),
+ new ( "/a*" , "a/x/d" , true ),
+ new ( "/a*" , "ab" , true ),
+ new ( "/a*" , "ab/x" , true ),
+ new ( "/a*" , "ab/x/d" , true ),
+ new ( "/a/**" , "a" , false ),
+ new ( "/*/**" , "a" , false ),
+ new ( "/*/**" , "a/" , false ),
+ new ( "/*/**" , "a/b" , false ),
+ new ( "/*/" , "a" , false ),
+ new ( "/*/" , "a/" , true ),
+ new ( "/*/b" , "a/b" , true ),
+ new ( "/**/a" , "a" , true ),
+ new ( "/**/a" , "x/ba" , false ),
+ new ( "/a/*" , "a" , false ),
+ new ( "/a/*" , "a/" , true ),
+ new ( "/a/*" , "a/b" , true ),
+ new ( "/a/*" , "a/b/" , false ),
+ new ( "/a/*" , "a/b/c" , false ),
+ new ( "/a/*/" , "a" , false ),
+ new ( "/a/*/" , "a/" , false ),
+ new ( "/a/*/" , "a/b" , false ),
+ new ( "/a/*/" , "a/b/" , true ),
+ new ( "/a/*/" , "a/b/c" , true ),
+ new ( "/a/**" , "a" , false ),
+ new ( "/a/**" , "a/" , false ),
+ new ( "/a/**" , "a/b" , false ),
+ new ( "/a/**" , "a/b/" , false ),
+ new ( "/a/**" , "a/b/c" , false ),
+ new ( "/a/**/" , "a" , false ),
+ new ( "/a/**/" , "a/" , false ),
+ new ( "/a/**/" , "a/b" , false ),
+ new ( "/a/**/" , "a/b/" , false ),
+ new ( "/a/**/" , "a/b/c" , false ),
+ new ( "/**/a/" , "a" , false ),
+ new ( "/**/a/" , "a/" , true ),
+ new ( "/**/a/" , "a/b" , true ),
+ new ( "/**/b/" , "a/b" , false ),
+ new ( "/**/b/" , "a/b/" , true ),
+ new ( "/**/b/" , "a/c/" , false ),
+ new ( "/a/*/b/" , "a/b/" , false ),
+ new ( "/a/*/b/" , "a/x/b/" , true ),
+ new ( "/a/*/b/" , "a/x/b/c" , true ),
+ new ( "/a/*/b/" , "a/x/c" , false ),
+ new ( "/a/*/b/" , "a/x/y/b" , false ),
+ new ( "/a**b/" , "a/x/y/b" , false ),
+ new ( "/a/**/b/" , "a/b" , false ),
+ new ( "/a/**/b/" , "a/b/" , true ),
+ new ( "/a/**/b/" , "a/x/b/" , true ),
+ new ( "/a/**/b/" , "a/x/y/b/" , true ),
+ new ( "/a/**/b/" , "a/x/y/c" , false ),
+ new ( "/a/**/b/" , "a-b/" , false ),
+ new ( "a/*/*" , "a/b" , false ),
+ new ( "/a/*/*/d" , "a/b/c/d" , true ),
+ new ( "/a/*/*/d" , "a/b/x/c/d" , false ),
+ new ( "/a/**/*/d" , "a/b/x/c/d" , true ),
+ new ( "*/*/b" , "a/b" , false ),
+ new ( "/a*/" , "abc/" , true ),
+ new ( "/a*/" , "ab/c/" , true ),
+ new ( "/*b*/" , "axbyc/" , true ),
+ new ( "/*c/" , "abc/" , true ),
+ new ( "/*c/" , "a/abc/" , false ),
+ new ( "/a*c/" , "axbyc/" , true ),
+ new ( "/a*c/" , "axb/yc/" , false ),
+ new ( "/**/*x*/" , "a/b/cxy/d" , true ),
+ new ( "/a/*.md" , "a/x.md" , true ),
+ new ( "/*/*/*.md" , "a/b/x.md" , true ),
+ new ( "/**/*.md" , "a/b.md/x.md" , true ),
+ new ( "**/*.md" , "a/b.md/x.md" , false ),
+ new ( "/*.md" , "a/md" , false ),
+ new ( "/a.*" , "a.b" , true ),
+ new ( "/a.*" , "a.b/" , true ),
+ new ( "/a.*" , "x/a.b/" , false ),
+ new ( "/a.*/" , "a.b" , false ),
+ new ( "/a.*/" , "a.b/" , true ),
+ new ( "/**/*x*/AB/*/CD" , "a/b/cxy/AB/fff/CD" , true ),
+ new ( "/**/*x*/AB/*/CD" , "a/b/cxy/AB/ff/ff/CD" , false ),
+ new ( "/**/*x*/AB/**/CD/*" , "a/b/cxy/AB/ff/ff/CD" , false ),
+ new ( "/**/*x*/AB/**/CD/*" , "a/b/cxy/AB/ff/ff/CD/" , true ),
+ new ( "/**/*x*/AB/**/CD/*" , "a/b/cxy/AB/[]/!!/CD/h" , true ),
// @formatter:on
};
///
- /// Exercises Azure.Sdk.Tools.CodeOwnersParser.Tests.CodeownersFileTests.testCases.
+ /// Exercises CodeownersFileTests.testCases
/// See comment on that member for details.
///
[TestCaseSource(nameof(testCases))]
@@ -217,6 +215,9 @@ private static void VerifyGetMatchingCodeownersEntry(
Assert.That(entry.Owners, Has.Count.EqualTo(expectedMatch ? 1 : 0));
}
+ ///
+ /// Please see comment on CodeownersFileTests.testCases
+ ///
public record TestCase(
string CodeownersPath,
string TargetPath,
diff --git a/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/RetrieveCodeOwnersProgramTests.cs b/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/RetrieveCodeOwnersProgramTests.cs
index 2ab96772ac8..1879eecda4d 100644
--- a/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/RetrieveCodeOwnersProgramTests.cs
+++ b/tools/code-owners-parser/Azure.Sdk.Tools.RetrieveCodeOwners.Tests/RetrieveCodeOwnersProgramTests.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text.Json;
using Azure.Sdk.Tools.CodeOwnersParser;
using NUnit.Framework;
@@ -21,50 +22,115 @@ namespace Azure.Sdk.Tools.RetrieveCodeOwners.Tests;
public class RetrieveCodeOwnersProgramTests
{
///
- /// Given:
+ /// A battery of test cases exercising the Azure.Sdk.Tools.RetrieveCodeOwners.Program.Main executable.
///
- /// file system contents as seen in TestData/InputDir
- ///
- /// codeownersFilePathOrUrl contents as seen in TestData/glob_path_CODEOWNERS
+ /// Each test case is composed of a targetPath and expected CodeownersEntry that is to match against
+ /// the targetPath when the executable is executed.
///
- /// targetPath of /**
+ /// These test battery is used in the following ways:
///
- /// excludeNonUserAliases set to false
- ///
- /// When:
- /// The retrieve-codeowners tool is executed on these inputs.
+ /// 1. In OutputsCorrectCodeownersOnSimpleTargetPath parameterized unit test, each test case is exercised
+ /// by running the executable with targetPath provided as input targetPath.
///
- /// Then:
- /// The tool should return on STDOUT owners matched as seen in the
- /// "expectedEntries" dictionary.
- ///
+ /// 2. In OutputsCorrectCodeownersOnGlobTargetPath the entire test battery is asserted against
+ /// by running the executable with targetPaths set to "/**", thus entering the glob-matching mode and finding
+ /// all the targetPaths present in this battery.
+ ///
+ /// Preconditions for running tests against this battery:
+ /// - directory "./TestData/InputDir" and file "./TestData/test_CODEOWNERS" contain appropriate contents
+ /// - the exercised executable is passed as input appropriate arguments pointing to the file system;
+ /// consult the aforementioned tests for concrete values.
+ ///
+ private static readonly TestCase[] testCases =
+ {
+ // @formatter:off
+ // targetPath expected CodeownersEntry
+ new ("a.txt" , new CodeownersEntry("/*", new List { "star" })),
+ new ("b.txt" , new CodeownersEntry("/*", new List { "star" })),
+ new ("foo/a.txt" , new CodeownersEntry("/foo/**/a.txt", new List { "foo_2star_a" })),
+ new ("foo/b.txt" , new CodeownersEntry("/**", new List { "2star" })),
+ new ("foo/bar/a.txt" , new CodeownersEntry("/foo/*/a.txt", new List { "foo_star_a_1", "foo_star_a_2" })),
+ new ("foo/bar/b.txt" , new CodeownersEntry("/**", new List { "2star" })),
+ new ("baz/cor/c.txt" , new CodeownersEntry("/baz*", new List { "baz_star" })),
+ new ("baz_.txt" , new CodeownersEntry("/baz*", new List { "baz_star" })),
+ new ("qux/abc/d.txt" , new CodeownersEntry("/qux/", new List { "qux" })),
+ new ("cor.txt" , new CodeownersEntry("/*", new List { "star" })),
+ new ("cor2/a.txt" , new CodeownersEntry("/**", new List { "2star" })),
+ new ("cor/gra/a.txt" , new CodeownersEntry("/**", new List { "2star" }))
+ // @formatter:on
+ };
+
+ private static Dictionary TestCasesAsDictionary
+ => testCases.ToDictionary(
+ testCase => testCase.TargetPath,
+ testCase => testCase.ExpectedCodeownersEntry);
+
+ ///
+ /// Please see comment on RetrieveCodeOwnersProgramTests.testCases
+ ///
+ [TestCaseSource(nameof(testCases))]
+ public void OutputsCorrectCodeownersOnSimpleTargetPath(TestCase testCase)
+ {
+ const string targetDir = "./TestData/InputDir";
+ const string codeownersFilePathOrUrl = "./TestData/test_CODEOWNERS";
+ const bool excludeNonUserAliases = false;
+
+ var targetPath = testCase.TargetPath;
+ var expectedEntry = testCase.ExpectedCodeownersEntry;
+
+ // Act
+ (string actualOutput, string actualErr, int returnCode) = RunProgramMain(
+ targetPath,
+ codeownersFilePathOrUrl,
+ excludeNonUserAliases,
+ targetDir);
+
+ CodeownersEntry actualEntry = TryDeserializeActualEntryFromSimpleTargetPath(actualOutput, actualErr);
+
+ Assert.Multiple(() =>
+ {
+ Assert.That(actualEntry, Is.EqualTo(expectedEntry), $"path: {targetPath}");
+ Assert.That(returnCode, Is.EqualTo(0));
+ Assert.That(actualErr, Is.EqualTo(string.Empty));
+ });
+ }
+
+ ///
+ /// Please see comment on RetrieveCodeOwnersProgramTests.testCases
///
[Test]
- public void OutputsCodeowners()
+ public void OutputsCorrectCodeownersOnGlobTargetPath()
{
const string targetDir = "./TestData/InputDir";
const string targetPath = "/**";
const string codeownersFilePathOrUrl = "./TestData/test_CODEOWNERS";
const bool excludeNonUserAliases = false;
- var expectedEntries = new Dictionary
+ Dictionary expectedEntriesByPath = TestCasesAsDictionary;
+
+ // Act
+ (string actualOutput, string actualErr, int returnCode) = RunProgramMain(
+ targetPath,
+ codeownersFilePathOrUrl,
+ excludeNonUserAliases,
+ targetDir);
+
+ Dictionary actualEntriesByPath = TryDeserializeActualEntriesFromGlobTargetPath(actualOutput, actualErr);
+
+ Assert.Multiple(() =>
{
- // @formatter:off
- ["a.txt"] = new CodeownersEntry("/*", new List { "star" }),
- ["b.txt"] = new CodeownersEntry("/*", new List { "star" }),
- ["foo/a.txt"] = new CodeownersEntry("/foo/**/a.txt", new List { "foo_2star_a" }),
- ["foo/b.txt"] = new CodeownersEntry("/**", new List { "2star" }),
- ["foo/bar/a.txt"] = new CodeownersEntry("/foo/*/a.txt", new List { "foo_star_a_1", "foo_star_a_2" }),
- ["foo/bar/b.txt"] = new CodeownersEntry("/**", new List { "2star" }),
- ["baz/cor/c.txt"] = new CodeownersEntry("/baz*", new List { "baz_star" }),
- ["baz_.txt"] = new CodeownersEntry("/baz*", new List { "baz_star" }),
- ["qux/abc/d.txt"] = new CodeownersEntry("/qux/", new List { "qux" }),
- ["cor.txt"] = new CodeownersEntry("/*", new List { "star" }),
- ["cor2/a.txt"] = new CodeownersEntry("/**", new List { "2star" }),
- ["cor/gra/a.txt"] = new CodeownersEntry("/**", new List { "2star" }),
- // @formatter:on
- };
-
+ AssertEntries(actualEntriesByPath, expectedEntriesByPath);
+ Assert.That(returnCode, Is.EqualTo(0));
+ Assert.That(actualErr, Is.EqualTo(string.Empty));
+ });
+ }
+
+ private static (string actualOutput, string actualErr, int returnCode) RunProgramMain(
+ string targetPath,
+ string codeownersFilePathOrUrl,
+ bool excludeNonUserAliases,
+ string targetDir)
+ {
string actualOutput, actualErr;
int returnCode;
using (var consoleOutput = new ConsoleOutput())
@@ -80,17 +146,31 @@ public void OutputsCodeowners()
actualErr = consoleOutput.GetStderr();
}
- var actualEntries = TryDeserializeActualEntries(actualOutput, actualErr);
+ return (actualOutput, actualErr, returnCode);
+ }
- Assert.Multiple(() =>
+ private static CodeownersEntry TryDeserializeActualEntryFromSimpleTargetPath(
+ string actualOutput,
+ string actualErr)
+ {
+ CodeownersEntry actualEntry;
+ try
{
- AssertEntries(actualEntries, expectedEntries);
- Assert.That(returnCode, Is.EqualTo(0));
- Assert.That(actualErr, Is.EqualTo(string.Empty));
- });
+ actualEntry =
+ JsonSerializer.Deserialize(actualOutput)!;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ Console.WriteLine("actualOutput: " + actualOutput);
+ Console.WriteLine("actualErr: " + actualErr);
+ throw;
+ }
+
+ return actualEntry;
}
- private static Dictionary TryDeserializeActualEntries(
+ private static Dictionary TryDeserializeActualEntriesFromGlobTargetPath(
string actualOutput,
string actualErr)
{
@@ -124,4 +204,11 @@ private static void AssertEntries(
Assert.That(actualEntries, Has.Count.EqualTo(expectedEntries.Count));
}
+
+ ///
+ /// Please see comment on RetrieveCodeOwnersProgramTests.testCases
+ ///
+ public record TestCase(
+ string TargetPath,
+ CodeownersEntry ExpectedCodeownersEntry);
}