From dcd92438cf3a870100549d419fcabb0cb17c6613 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 17:34:11 +0000 Subject: [PATCH 1/2] Initial plan From 0f5556c71b37f3a0054773d70bb522cfddcf9bb3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 17:41:01 +0000 Subject: [PATCH 2/2] Add tests for PiExample and PiExampleFluent; refactor to share helper code Co-authored-by: dex3r <3155725+dex3r@users.noreply.github.com> --- .../GeneratedCodeTestHelper.cs | 43 ++++++++++++ .../PiExampleFluentTests.cs | 65 +++++++++++++++++++ MattSourceGenHelpers.Tests/PiExampleTests.cs | 60 +++++++++++++++++ MattSourceGenHelpers.Tests/TestSlowMath.cs | 34 ++++++++++ MattSourceGenHelpers.Tests/UnitTest1.cs | 36 +--------- 5 files changed, 203 insertions(+), 35 deletions(-) create mode 100644 MattSourceGenHelpers.Tests/GeneratedCodeTestHelper.cs create mode 100644 MattSourceGenHelpers.Tests/PiExampleFluentTests.cs create mode 100644 MattSourceGenHelpers.Tests/PiExampleTests.cs create mode 100644 MattSourceGenHelpers.Tests/TestSlowMath.cs diff --git a/MattSourceGenHelpers.Tests/GeneratedCodeTestHelper.cs b/MattSourceGenHelpers.Tests/GeneratedCodeTestHelper.cs new file mode 100644 index 0000000..a7501db --- /dev/null +++ b/MattSourceGenHelpers.Tests/GeneratedCodeTestHelper.cs @@ -0,0 +1,43 @@ +namespace MattSourceGenHelpers.Tests; + +internal static class GeneratedCodeTestHelper +{ + private const char UnicodeBom = '\uFEFF'; + + internal static string ReadGeneratedCode(string generatedFileName) + { + string generatedCodePath = GetGeneratedCodePath(generatedFileName); + return File.ReadAllText(generatedCodePath).TrimStart(UnicodeBom).ReplaceLineEndings("\n").TrimEnd(); + } + + private static string GetGeneratedCodePath(string generatedFileName) + { + string projectDirectory = FindProjectDirectory(); + string[] generatedFiles = Directory.GetFiles(projectDirectory, generatedFileName, SearchOption.AllDirectories); + + if (generatedFiles.Length != 1) + { + throw new AssertionException($"Expected exactly one generated file '{generatedFileName}', but found {generatedFiles.Length}."); + } + + return generatedFiles[0]; + } + + private static string FindProjectDirectory() + { + string? currentDirectory = TestContext.CurrentContext.TestDirectory; + + while (currentDirectory is not null) + { + string projectFilePath = Path.Combine(currentDirectory, "MattSourceGenHelpers.Tests.csproj"); + if (File.Exists(projectFilePath)) + { + return currentDirectory; + } + + currentDirectory = Directory.GetParent(currentDirectory)?.FullName; + } + + throw new DirectoryNotFoundException("Could not locate MattSourceGenHelpers.Tests project directory."); + } +} diff --git a/MattSourceGenHelpers.Tests/PiExampleFluentTests.cs b/MattSourceGenHelpers.Tests/PiExampleFluentTests.cs new file mode 100644 index 0000000..86fd66f --- /dev/null +++ b/MattSourceGenHelpers.Tests/PiExampleFluentTests.cs @@ -0,0 +1,65 @@ +using MattSourceGenHelpers.Abstractions; +// ReSharper disable ConvertClosureToMethodGroup + +namespace MattSourceGenHelpers.Tests; + +[TestFixture] +public class PiExampleFluentTests +{ + [TestCase(0, 3)] + [TestCase(1, 1)] + [TestCase(2, 4)] + [TestCase(300, 3)] + [TestCase(301, 7)] + [TestCase(302, 2)] + [TestCase(303, 4)] + [TestCase(5, 9)] + public void PiExampleFluentLikeGenerator_ProducesExpectedRuntimeOutput(int decimalNumber, int expectedDigit) + { + int result = TestPiFluentClass.GetPiDecimal(decimalNumber); + + Assert.That(result, Is.EqualTo(expectedDigit)); + } + + [Test] + public void PiExampleFluentLikeGenerator_ProducesExpectedGeneratedCode() + { + string generatedCode = GeneratedCodeTestHelper.ReadGeneratedCode("TestPiFluentClass_GetPiDecimal.g.cs"); + string expectedCode = """ + namespace MattSourceGenHelpers.Tests; + + static partial class TestPiFluentClass + { + public static partial int GetPiDecimal(int decimalNumber) + { + switch (decimalNumber) + { + case 0: return 3; + case 1: return 1; + case 2: return 4; + case 300: return 3; + case 301: return 7; + case 302: return 2; + case 303: return 4; + default: return TestSlowMath.CalculatePiDecimal(decimalNumber); + } + } + } + """.ReplaceLineEndings("\n").TrimEnd(); + + Assert.That(generatedCode, Is.EqualTo(expectedCode)); + } +} + +public static partial class TestPiFluentClass +{ + public static partial int GetPiDecimal(int decimalNumber); + + [GeneratesMethod(nameof(GetPiDecimal))] + static IMethodImplementationGenerator GetPiDecimal_Generator() => + Generator + .MethodImplementation() + .WithSwitchBody() + .ForCases(0, 1, 2, Integer.Range(300, 303)).CompileTimeBody(decimalNumber => TestSlowMath.CalculatePiDecimal(decimalNumber)) + .ForDefaultCase().RuntimeBody(decimalNumber => () => TestSlowMath.CalculatePiDecimal(decimalNumber)); +} diff --git a/MattSourceGenHelpers.Tests/PiExampleTests.cs b/MattSourceGenHelpers.Tests/PiExampleTests.cs new file mode 100644 index 0000000..9e38b06 --- /dev/null +++ b/MattSourceGenHelpers.Tests/PiExampleTests.cs @@ -0,0 +1,60 @@ +using MattSourceGenHelpers.Abstractions; +// ReSharper disable ConvertClosureToMethodGroup + +namespace MattSourceGenHelpers.Tests; + +[TestFixture] +public class PiExampleTests +{ + [TestCase(0, 3)] + [TestCase(1, 1)] + [TestCase(2, 4)] + [TestCase(5, 9)] + public void PiExampleLikeGenerator_ProducesExpectedRuntimeOutput(int decimalNumber, int expectedDigit) + { + int result = TestPiClass.GetPiDecimal(decimalNumber); + + Assert.That(result, Is.EqualTo(expectedDigit)); + } + + [Test] + public void PiExampleLikeGenerator_ProducesExpectedGeneratedCode() + { + string generatedCode = GeneratedCodeTestHelper.ReadGeneratedCode("TestPiClass_GetPiDecimal.g.cs"); + string expectedCode = """ + namespace MattSourceGenHelpers.Tests; + + static partial class TestPiClass + { + public static partial int GetPiDecimal(int decimalNumber) + { + switch (decimalNumber) + { + case 0: return 3; + case 1: return 1; + case 2: return 4; + default: return TestSlowMath.CalculatePiDecimal(decimalNumber); + } + } + } + """.ReplaceLineEndings("\n").TrimEnd(); + + Assert.That(generatedCode, Is.EqualTo(expectedCode)); + } +} + +public static partial class TestPiClass +{ + public static partial int GetPiDecimal(int decimalNumber); + + [GeneratesMethod(nameof(GetPiDecimal))] + [SwitchCase(arg1: 0)] + [SwitchCase(arg1: 1)] + [SwitchCase(arg1: 2)] + static int GetPiDecimal_Generator_Specialized(int decimalNumber) => + TestSlowMath.CalculatePiDecimal(decimalNumber); + + [GeneratesMethod(nameof(GetPiDecimal))] + [SwitchDefault] + static Func GetPiDecimal_Generator_Fallback() => decimalNumber => TestSlowMath.CalculatePiDecimal(decimalNumber); +} diff --git a/MattSourceGenHelpers.Tests/TestSlowMath.cs b/MattSourceGenHelpers.Tests/TestSlowMath.cs new file mode 100644 index 0000000..00c410f --- /dev/null +++ b/MattSourceGenHelpers.Tests/TestSlowMath.cs @@ -0,0 +1,34 @@ +namespace MattSourceGenHelpers.Tests; + +internal static class TestSlowMath +{ + // Pi digits string (0-indexed: position 0 = '3', position 1 = '1', position 2 = '4', ...) + private static readonly string PiDigits = + "31415926535897932384626433832795028841971693993751" + + "05820974944592307816406286208998628034825342117067" + + "98214808651328230664709384460955058223172535940812" + + "84811174502841027019385211055596446229489549303819" + + "64428810975665933446128475648233786783165271201909" + + "14564856692346034861045432664821339360726024914127" + + "37245870066063155881748815209209628292540917153643" + + "67892590360011330530548820466521384146951941511609" + + "43305727036575959195309218611738193261179310511854" + + "80744623799627495673518857527248912279381830119491" + + "29833673362440656643086021394946395224737190702179" + + "86094370277053921717629317675238467481846766940513" + + "20005681271452635608277857713427577896091736371787" + + "21468440901224953430146549585371050792279689258923" + + "54201995611212902196086403441815981362977477130996" + + "05187072113499999983729780499510597317328160963185" + + "95024459455346908302642522308253344685035261931188" + + "17101000313783875288658753320838142061717766914730" + + "35982534904287554687311595628638823537875937519577" + + "81857780532171226806613001927876611195909216420198"; + + public static int CalculatePiDecimal(int decimalNumber) + { + if (decimalNumber >= 0 && decimalNumber < PiDigits.Length) + return PiDigits[decimalNumber] - '0'; + return 0; + } +} diff --git a/MattSourceGenHelpers.Tests/UnitTest1.cs b/MattSourceGenHelpers.Tests/UnitTest1.cs index 4f66b4d..e8448c2 100644 --- a/MattSourceGenHelpers.Tests/UnitTest1.cs +++ b/MattSourceGenHelpers.Tests/UnitTest1.cs @@ -4,8 +4,6 @@ namespace MattSourceGenHelpers.Tests; public class Tests { - private const char UnicodeBom = '\uFEFF'; - [Test] public void ColorsClassLikeGenerator_ProducesExpectedRuntimeOutput() { @@ -19,8 +17,7 @@ public void ColorsClassLikeGenerator_ProducesExpectedRuntimeOutput() [Test] public void ColorsClassLikeGenerator_ProducesExpectedGeneratedCode() { - string generatedCodePath = GetGeneratedCodePath(); - string generatedCode = File.ReadAllText(generatedCodePath).TrimStart(UnicodeBom).ReplaceLineEndings("\n").TrimEnd(); + string generatedCode = GeneratedCodeTestHelper.ReadGeneratedCode("TestColorsClass_GetAllColorsString.g.cs"); string expectedCode = """ namespace MattSourceGenHelpers.Tests; @@ -35,37 +32,6 @@ public partial string GetAllColorsString() Assert.That(generatedCode, Is.EqualTo(expectedCode)); } - - private static string GetGeneratedCodePath() - { - string projectDirectory = FindProjectDirectory(); - string[] generatedFiles = Directory.GetFiles(projectDirectory, "TestColorsClass_GetAllColorsString.g.cs", SearchOption.AllDirectories); - - if (generatedFiles.Length != 1) - { - throw new AssertionException($"Expected exactly one generated file, but found {generatedFiles.Length}."); - } - - return generatedFiles[0]; - } - - private static string FindProjectDirectory() - { - string? currentDirectory = TestContext.CurrentContext.TestDirectory; - - while (currentDirectory is not null) - { - string projectFilePath = Path.Combine(currentDirectory, "MattSourceGenHelpers.Tests.csproj"); - if (File.Exists(projectFilePath)) - { - return currentDirectory; - } - - currentDirectory = Directory.GetParent(currentDirectory)?.FullName; - } - - throw new DirectoryNotFoundException("Could not locate MattSourceGenHelpers.Tests project directory."); - } } public enum TestColorsEnum