test(config): 添加 YAML 配置加载器单元测试

- 验证 YAML 文件扫描和注册功能
- 测试配置表注册选项对象支持
- 验证空选项对象异常处理
- 测试配置目录不存在时的错误处理
- 验证部分加载失败时的回滚机制
- 测试非法 YAML 文件的错误处理
- 验证 schema 校验功能包括必填字段检查
- 测试类型不匹配的字段校验
- 验证标量 enum 限制校验
- 测试数值范围约束校验包括最小值最大值
- 验证数值特殊约束如 exclusiveMinimum/exclusiveMaximum
- 测试 multipleOf 约束校验
- 验证大数值和科学计数法处理
- 测试字符串长度和正则模式校验
- 验证数组元素数量和唯一性校验
- 测试未知字段检测
- 验证嵌套对象和对象属性数量校验
This commit is contained in:
GeWuYou 2026-04-10 10:20:40 +08:00
parent 7931b41589
commit 1a50d7af39

View File

@ -1409,6 +1409,60 @@ public class YamlConfigLoaderTests
});
}
/// <summary>
/// 验证对象字段将 <c>maxProperties</c> 声明为非整数数值时,会在 schema 解析阶段被拒绝。
/// </summary>
[Test]
public void LoadAsync_Should_Throw_When_Object_MaxProperties_Constraint_Is_Not_Integer()
{
CreateConfigFile(
"monster/slime.yaml",
"""
id: 1
name: Slime
reward:
gold: 10
currency: coin
""");
CreateSchemaFile(
"schemas/monster.schema.json",
"""
{
"type": "object",
"required": ["id", "name", "reward"],
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"reward": {
"type": "object",
"maxProperties": 1.5,
"properties": {
"gold": { "type": "integer" },
"currency": { "type": "string" }
}
}
}
}
""");
var loader = new YamlConfigLoader(_rootPath)
.RegisterTable<int, MonsterNestedConfigStub>("monster", "monster", "schemas/monster.schema.json",
static config => config.Id);
var registry = new ConfigRegistry();
var exception = Assert.ThrowsAsync<ConfigLoadException>(async () => await loader.LoadAsync(registry));
Assert.Multiple(() =>
{
Assert.That(exception, Is.Not.Null);
Assert.That(exception!.Diagnostic.FailureKind, Is.EqualTo(ConfigLoadFailureKind.SchemaUnsupported));
Assert.That(exception.Diagnostic.DisplayPath, Is.EqualTo("reward"));
Assert.That(exception.Message, Does.Contain("maxProperties"));
Assert.That(exception.Message, Does.Contain("non-negative integer"));
Assert.That(registry.Count, Is.EqualTo(0));
});
}
/// <summary>
/// 验证对象字段将 <c>minProperties</c> 声明为大于 <c>maxProperties</c> 时,会在 schema 解析阶段被拒绝。
/// </summary>