using System.IO; namespace GFramework.SourceGenerators.Tests.Config; /// /// 验证 schema 配置生成器的生成快照。 /// [TestFixture] public class SchemaConfigGeneratorSnapshotTests { /// /// 验证一个最小 monster schema 能生成配置类型和表包装。 /// [Test] public async Task Snapshot_SchemaConfigGenerator() { const string source = """ using System; using System.Collections.Generic; namespace GFramework.Game.Abstractions.Config { public interface IConfigTable { Type KeyType { get; } Type ValueType { get; } int Count { get; } } public interface IConfigTable : IConfigTable where TKey : notnull { TValue Get(TKey key); bool TryGet(TKey key, out TValue? value); bool ContainsKey(TKey key); IReadOnlyCollection All(); } } """; const string schema = """ { "type": "object", "required": ["id", "name"], "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, "hp": { "type": "integer" }, "dropItems": { "type": "array", "items": { "type": "string" } } } } """; var result = SchemaGeneratorTestDriver.Run( source, ("monster.schema.json", schema)); var generatedSources = result.Results .Single() .GeneratedSources .ToDictionary( static sourceResult => sourceResult.HintName, static sourceResult => sourceResult.SourceText.ToString(), StringComparer.Ordinal); var snapshotFolder = Path.Combine( TestContext.CurrentContext.TestDirectory, "..", "..", "..", "Config", "snapshots", "SchemaConfigGenerator"); snapshotFolder = Path.GetFullPath(snapshotFolder); await AssertSnapshotAsync(generatedSources, snapshotFolder, "MonsterConfig.g.cs", "MonsterConfig.g.txt"); await AssertSnapshotAsync(generatedSources, snapshotFolder, "MonsterTable.g.cs", "MonsterTable.g.txt"); } /// /// 对单个生成文件执行快照断言。 /// /// 生成结果字典。 /// 快照目录。 /// 快照文件名。 private static async Task AssertSnapshotAsync( IReadOnlyDictionary generatedSources, string snapshotFolder, string generatedFileName, string snapshotFileName) { if (!generatedSources.TryGetValue(generatedFileName, out var actual)) { Assert.Fail($"Generated source '{generatedFileName}' was not found."); return; } var path = Path.Combine(snapshotFolder, snapshotFileName); if (!File.Exists(path)) { Directory.CreateDirectory(snapshotFolder); await File.WriteAllTextAsync(path, actual); Assert.Fail($"Snapshot not found. Generated new snapshot at:\n{path}"); } var expected = await File.ReadAllTextAsync(path); Assert.That( Normalize(expected), Is.EqualTo(Normalize(actual)), $"Snapshot mismatch: {generatedFileName}"); } /// /// 标准化快照文本以避免平台换行差异。 /// /// 原始文本。 /// 标准化后的文本。 private static string Normalize(string text) { return text.Replace("\r\n", "\n", StringComparison.Ordinal).Trim(); } }