diff --git a/GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs b/GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs index fddea068..ecb44a4f 100644 --- a/GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs +++ b/GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs @@ -1635,57 +1635,7 @@ public class YamlConfigLoaderTests [Test] public async Task LoadAsync_Should_Accept_Object_Array_When_Contains_Matches_Declared_Subset_Properties() { - CreateConfigFile( - "monster/slime.yaml", - """ - id: 1 - name: Slime - entries: - - - id: 1 - weight: 2 - - - id: 2 - weight: 3 - """); - CreateSchemaFile( - "schemas/monster.schema.json", - """ - { - "type": "object", - "required": ["id", "name", "entries"], - "properties": { - "id": { "type": "integer" }, - "name": { "type": "string" }, - "entries": { - "type": "array", - "minContains": 1, - "contains": { - "type": "object", - "required": ["id"], - "properties": { - "id": { - "type": "integer", - "const": 1 - } - } - }, - "items": { - "type": "object", - "required": ["id", "weight"], - "properties": { - "id": { "type": "integer" }, - "weight": { "type": "integer" } - } - } - } - } - } - """); - - var loader = new YamlConfigLoader(_rootPath) - .RegisterTable("monster", "monster", "schemas/monster.schema.json", - static config => config.Id); + var loader = CreateLoaderForContainsSubsetObjectArrayScenario(); var registry = new ConfigRegistry(); await loader.LoadAsync(registry); @@ -2553,14 +2503,7 @@ public class YamlConfigLoaderTests [Test] public void LoadAsync_Should_Throw_When_Nested_Object_Array_Reference_Target_Is_Missing() { - CreateConfigFile( - "item/potion.yaml", - """ - id: potion - name: Potion - """); - CreateConfigFile( - "monster/slime.yaml", + var loader = CreateItemBackedMonsterLoader( """ id: 1 name: Slime @@ -2571,21 +2514,7 @@ public class YamlConfigLoaderTests - wave: 2 dropItemId: bomb - """); - CreateSchemaFile( - "schemas/item.schema.json", - """ - { - "type": "object", - "required": ["id", "name"], - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" } - } - } - """); - CreateSchemaFile( - "schemas/monster.schema.json", + """, """ { "type": "object", @@ -2609,13 +2538,9 @@ public class YamlConfigLoaderTests } } } - """); - - var loader = new YamlConfigLoader(_rootPath) - .RegisterTable("item", "item", "schemas/item.schema.json", - static config => config.Id) - .RegisterTable("monster", "monster", "schemas/monster.schema.json", - static config => config.Id); + """, + static config => config.Id, + ("item/potion.yaml", "potion", "Potion")); var registry = new ConfigRegistry(); var exception = Assert.ThrowsAsync(() => loader.LoadAsync(registry)); @@ -2766,41 +2691,14 @@ public class YamlConfigLoaderTests [Test] public void LoadAsync_Should_Throw_When_Array_Reference_Item_Is_Missing() { - CreateConfigFile( - "item/potion.yaml", - """ - id: potion - name: Potion - """); - CreateConfigFile( - "item/slime-gel.yaml", - """ - id: slime_gel - name: Slime Gel - """); - CreateConfigFile( - "monster/slime.yaml", + var loader = CreateItemBackedMonsterLoader( """ id: 1 name: Slime dropItemIds: - potion - missing_item - """); - CreateSchemaFile( - "schemas/item.schema.json", - """ - { - "type": "object", - "required": ["id", "name"], - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" } - } - } - """); - CreateSchemaFile( - "schemas/monster.schema.json", + """, """ { "type": "object", @@ -2815,13 +2713,10 @@ public class YamlConfigLoaderTests } } } - """); - - var loader = new YamlConfigLoader(_rootPath) - .RegisterTable("item", "item", "schemas/item.schema.json", - static config => config.Id) - .RegisterTable("monster", "monster", "schemas/monster.schema.json", - static config => config.Id); + """, + static config => config.Id, + ("item/potion.yaml", "potion", "Potion"), + ("item/slime-gel.yaml", "slime_gel", "Slime Gel")); var registry = new ConfigRegistry(); var exception = Assert.ThrowsAsync(() => loader.LoadAsync(registry)); @@ -2841,35 +2736,14 @@ public class YamlConfigLoaderTests [Test] public void LoadAsync_Should_Throw_When_Contains_Matched_Reference_Target_Is_Missing() { - CreateConfigFile( - "item/potion.yaml", - """ - id: potion - name: Potion - """); - CreateConfigFile( - "monster/slime.yaml", + var loader = CreateItemBackedMonsterLoader( """ id: 1 name: Slime dropItemIds: - potion - missing_item - """); - CreateSchemaFile( - "schemas/item.schema.json", - """ - { - "type": "object", - "required": ["id", "name"], - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" } - } - } - """); - CreateSchemaFile( - "schemas/monster.schema.json", + """, """ { "type": "object", @@ -2890,13 +2764,9 @@ public class YamlConfigLoaderTests } } } - """); - - var loader = new YamlConfigLoader(_rootPath) - .RegisterTable("item", "item", "schemas/item.schema.json", - static config => config.Id) - .RegisterTable("monster", "monster", "schemas/monster.schema.json", - static config => config.Id); + """, + static config => config.Id, + ("item/potion.yaml", "potion", "Potion")); var registry = new ConfigRegistry(); var exception = Assert.ThrowsAsync(() => loader.LoadAsync(registry)); @@ -3353,6 +3223,111 @@ public class YamlConfigLoaderTests } } + /// + /// 为对象数组 contains 子集匹配场景创建加载器,避免测试方法体被大段固定 schema 稀释。 + /// + /// 已注册目标表的加载器。 + private YamlConfigLoader CreateLoaderForContainsSubsetObjectArrayScenario() + { + CreateConfigFile( + "monster/slime.yaml", + """ + id: 1 + name: Slime + entries: + - + id: 1 + weight: 2 + - + id: 2 + weight: 3 + """); + CreateSchemaFile( + "schemas/monster.schema.json", + """ + { + "type": "object", + "required": ["id", "name", "entries"], + "properties": { + "id": { "type": "integer" }, + "name": { "type": "string" }, + "entries": { + "type": "array", + "minContains": 1, + "contains": { + "type": "object", + "required": ["id"], + "properties": { + "id": { + "type": "integer", + "const": 1 + } + } + }, + "items": { + "type": "object", + "required": ["id", "weight"], + "properties": { + "id": { "type": "integer" }, + "weight": { "type": "integer" } + } + } + } + } + } + """); + + return new YamlConfigLoader(_rootPath) + .RegisterTable("monster", "monster", "schemas/monster.schema.json", + static config => config.Id); + } + + /// + /// 为跨表引用加载测试创建标准 item 表夹具,并按既有顺序注册 itemmonster。 + /// + /// monster 表的配置类型。 + /// monster 配置文件内容。 + /// monster schema 内容。 + /// monster 表主键选择器。 + /// 要写入的 item 配置文件集合。 + /// 已完成 schema 与表注册的加载器。 + private YamlConfigLoader CreateItemBackedMonsterLoader( + string monsterConfigContent, + string monsterSchemaContent, + Func keySelector, + params (string RelativePath, string ItemId, string Name)[] items) + { + foreach (var (relativePath, itemId, name) in items) + { + CreateConfigFile( + relativePath, + $""" + id: {itemId} + name: {name} + """); + } + + CreateConfigFile("monster/slime.yaml", monsterConfigContent); + CreateSchemaFile( + "schemas/item.schema.json", + """ + { + "type": "object", + "required": ["id", "name"], + "properties": { + "id": { "type": "string" }, + "name": { "type": "string" } + } + } + """); + CreateSchemaFile("schemas/monster.schema.json", monsterSchemaContent); + + return new YamlConfigLoader(_rootPath) + .RegisterTable("item", "item", "schemas/item.schema.json", + static config => config.Id) + .RegisterTable("monster", "monster", "schemas/monster.schema.json", keySelector); + } + /// /// 创建测试用配置文件。 ///