diff --git a/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs b/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs new file mode 100644 index 00000000..a419c260 --- /dev/null +++ b/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs @@ -0,0 +1,125 @@ +using System.IO; +using GFramework.Game.Config; +using GFramework.Game.Config.Generated; + +namespace GFramework.Game.Tests.Config; + +/// +/// 验证消费者项目通过 `schemas/**/*.schema.json` 自动拾取 schema 后, +/// 可以直接编译并使用生成的注册辅助、强类型访问入口与运行时加载链路。 +/// +[TestFixture] +public class GeneratedConfigConsumerIntegrationTests +{ + /// + /// 为每个端到端测试准备独立的配置根目录,避免编译期 schema 资产与运行时写入互相污染。 + /// + [SetUp] + public void SetUp() + { + _rootPath = Path.Combine(Path.GetTempPath(), "GFramework.GeneratedConfigTests", Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(_rootPath); + } + + /// + /// 清理测试过程中创建的临时消费者目录。 + /// + [TearDown] + public void TearDown() + { + if (Directory.Exists(_rootPath)) + { + Directory.Delete(_rootPath, true); + } + } + + private string _rootPath = null!; + + /// + /// 验证生成器自动拾取消费者项目的 schema 后, + /// 可以用生成的注册辅助完成加载,并通过强类型表包装访问运行时数据。 + /// + [Test] + public async Task LoadAsync_Should_Support_Generated_Bindings_In_Consumer_Project() + { + CreateFile( + "schemas/monster.schema.json", + """ + { + "title": "Monster Config", + "description": "Defines one monster entry for the end-to-end consumer integration test.", + "type": "object", + "required": ["id", "name", "hp"], + "properties": { + "id": { + "type": "integer", + "description": "Monster identifier." + }, + "name": { + "type": "string", + "description": "Monster display name." + }, + "hp": { + "type": "integer", + "description": "Monster base health." + } + } + } + """); + CreateFile( + "monster/slime.yaml", + """ + id: 1 + name: Slime + hp: 10 + """); + CreateFile( + "monster/goblin.yaml", + """ + id: 2 + name: Goblin + hp: 30 + """); + + var registry = new ConfigRegistry(); + var loader = new YamlConfigLoader(_rootPath) + .RegisterMonsterTable(); + + await loader.LoadAsync(registry); + + var table = registry.GetMonsterTable(); + + Assert.Multiple(() => + { + Assert.That(MonsterConfigBindings.TableName, Is.EqualTo("monster")); + Assert.That(MonsterConfigBindings.ConfigRelativePath, Is.EqualTo("monster")); + Assert.That(MonsterConfigBindings.SchemaRelativePath, Is.EqualTo("schemas/monster.schema.json")); + Assert.That(table.Count, Is.EqualTo(2)); + Assert.That(table.Get(1).Name, Is.EqualTo("Slime")); + Assert.That(table.Get(2).Hp, Is.EqualTo(30)); + Assert.That(registry.TryGetMonsterTable(out var generatedTable), Is.True); + Assert.That(generatedTable, Is.Not.Null); + Assert.That(generatedTable!.All().Select(static config => config.Name), + Is.EquivalentTo(new[] { "Slime", "Goblin" })); + }); + } + + /// + /// 在临时消费者根目录中创建测试文件。 + /// + /// 相对根目录的文件路径。 + /// 要写入的文件内容。 + private void CreateFile( + string relativePath, + string content) + { + var path = Path.Combine(_rootPath, relativePath.Replace('/', Path.DirectorySeparatorChar)); + var directoryPath = Path.GetDirectoryName(path); + if (!string.IsNullOrEmpty(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + + File.WriteAllText(path, content.Replace("\n", Environment.NewLine, StringComparison.Ordinal)); + } +} \ No newline at end of file diff --git a/GFramework.Game.Tests/GFramework.Game.Tests.csproj b/GFramework.Game.Tests/GFramework.Game.Tests.csproj index 7df909e8..6ad45dbe 100644 --- a/GFramework.Game.Tests/GFramework.Game.Tests.csproj +++ b/GFramework.Game.Tests/GFramework.Game.Tests.csproj @@ -19,6 +19,21 @@ + + + + + + diff --git a/GFramework.Game.Tests/schemas/monster.schema.json b/GFramework.Game.Tests/schemas/monster.schema.json new file mode 100644 index 00000000..4b16aa59 --- /dev/null +++ b/GFramework.Game.Tests/schemas/monster.schema.json @@ -0,0 +1,24 @@ +{ + "title": "Monster Config", + "description": "Defines one monster entry for the generated consumer integration test.", + "type": "object", + "required": [ + "id", + "name", + "hp" + ], + "properties": { + "id": { + "type": "integer", + "description": "Monster identifier." + }, + "name": { + "type": "string", + "description": "Monster display name." + }, + "hp": { + "type": "integer", + "description": "Monster base health." + } + } +} diff --git a/GFramework.SourceGenerators/GeWuYou.GFramework.SourceGenerators.targets b/GFramework.SourceGenerators/GeWuYou.GFramework.SourceGenerators.targets index b66b376d..c2c3af2d 100644 --- a/GFramework.SourceGenerators/GeWuYou.GFramework.SourceGenerators.targets +++ b/GFramework.SourceGenerators/GeWuYou.GFramework.SourceGenerators.targets @@ -12,9 +12,17 @@ - - - + + + +