test(generator): 添加源代码生成器快照测试框架和枚举扩展生成器测试

- 实现 GeneratorSnapshotTest 类用于源代码生成器的快照测试功能
- 添加 EnumExtensionsGeneratorSnapshotTests 测试类验证各种枚举配置的输出
- 创建完整的快照测试基础设施支持生成器输出验证
- 配置测试项目依赖和快照文件管理规则
- 生成多个测试场景的快照文件验证枚举扩展生成功能
This commit is contained in:
GeWuYou 2026-04-16 22:34:09 +08:00
parent 8e38afc6c4
commit fe27dfe609
9 changed files with 32 additions and 13 deletions

View File

@ -1,7 +1,4 @@
using System.IO;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using NUnit.Framework;
namespace GFramework.SourceGenerators.Tests.Core;
@ -17,10 +14,12 @@ public static class GeneratorSnapshotTest<TGenerator>
/// </summary>
/// <param name="source">输入的源代码字符串</param>
/// <param name="snapshotFolder">快照文件存储的文件夹路径</param>
/// <param name="snapshotFileNameSelector">将生成文件名映射为快照文件名的规则;为空时使用原始生成文件名。</param>
/// <returns>异步任务</returns>
public static async Task RunAsync(
string source,
string snapshotFolder)
string snapshotFolder,
Func<string, string>? snapshotFileNameSelector = null)
{
var test = new CSharpSourceGeneratorTest<TGenerator, DefaultVerifier>
{
@ -38,9 +37,11 @@ public static class GeneratorSnapshotTest<TGenerator>
foreach (var (filename, content) in generated)
{
// 不同测试套件可能需要将生成文件映射到非 .cs 快照,以避免测试资产被当作可编译源码参与构建。
var snapshotFileName = snapshotFileNameSelector?.Invoke(filename) ?? filename;
var path = Path.Combine(
snapshotFolder,
filename);
snapshotFileName);
if (!File.Exists(path))
{
@ -57,7 +58,7 @@ public static class GeneratorSnapshotTest<TGenerator>
Assert.That(
Normalize(expected),
Is.EqualTo(Normalize(content.ToString())),
$"Snapshot mismatch: {filename}");
$"Snapshot mismatch: {snapshotFileName}");
}
}
@ -70,4 +71,4 @@ public static class GeneratorSnapshotTest<TGenerator>
{
return text.Replace("\r\n", "\n").Trim();
}
}
}

View File

@ -30,7 +30,8 @@ public class EnumExtensionsGeneratorSnapshotTests
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
source,
GetSnapshotFolder("BasicEnum_IsMethods"));
GetSnapshotFolder("BasicEnum_IsMethods"),
GetSnapshotFileName);
}
/// <summary>
@ -50,7 +51,8 @@ public class EnumExtensionsGeneratorSnapshotTests
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
source,
GetSnapshotFolder("BasicEnum_IsInMethod"));
GetSnapshotFolder("BasicEnum_IsInMethod"),
GetSnapshotFileName);
}
/// <summary>
@ -73,7 +75,8 @@ public class EnumExtensionsGeneratorSnapshotTests
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
source,
GetSnapshotFolder("EnumWithFlagValues"));
GetSnapshotFolder("EnumWithFlagValues"),
GetSnapshotFileName);
}
/// <summary>
@ -94,7 +97,8 @@ public class EnumExtensionsGeneratorSnapshotTests
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
source,
GetSnapshotFolder("DisableIsMethods"));
GetSnapshotFolder("DisableIsMethods"),
GetSnapshotFileName);
}
/// <summary>
@ -115,7 +119,8 @@ public class EnumExtensionsGeneratorSnapshotTests
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
source,
GetSnapshotFolder("DisableIsInMethod"));
GetSnapshotFolder("DisableIsInMethod"),
GetSnapshotFileName);
}
/// <summary>
@ -136,7 +141,8 @@ public class EnumExtensionsGeneratorSnapshotTests
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
source,
GetSnapshotFolder("DisableAllGeneratedMethods"));
GetSnapshotFolder("DisableAllGeneratedMethods"),
GetSnapshotFileName);
}
/// <summary>
@ -158,6 +164,16 @@ public class EnumExtensionsGeneratorSnapshotTests
scenarioName));
}
/// <summary>
/// 将生成器输出文件名映射为非 C# 快照文件名,避免快照资产被命名校验和项目编译误判为源码。
/// </summary>
/// <param name="generatedFileName">生成器输出的提示文件名。</param>
/// <returns>对应的快照文件名。</returns>
private static string GetSnapshotFileName(string generatedFileName)
{
return Path.ChangeExtension(generatedFileName, ".txt");
}
/// <summary>
/// 构造最小自洽的测试输入源码,以稳定驱动枚举扩展生成器的快照测试。
/// </summary>

View File

@ -30,7 +30,9 @@
<ItemGroup>
<Compile Remove="**\snapshots\**\*.cs"/>
<Compile Remove="**\Snapshots\**\*.cs"/>
<None Include="**\snapshots\**\*.cs"/>
<None Include="**\Snapshots\**\*.cs"/>
<Folder Include="rule\snapshots\ContextAwareGenerator\"/>
</ItemGroup>