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
43 changes: 43 additions & 0 deletions MattSourceGenHelpers.Tests/GeneratedCodeTestHelper.cs
Original file line number Diff line number Diff line change
@@ -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.");
}
}
65 changes: 65 additions & 0 deletions MattSourceGenHelpers.Tests/PiExampleFluentTests.cs
Original file line number Diff line number Diff line change
@@ -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<int, int>()
.WithSwitchBody()
.ForCases(0, 1, 2, Integer.Range(300, 303)).CompileTimeBody(decimalNumber => TestSlowMath.CalculatePiDecimal(decimalNumber))
.ForDefaultCase().RuntimeBody(decimalNumber => () => TestSlowMath.CalculatePiDecimal(decimalNumber));
}
60 changes: 60 additions & 0 deletions MattSourceGenHelpers.Tests/PiExampleTests.cs
Original file line number Diff line number Diff line change
@@ -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<int, int> GetPiDecimal_Generator_Fallback() => decimalNumber => TestSlowMath.CalculatePiDecimal(decimalNumber);
}
34 changes: 34 additions & 0 deletions MattSourceGenHelpers.Tests/TestSlowMath.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
36 changes: 1 addition & 35 deletions MattSourceGenHelpers.Tests/UnitTest1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ namespace MattSourceGenHelpers.Tests;

public class Tests
{
private const char UnicodeBom = '\uFEFF';

[Test]
public void ColorsClassLikeGenerator_ProducesExpectedRuntimeOutput()
{
Expand All @@ -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;

Expand All @@ -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
Expand Down