docs(config): 添加游戏内容配置系统文档与验证工具#206
Conversation
- 新增游戏内容配置系统完整文档,包含 YAML 配置、JSON Schema 结构描述 - 添加运行时只读查询、Source Generator 类型生成等功能说明 - 提供推荐目录结构、Schema 示例和 YAML 示例配置模板 - 添加 VS Code 插件工具支持配置浏览、校验和表单编辑功能 - 实现跨表引用校验、热重载及批量编辑等高级特性文档 - 集成 Architecture 模块化接入和运行时校验行为说明 - 添加配置系统限制说明与独立工具评估结论
Reviewer's Guide扩展共享配置系统,使其在运行时验证器、VS Code 校验/工具以及源码生成器文档中,一致地支持 JSON Schema 对象级属性数量约束(minProperties/maxProperties),并相应更新测试和中文文档。 运行时 minProperties/maxProperties 校验的时序图sequenceDiagram
actor Developer
participant GameRuntime
participant YamlConfigLoader
participant YamlConfigSchemaValidator
participant YamlConfigSchemaNode
participant ConfigLoadExceptionFactory
Developer->>GameRuntime: Start game/load configs
GameRuntime->>YamlConfigLoader: LoadAsync(registry)
rect rgb(235,235,255)
note over YamlConfigLoader,YamlConfigSchemaValidator: Schema parsing phase
YamlConfigLoader->>YamlConfigSchemaValidator: ParseObjectNode(tableName, schemaPath, propertyPath, element)
YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ParseObjectConstraints(..., element)
YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: TryParseObjectPropertyCountConstraint(minProperties)
YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: TryParseObjectPropertyCountConstraint(maxProperties)
alt minProperties > maxProperties
YamlConfigSchemaValidator->>ConfigLoadExceptionFactory: Create(SchemaUnsupported,...)
ConfigLoadExceptionFactory-->>YamlConfigLoader: throw ConfigLoadException
YamlConfigLoader-->>GameRuntime: Propagate exception
GameRuntime-->>Developer: Report schema error
YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: return
end
YamlConfigSchemaValidator-->>YamlConfigLoader: YamlConfigSchemaNode.CreateObject(..., objectConstraints,...)
end
rect rgb(235,255,235)
note over YamlConfigLoader,YamlConfigSchemaValidator: YAML validation phase
YamlConfigLoader->>YamlConfigSchemaValidator: ValidateObjectNode(tableName, yamlPath, displayPath, schemaNode, yamlNode)
YamlConfigSchemaValidator->>YamlConfigSchemaNode: Read ObjectConstraints and Children
YamlConfigSchemaNode-->>YamlConfigSchemaValidator: ObjectConstraints
YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: Count YAML properties
YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ValidateObjectConstraints(tableName, yamlPath, displayPath, propertyCount, schemaNode)
alt propertyCount < MinProperties or propertyCount > MaxProperties
YamlConfigSchemaValidator->>ConfigLoadExceptionFactory: Create(ConstraintViolation,... rawValue=propertyCount)
ConfigLoadExceptionFactory-->>YamlConfigLoader: throw ConfigLoadException
YamlConfigLoader-->>GameRuntime: Propagate exception
GameRuntime-->>Developer: Report constraint violation
else
YamlConfigSchemaValidator-->>YamlConfigLoader: Validation success
YamlConfigLoader-->>GameRuntime: Table registered
GameRuntime-->>Developer: Game continues normally
end
end
YAML 对象属性数量约束的类图classDiagram
direction LR
class YamlConfigSchemaValidator {
<<static>>
ParseObjectNode(tableName string, schemaPath string, propertyPath string, element JsonElement) YamlConfigSchemaNode
ValidateObjectNode(tableName string, yamlPath string, displayPath string, schemaNode YamlConfigSchemaNode, yamlNode object)
ValidateObjectConstraints(tableName string, yamlPath string, displayPath string, propertyCount int, schemaNode YamlConfigSchemaNode)
ParseObjectConstraints(tableName string, schemaPath string, propertyPath string, element JsonElement) YamlConfigObjectConstraints
TryParseObjectPropertyCountConstraint(tableName string, schemaPath string, propertyPath string, element JsonElement, keywordName string) int?
}
class YamlConfigSchemaNode {
+YamlConfigSchemaPropertyType PropertyType
+NodeChildren Children
+string? ReferenceTableName
+IReadOnlyCollection~string~? AllowedValues
+YamlConfigScalarConstraints? Constraints
+YamlConfigArrayConstraints? ArrayConstraints
+YamlConfigObjectConstraints? ObjectConstraints
+string SchemaPathHint
+CreateObject(properties IReadOnlyDictionary~string,YamlConfigSchemaNode~?, requiredProperties IReadOnlyCollection~string~?, objectConstraints YamlConfigObjectConstraints?, schemaPathHint string) YamlConfigSchemaNode
+CreateArray(itemNode YamlConfigSchemaNode, arrayConstraints YamlConfigArrayConstraints?, schemaPathHint string) YamlConfigSchemaNode
+CreateScalar(propertyType YamlConfigSchemaPropertyType, referenceTableName string?, allowedValues IReadOnlyCollection~string~?, constraints YamlConfigScalarConstraints?, schemaPathHint string) YamlConfigSchemaNode
}
class NodeValidation {
+string? ReferenceTableName
+IReadOnlyCollection~string~? AllowedValues
+YamlConfigScalarConstraints? Constraints
+YamlConfigArrayConstraints? ArrayConstraints
+YamlConfigObjectConstraints? ObjectConstraints
+WithReferenceTable(referenceTableName string) NodeValidation
}
class YamlConfigObjectConstraints {
+int? MinProperties
+int? MaxProperties
+YamlConfigObjectConstraints(minProperties int?, maxProperties int?)
}
class YamlConfigArrayConstraints {
+int? MinItems
+int? MaxItems
+bool UniqueItems
}
class YamlConfigScalarConstraints {
+double? Minimum
+double? Maximum
+double? ExclusiveMinimum
+double? ExclusiveMaximum
+double? MultipleOf
+int? MinLength
+int? MaxLength
+string? Pattern
}
YamlConfigSchemaNode o-- NodeValidation : wraps
YamlConfigSchemaNode o-- YamlConfigScalarConstraints : uses
YamlConfigSchemaNode o-- YamlConfigArrayConstraints : uses
YamlConfigSchemaNode o-- YamlConfigObjectConstraints : uses
NodeValidation *-- YamlConfigScalarConstraints : aggregates
NodeValidation *-- YamlConfigArrayConstraints : aggregates
NodeValidation *-- YamlConfigObjectConstraints : aggregates
YamlConfigSchemaValidator --> YamlConfigSchemaNode : creates/reads
YamlConfigSchemaValidator --> YamlConfigObjectConstraints : parses/validates
文件级改动
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 以:
Getting HelpOriginal review guide in EnglishReviewer's GuideExtend the shared config system to support JSON Schema object-level property-count constraints (minProperties/maxProperties) consistently across runtime validator, VS Code validation/tooling, and source generator docs, with tests and Chinese docs updated accordingly. Sequence diagram for runtime minProperties/maxProperties validationsequenceDiagram
actor Developer
participant GameRuntime
participant YamlConfigLoader
participant YamlConfigSchemaValidator
participant YamlConfigSchemaNode
participant ConfigLoadExceptionFactory
Developer->>GameRuntime: Start game/load configs
GameRuntime->>YamlConfigLoader: LoadAsync(registry)
rect rgb(235,235,255)
note over YamlConfigLoader,YamlConfigSchemaValidator: Schema parsing phase
YamlConfigLoader->>YamlConfigSchemaValidator: ParseObjectNode(tableName, schemaPath, propertyPath, element)
YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ParseObjectConstraints(..., element)
YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: TryParseObjectPropertyCountConstraint(minProperties)
YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: TryParseObjectPropertyCountConstraint(maxProperties)
alt minProperties > maxProperties
YamlConfigSchemaValidator->>ConfigLoadExceptionFactory: Create(SchemaUnsupported,...)
ConfigLoadExceptionFactory-->>YamlConfigLoader: throw ConfigLoadException
YamlConfigLoader-->>GameRuntime: Propagate exception
GameRuntime-->>Developer: Report schema error
YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: return
end
YamlConfigSchemaValidator-->>YamlConfigLoader: YamlConfigSchemaNode.CreateObject(..., objectConstraints,...)
end
rect rgb(235,255,235)
note over YamlConfigLoader,YamlConfigSchemaValidator: YAML validation phase
YamlConfigLoader->>YamlConfigSchemaValidator: ValidateObjectNode(tableName, yamlPath, displayPath, schemaNode, yamlNode)
YamlConfigSchemaValidator->>YamlConfigSchemaNode: Read ObjectConstraints and Children
YamlConfigSchemaNode-->>YamlConfigSchemaValidator: ObjectConstraints
YamlConfigSchemaValidator-->>YamlConfigSchemaValidator: Count YAML properties
YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ValidateObjectConstraints(tableName, yamlPath, displayPath, propertyCount, schemaNode)
alt propertyCount < MinProperties or propertyCount > MaxProperties
YamlConfigSchemaValidator->>ConfigLoadExceptionFactory: Create(ConstraintViolation,... rawValue=propertyCount)
ConfigLoadExceptionFactory-->>YamlConfigLoader: throw ConfigLoadException
YamlConfigLoader-->>GameRuntime: Propagate exception
GameRuntime-->>Developer: Report constraint violation
else
YamlConfigSchemaValidator-->>YamlConfigLoader: Validation success
YamlConfigLoader-->>GameRuntime: Table registered
GameRuntime-->>Developer: Game continues normally
end
end
Class diagram for YAML object property-count constraintsclassDiagram
direction LR
class YamlConfigSchemaValidator {
<<static>>
ParseObjectNode(tableName string, schemaPath string, propertyPath string, element JsonElement) YamlConfigSchemaNode
ValidateObjectNode(tableName string, yamlPath string, displayPath string, schemaNode YamlConfigSchemaNode, yamlNode object)
ValidateObjectConstraints(tableName string, yamlPath string, displayPath string, propertyCount int, schemaNode YamlConfigSchemaNode)
ParseObjectConstraints(tableName string, schemaPath string, propertyPath string, element JsonElement) YamlConfigObjectConstraints
TryParseObjectPropertyCountConstraint(tableName string, schemaPath string, propertyPath string, element JsonElement, keywordName string) int?
}
class YamlConfigSchemaNode {
+YamlConfigSchemaPropertyType PropertyType
+NodeChildren Children
+string? ReferenceTableName
+IReadOnlyCollection~string~? AllowedValues
+YamlConfigScalarConstraints? Constraints
+YamlConfigArrayConstraints? ArrayConstraints
+YamlConfigObjectConstraints? ObjectConstraints
+string SchemaPathHint
+CreateObject(properties IReadOnlyDictionary~string,YamlConfigSchemaNode~?, requiredProperties IReadOnlyCollection~string~?, objectConstraints YamlConfigObjectConstraints?, schemaPathHint string) YamlConfigSchemaNode
+CreateArray(itemNode YamlConfigSchemaNode, arrayConstraints YamlConfigArrayConstraints?, schemaPathHint string) YamlConfigSchemaNode
+CreateScalar(propertyType YamlConfigSchemaPropertyType, referenceTableName string?, allowedValues IReadOnlyCollection~string~?, constraints YamlConfigScalarConstraints?, schemaPathHint string) YamlConfigSchemaNode
}
class NodeValidation {
+string? ReferenceTableName
+IReadOnlyCollection~string~? AllowedValues
+YamlConfigScalarConstraints? Constraints
+YamlConfigArrayConstraints? ArrayConstraints
+YamlConfigObjectConstraints? ObjectConstraints
+WithReferenceTable(referenceTableName string) NodeValidation
}
class YamlConfigObjectConstraints {
+int? MinProperties
+int? MaxProperties
+YamlConfigObjectConstraints(minProperties int?, maxProperties int?)
}
class YamlConfigArrayConstraints {
+int? MinItems
+int? MaxItems
+bool UniqueItems
}
class YamlConfigScalarConstraints {
+double? Minimum
+double? Maximum
+double? ExclusiveMinimum
+double? ExclusiveMaximum
+double? MultipleOf
+int? MinLength
+int? MaxLength
+string? Pattern
}
YamlConfigSchemaNode o-- NodeValidation : wraps
YamlConfigSchemaNode o-- YamlConfigScalarConstraints : uses
YamlConfigSchemaNode o-- YamlConfigArrayConstraints : uses
YamlConfigSchemaNode o-- YamlConfigObjectConstraints : uses
NodeValidation *-- YamlConfigScalarConstraints : aggregates
NodeValidation *-- YamlConfigArrayConstraints : aggregates
NodeValidation *-- YamlConfigObjectConstraints : aggregates
YamlConfigSchemaValidator --> YamlConfigSchemaNode : creates/reads
YamlConfigSchemaValidator --> YamlConfigObjectConstraints : parses/validates
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🧰 Additional context used🧠 Learnings (1)📓 Common learnings🔇 Additional comments (8)
📝 WalkthroughWalkthrough在运行时、源生成器与工具链中新增对 JSON Schema 对象级关键字 Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer / Generator
participant Generator as SchemaConfigGenerator
participant Tool as ConfigTool (JS)
participant Loader as YamlConfigLoader
participant Validator as YamlConfigSchemaValidator
participant Registry as ConfigRegistry
Dev->>Generator: 生成带 minProperties/maxProperties 的约束文档
Generator->>Tool: 输出架构元数据(包含约束)
Tool->>Tool: 解析 schema,附加 minProperties/maxProperties 到节点
Loader->>Validator: 加载 YAML 并传入对应 schema 节点
Validator->>Validator: 计数对象属性,校验 min/max
Validator-->>Loader: 若违规,抛出 ConstraintViolation(含 DisplayPath/RawValue)
Loader->>Registry: 成功时注册表项(违规则不注册)
Estimated code review effort🎯 3 (中等) | ⏱️ ~20 分钟 Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并留下了一些整体性的反馈:
- 在 VS Code 工具链中,
localizeValidationMessage现在通过formatObjectPropertyCountMessage对minProperties/maxProperties做了特殊处理,而同样的键也在enMessages/zhCnMessages中定义;建议要么移除这些已不再使用的字典条目,要么改为全部通过字典进行路由,以避免出现重复/相互竞争的消息定义。 - 在
ValidateObjectConstraints中,诊断消息使用了自定义的subject字符串,但仍然传入了GetDiagnosticPath(displayPath);如果对于根对象displayPath为空,请仔细确认这种组合是否生成了预期的诊断路径格式,并且不会在工具中显示空白路径。
面向 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- In the VS Code tooling, `localizeValidationMessage` now special-cases `minProperties`/`maxProperties` via `formatObjectPropertyCountMessage` while the same keys are also defined in `enMessages`/`zhCnMessages`; consider removing the now-unused dictionary entries or routing everything through the dictionary to avoid duplicated/competing message definitions.
- In `ValidateObjectConstraints` the diagnostic messages use a custom `subject` string but still pass `GetDiagnosticPath(displayPath)`; if `displayPath` is empty for root objects, double-check that this combination produces the intended diagnostic path formatting and doesn’t show a blank path in tools.
## Individual Comments
### Comment 1
<location path="GFramework.Game/Config/YamlConfigSchemaValidator.cs" line_range="965-973" />
<code_context>
+ if (minProperties.HasValue && maxProperties.HasValue && minProperties.Value > maxProperties.Value)
+ {
+ throw ConfigLoadExceptionFactory.Create(
+ ConfigLoadFailureKind.SchemaUnsupported,
+ tableName,
+ $"Property '{propertyPath}' in schema file '{schemaPath}' declares 'minProperties' greater than 'maxProperties'.",
+ schemaPath: schemaPath,
+ displayPath: GetDiagnosticPath(propertyPath));
</code_context>
<issue_to_address>
**suggestion:** Error message for invalid min/max properties can be awkward when `propertyPath` is empty (root object).
When this validation runs on the root schema object, `propertyPath` may be empty, yielding a message like `Property '' in schema file ... declares ...`. Please either special‑case the root (e.g., `Root object in schema file ...`) or rely on `GetDiagnosticPath(propertyPath)` for the message text so we don’t surface an empty property name to users.
```suggestion
if (minProperties.HasValue && maxProperties.HasValue && minProperties.Value > maxProperties.Value)
{
var targetDescription = string.IsNullOrEmpty(propertyPath)
? "Root object"
: $"Property '{propertyPath}'";
throw ConfigLoadExceptionFactory.Create(
ConfigLoadFailureKind.SchemaUnsupported,
tableName,
$"{targetDescription} in schema file '{schemaPath}' declares 'minProperties' greater than 'maxProperties'.",
schemaPath: schemaPath,
displayPath: GetDiagnosticPath(propertyPath));
}
```
</issue_to_address>帮我变得更有用!请对每条评论点 👍 或 👎,我会根据你的反馈改进后续的审查建议。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- In the VS Code tooling,
localizeValidationMessagenow special-casesminProperties/maxPropertiesviaformatObjectPropertyCountMessagewhile the same keys are also defined inenMessages/zhCnMessages; consider removing the now-unused dictionary entries or routing everything through the dictionary to avoid duplicated/competing message definitions. - In
ValidateObjectConstraintsthe diagnostic messages use a customsubjectstring but still passGetDiagnosticPath(displayPath); ifdisplayPathis empty for root objects, double-check that this combination produces the intended diagnostic path formatting and doesn’t show a blank path in tools.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In the VS Code tooling, `localizeValidationMessage` now special-cases `minProperties`/`maxProperties` via `formatObjectPropertyCountMessage` while the same keys are also defined in `enMessages`/`zhCnMessages`; consider removing the now-unused dictionary entries or routing everything through the dictionary to avoid duplicated/competing message definitions.
- In `ValidateObjectConstraints` the diagnostic messages use a custom `subject` string but still pass `GetDiagnosticPath(displayPath)`; if `displayPath` is empty for root objects, double-check that this combination produces the intended diagnostic path formatting and doesn’t show a blank path in tools.
## Individual Comments
### Comment 1
<location path="GFramework.Game/Config/YamlConfigSchemaValidator.cs" line_range="965-973" />
<code_context>
+ if (minProperties.HasValue && maxProperties.HasValue && minProperties.Value > maxProperties.Value)
+ {
+ throw ConfigLoadExceptionFactory.Create(
+ ConfigLoadFailureKind.SchemaUnsupported,
+ tableName,
+ $"Property '{propertyPath}' in schema file '{schemaPath}' declares 'minProperties' greater than 'maxProperties'.",
+ schemaPath: schemaPath,
+ displayPath: GetDiagnosticPath(propertyPath));
</code_context>
<issue_to_address>
**suggestion:** Error message for invalid min/max properties can be awkward when `propertyPath` is empty (root object).
When this validation runs on the root schema object, `propertyPath` may be empty, yielding a message like `Property '' in schema file ... declares ...`. Please either special‑case the root (e.g., `Root object in schema file ...`) or rely on `GetDiagnosticPath(propertyPath)` for the message text so we don’t surface an empty property name to users.
```suggestion
if (minProperties.HasValue && maxProperties.HasValue && minProperties.Value > maxProperties.Value)
{
var targetDescription = string.IsNullOrEmpty(propertyPath)
? "Root object"
: $"Property '{propertyPath}'";
throw ConfigLoadExceptionFactory.Create(
ConfigLoadFailureKind.SchemaUnsupported,
tableName,
$"{targetDescription} in schema file '{schemaPath}' declares 'minProperties' greater than 'maxProperties'.",
schemaPath: schemaPath,
displayPath: GetDiagnosticPath(propertyPath));
}
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Greptile SummaryThis PR extends the shared config validation subset ( Key changes:
One asymmetry remains: the JS tool silently accepts a schema where Confidence Score: 4/5Safe to merge; all layers are correctly implemented with good test coverage, and the previous thread concern about missing localization entries is resolved. The implementation is solid and consistent across C# runtime, source generator, and VS Code tool. The localization entries are now present. One P2 asymmetry remains: the JS tool does not warn when a schema declares minProperties > maxProperties (the C# runtime rejects such schemas at load time), which can produce confusing YAML-level diagnostics instead of a schema-level error. This does not affect correctness of well-formed schemas and does not block merging. tools/gframework-config-tool/src/configValidation.js — missing minProperties > maxProperties consistency check at schema-parse time. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Schema JSON file] --> B{Parse schema}
B -->|C# runtime| C[ParseObjectConstraints]
B -->|JS tool| D[parseSchemaNode / normalizeSchemaNonNegativeInteger]
C --> E{minProperties > maxProperties?}
E -->|Yes| F[Throw ConfigLoadException\nSchemaUnsupported]
E -->|No| G[YamlConfigObjectConstraints stored]
D --> H[minProperties + maxProperties stored\nno cross-check]
G --> I[ValidateObjectNode]
H --> J[validateObjectNode]
I --> K{seenProperties.Count\nviolates min or max?}
J --> L{propertyCount\nviolates min or max?}
K -->|Yes| M[Throw ConfigLoadException\nConstraintViolation]
L -->|Yes| N[Push diagnostic via\nlocalizeValidationMessage]
N --> O{displayPath empty?}
O -->|Yes - root object| P[formatObjectPropertyCountMessage\nhardcoded root text]
O -->|No - nested| Q[localizer.t via\nlocalization dictionary]
G --> R[SchemaConfigGenerator\nXML doc output:\nConstraints: minProperties = N]
Reviews (4): Last reviewed commit: "feat(config): 添加配置验证功能模块" | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs`:
- Around line 1251-1358: Add regression tests in YamlConfigLoaderTests to cover
invalid-schema parsing branches: create new tests (e.g.,
LoadAsync_Should_Throw_When_MinProperties_Is_Negative,
LoadAsync_Should_Throw_When_MaxProperties_Is_Negative,
LoadAsync_Should_Throw_When_MinGreaterThanMax) that mirror the existing
LoadAsync_Should_Throw_When_Object_Violates_MinProperties/MaxProperties setup
but write schemas where "minProperties" or "maxProperties" are negative or where
minProperties > maxProperties, then call loader.LoadAsync(registry) and
Assert.ThrowsAsync<ConfigLoadException> and assert
exception.Diagnostic.FailureKind == ConfigLoadFailureKind.SchemaUnsupported (and
appropriate Diagnostic.DisplayPath/Message as needed); place these tests
alongside the existing ones in the YamlConfigLoaderTests class so parsing
failures of bad schemas are asserted.
In `@tools/gframework-config-tool/src/configValidation.js`:
- Line 978: propertyCount is incorrectly computed from yamlNode.entries which
counts duplicate keys; change it to use the node's map semantics instead (derive
the property count from yamlNode.map—e.g. count map items or unique map keys) so
duplicate keys aren't double-counted; update the assignment that sets
propertyCount (currently referencing yamlNode.entries) to read from yamlNode.map
(or compute unique keys from yamlNode.map) and leave minProperties/maxProperties
checks unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 69078e87-04c8-4f43-a2d4-a15dcf1ebfa1
📒 Files selected for processing (11)
GFramework.Game.Tests/Config/YamlConfigLoaderTests.csGFramework.Game/Config/YamlConfigSchemaValidator.csGFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.csGFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txtGFramework.SourceGenerators/Config/SchemaConfigGenerator.csdocs/zh-CN/game/config-system.mdtools/gframework-config-tool/src/configValidation.jstools/gframework-config-tool/src/extension.jstools/gframework-config-tool/src/localization.jstools/gframework-config-tool/src/localizationKeys.jstools/gframework-config-tool/test/configValidation.test.js
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Code Quality & Security
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>tags where applicable
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds, compatibility constraints, or edge cases in C# code
Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and generator pipelines MUST include comments explaining what is generated, why it is generated, the semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling in C# code
Do not rely on implicit imports; declare every requiredusingexplicitly in C# files
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C# files
Use the namespace patternGFramework.{Module}.{Feature}with PascalCase segments in C# code
Follow standard C# naming: Types, methods, properties, events, and constants use PascalCase; Interfaces useIprefix; Parameters and locals use camelCase; Private fields use_camelCase
Use 4 spaces for i...
Files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.csGFramework.Game/Config/YamlConfigSchemaValidator.cs
**/*.Tests/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.Tests/**/*.cs: Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Public API changes must be covered by unit or integration tests
When a public API defines multiple contract branches, tests MUST cover the meaningful variants, including null, empty, default, and filtered inputs when those branches change behavior
Regression fixes should include a test that fails before the fix and passes after it
Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant:ArchitectureTestsBase<T>,SyncTestArchitecture,AsyncTestArchitecture
Keep tests focused on observable behavior, not implementation trivia
Files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
**/*.SourceGenerators.Tests/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.SourceGenerators.Tests/**/*.cs: Source generator changes MUST be covered by generator tests
Preserve snapshot-based verification patterns already used in the repository for source generator tests
When generator behavior changes intentionally, update snapshots together with the implementation in source generator tests
Files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
docs/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Documentation must be located in docs/ directory with Chinese content in docs/zh-CN/
Files:
docs/zh-CN/game/config-system.md
{README.md,docs/**/*.md}
📄 CodeRabbit inference engine (AGENTS.md)
Update the relevant
README.mdordocs/page when behavior, setup steps, architecture guidance, or user-facing examples change
Files:
docs/zh-CN/game/config-system.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
docs/**/*.md: Keep code samples, package names, and command examples in documentation aligned with the current repository state
Prefer documenting behavior and design intent, not only API surface, in repository documentation
For integration-oriented features such as the AI-First config system, documentation MUST cover project directory layout and file conventions, required project or package wiring, minimal working usage example, and migration or compatibility notes when behavior changes
If an existing documentation page no longer reflects the current implementation, updating the documentation is part of fixing the code and cannot be deferred
Do not rely on 'the code is self-explanatory' for framework features that consumers need to adopt; write the adoption path down so future users do not need to rediscover it from source
Files:
docs/zh-CN/game/config-system.md
docs/zh-CN/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in
docs/zh-CN/in the same change
Files:
docs/zh-CN/game/config-system.md
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to docs/zh-CN/**/*.md : When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in `docs/zh-CN/` in the same change
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.cs : Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs
Applied to files:
GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txtGFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation in source generator tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : Source generator changes MUST be covered by generator tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.csGFramework.Game/Config/YamlConfigSchemaValidator.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to docs/**/*.md : For integration-oriented features such as the AI-First config system, documentation MUST cover project directory layout and file conventions, required project or package wiring, minimal working usage example, and migration or compatibility notes when behavior changes
Applied to files:
docs/zh-CN/game/config-system.md
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to docs/zh-CN/**/*.md : When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in `docs/zh-CN/` in the same change
Applied to files:
docs/zh-CN/game/config-system.md
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : Regression fixes should include a test that fails before the fix and passes after it
Applied to files:
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Applied to files:
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
🔇 Additional comments (8)
tools/gframework-config-tool/src/localizationKeys.js (1)
12-12: 新增校验键定义清晰且与语义对齐。Line 12 和 Line 17 的 key 粒度准确,适配对象属性数量约束场景,整体实现可直接合并。
Also applies to: 17-17
tools/gframework-config-tool/src/localization.js (1)
127-128: 双语提示与校验文案同步完整。新增的
minProperties/maxProperties在 English/简中两套字典都已覆盖,且与 validation key 一一对应,避免了本地化缺失。Also applies to: 139-144, 235-236, 247-252
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorSnapshotTests.cs (1)
72-73: 快照测试输入覆盖范围合理。这里同时覆盖了根对象和嵌套对象的属性数量约束,能有效支撑本次生成器输出变更验证。
Also applies to: 118-119
GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfig.g.txt (1)
10-12: 快照输出已正确反映对象约束文档。
MonsterConfig与RewardConfig的<remarks>约束说明已同步到快照,和预期生成行为一致。Also applies to: 80-82
docs/zh-CN/game/config-system.md (1)
15-15: 文档更新与功能变更保持一致。新增内容把
minProperties/maxProperties在能力列表、运行时校验、轻量元数据和 VS Code 表单入口全部串联起来了,集成说明完整。Also applies to: 660-660, 715-715, 812-812
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs (1)
262-263: 对象约束文档生成链路实现完整。从 schema 解析到
SchemaObjectSpec持有,再到AppendObjectType输出<remarks>,这次改动闭环清晰,行为一致。Also applies to: 1881-1887, 2523-2533, 2679-2687
tools/gframework-config-tool/test/configValidation.test.js (1)
311-344: 新增测试覆盖面到位。这两组用例把
minProperties/maxProperties的“解析正确性 + 校验诊断”都补齐了,并且覆盖了嵌套对象场景。Also applies to: 653-676
tools/gframework-config-tool/src/extension.js (1)
1098-1098: 表单对象区块的约束提示接入实现正确。
schema透传 +renderFieldHint扩展后,minProperties/maxProperties可以在 section 级别稳定展示,同时通过includeDescription避免了重复文案。Also applies to: 1306-1306, 1473-1473, 1580-1585, 1588-1589, 1637-1643
- 实现了JSON schema解析器和验证器 - 添加了YAML文档解析和注释提取功能 - 创建了配置验证诊断系统支持中英文本地化 - 实现了批量编辑器可编辑字段收集功能 - 添加了配置文件示例生成功能 - 实现了表单更新应用到YAML的功能 - 添加了精确十进制算术运算支持multipleOf约束检查 - 实现了YAML标量值格式化和引用处理 - 创建了完整的配置验证消息本地化系统
There was a problem hiding this comment.
♻️ Duplicate comments (1)
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs (1)
1360-1410:⚠️ Potential issue | 🟡 Minor建议补齐
maxProperties为负数的解析失败分支Line 1361-1365 当前只覆盖了
minProperties = -1,但同类分支里maxProperties = -1还未单独验证,SchemaUnsupported的另一条路径仍有回归盲区。📌 可选补丁(新增一个对称用例)
+ [Test] + public void LoadAsync_Should_Throw_When_Object_MaxProperties_Is_Negative() + { + CreateConfigFile( + "monster/slime.yaml", + """ + id: 1 + name: Slime + reward: + gold: 10 + """); + CreateSchemaFile( + "schemas/monster.schema.json", + """ + { + "type": "object", + "required": ["id", "name", "reward"], + "properties": { + "id": { "type": "integer" }, + "name": { "type": "string" }, + "reward": { + "type": "object", + "maxProperties": -1, + "properties": { + "gold": { "type": "integer" } + } + } + } + } + """); + + 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.Message, Does.Contain("maxProperties")); + Assert.That(exception.Message, Does.Contain("non-negative integer")); + Assert.That(registry.Count, Is.EqualTo(0)); + }); + }Based on learnings: When a public API defines multiple contract branches, tests MUST cover the meaningful variants, including null, empty, default, and filtered inputs when those branches change behavior.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs` around lines 1360 - 1410, Add a symmetric test to cover the negative maxProperties path: create a new test mirroring LoadAsync_Should_Throw_When_Object_Property_Count_Constraint_Is_Not_NonNegative_Integer that writes a schema with "maxProperties": -1 for the "reward" property, registers the table via YamlConfigLoader, calls loader.LoadAsync(registry) and asserts a ConfigLoadException is thrown with Diagnostic.FailureKind == ConfigLoadFailureKind.SchemaUnsupported, Diagnostic.DisplayPath == "reward", the exception message contains "maxProperties" and "non-negative integer", and that registry.Count remains 0; use the same helpers (CreateConfigFile, CreateSchemaFile) and the same MonsterNestedConfigStub registration to keep the case symmetric.
🧹 Nitpick comments (1)
tools/gframework-config-tool/src/configValidation.js (1)
644-667: 可选改进:考虑在解析阶段验证 schema 约束一致性。当前实现未验证
minProperties > maxProperties这类不一致的 schema 声明。如果 schema 声明了minProperties: 5, maxProperties: 3,配置验证阶段可能会对同一对象同时报告最小和最大约束违规,导致诊断信息令人困惑。可以考虑在
parseSchemaNode中添加一致性检查,在解析阶段就抛出错误:♻️ 可选的改进方案
return { type: "object", displayPath, required, properties, minProperties: metadata.minProperties, maxProperties: metadata.maxProperties, + // 可在此处或调用方添加一致性检查 title: metadata.title, description: metadata.description, defaultValue: metadata.defaultValue };或在返回前添加:
if (typeof metadata.minProperties === "number" && typeof metadata.maxProperties === "number" && metadata.minProperties > metadata.maxProperties) { throw new Error(`Schema property '${displayPath}' declares minProperties (${metadata.minProperties}) greater than maxProperties (${metadata.maxProperties}).`); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tools/gframework-config-tool/src/configValidation.js` around lines 644 - 667, Add a consistency check in parseSchemaNode after computing metadata (minProperties/maxProperties) and before returning the object: if both metadata.minProperties and metadata.maxProperties are numbers and metadata.minProperties > metadata.maxProperties, throw an Error that includes displayPath and both values; this prevents downstream confusing validation by failing fast when a schema declares minProperties greater than maxProperties.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs`:
- Around line 1360-1410: Add a symmetric test to cover the negative
maxProperties path: create a new test mirroring
LoadAsync_Should_Throw_When_Object_Property_Count_Constraint_Is_Not_NonNegative_Integer
that writes a schema with "maxProperties": -1 for the "reward" property,
registers the table via YamlConfigLoader, calls loader.LoadAsync(registry) and
asserts a ConfigLoadException is thrown with Diagnostic.FailureKind ==
ConfigLoadFailureKind.SchemaUnsupported, Diagnostic.DisplayPath == "reward", the
exception message contains "maxProperties" and "non-negative integer", and that
registry.Count remains 0; use the same helpers (CreateConfigFile,
CreateSchemaFile) and the same MonsterNestedConfigStub registration to keep the
case symmetric.
---
Nitpick comments:
In `@tools/gframework-config-tool/src/configValidation.js`:
- Around line 644-667: Add a consistency check in parseSchemaNode after
computing metadata (minProperties/maxProperties) and before returning the
object: if both metadata.minProperties and metadata.maxProperties are numbers
and metadata.minProperties > metadata.maxProperties, throw an Error that
includes displayPath and both values; this prevents downstream confusing
validation by failing fast when a schema declares minProperties greater than
maxProperties.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b0e1054f-2cbe-43ff-b5ae-dbc094b98ef6
📒 Files selected for processing (7)
GFramework.Game.Tests/Config/YamlConfigLoaderTests.csGFramework.Game/Config/YamlConfigSchemaValidator.csGFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.SourceGenerators/Config/SchemaConfigGenerator.cstools/gframework-config-tool/src/configValidation.jstools/gframework-config-tool/src/localization.jstools/gframework-config-tool/test/configValidation.test.js
✅ Files skipped from review due to trivial changes (1)
- tools/gframework-config-tool/test/configValidation.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
- tools/gframework-config-tool/src/localization.js
- GFramework.Game/Config/YamlConfigSchemaValidator.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Code Quality & Security
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>tags where applicable
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds, compatibility constraints, or edge cases in C# code
Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and generator pipelines MUST include comments explaining what is generated, why it is generated, the semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling in C# code
Do not rely on implicit imports; declare every requiredusingexplicitly in C# files
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C# files
Use the namespace patternGFramework.{Module}.{Feature}with PascalCase segments in C# code
Follow standard C# naming: Types, methods, properties, events, and constants use PascalCase; Interfaces useIprefix; Parameters and locals use camelCase; Private fields use_camelCase
Use 4 spaces for i...
Files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
**/*.Tests/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.Tests/**/*.cs: Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Public API changes must be covered by unit or integration tests
When a public API defines multiple contract branches, tests MUST cover the meaningful variants, including null, empty, default, and filtered inputs when those branches change behavior
Regression fixes should include a test that fails before the fix and passes after it
Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant:ArchitectureTestsBase<T>,SyncTestArchitecture,AsyncTestArchitecture
Keep tests focused on observable behavior, not implementation trivia
Files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
**/*.SourceGenerators.Tests/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.SourceGenerators.Tests/**/*.cs: Source generator changes MUST be covered by generator tests
Preserve snapshot-based verification patterns already used in the repository for source generator tests
When generator behavior changes intentionally, update snapshots together with the implementation in source generator tests
Files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to docs/zh-CN/**/*.md : When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation in `docs/zh-CN/` in the same change
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.cs : Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : Source generator changes MUST be covered by generator tests
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation in source generator tests
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.SourceGenerators/Config/SchemaConfigGenerator.csGFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.SourceGenerators.Tests/**/*.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : Regression fixes should include a test that fails before the fix and passes after it
Applied to files:
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.csGFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Applied to files:
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
📚 Learning: 2026-04-09T12:37:37.585Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T12:37:37.585Z
Learning: Applies to **/*.Tests/**/*.cs : When a public API defines multiple contract branches, tests MUST cover the meaningful variants, including null, empty, default, and filtered inputs when those branches change behavior
Applied to files:
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs
🔇 Additional comments (12)
GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs (2)
1251-1358:minProperties/maxProperties运行时回归覆盖做得很好这两组用例同时校验了
FailureKind、DisplayPath、RawValue和registry不变性,回归信号很清晰。
1412-1465:minProperties > maxProperties的反向约束回归用例有效该用例把
SchemaUnsupported与路径/消息断言串起来了,能稳定防回退。GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs (2)
223-223:required改为大小写敏感匹配是正确收敛这里改成
StringComparer.Ordinal能避免生成器与运行时在字段名大小写上的契约分歧。
257-263: 对象约束文档链路已完整打通
minProperties/maxProperties已从解析阶段进入SchemaObjectSpec,并最终落到生成类型的<remarks>,实现和文档输出一致。Also applies to: 1881-1887, 2523-2533, 2679-2687
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs (1)
317-357: 新增大小写敏感回归测试很到位这个用例能直接锁定
required名称比较语义,和本次生成器行为调整保持一致。tools/gframework-config-tool/src/configValidation.js (7)
23-26: LGTM!JSDoc 返回类型正确更新,新增了
minProperties和maxProperties可选字段。
644-645: LGTM!解析逻辑正确使用
normalizeSchemaNonNegativeInteger,与minItems/maxItems等同类约束的处理方式一致。Also applies to: 666-667
970-974: LGTM!属性计数逻辑已正确修复,使用
yamlNode.map.size获取去重后的属性数量,与运行时验证器行为保持一致。
1089-1107: LGTM!消息本地化路由逻辑清晰,将对象相关的验证消息委托给专用格式化函数,提升了代码的可维护性。
1194-1246: LGTM!格式化辅助函数实现完善:
- 正确区分根对象与嵌套对象场景
- 中英文消息表述准确
mode参数清晰区分最小/最大约束
1881-1882: LGTM!
SchemaNode类型定义正确更新,与实现保持一致。
1005-1026: 验证逻辑完全正确,无需进一步修改。
minProperties和maxProperties验证逻辑实现正确,与其他约束检查风格一致。必要的消息键ValidationMessageKeys.minPropertiesViolation和ValidationMessageKeys.maxPropertiesViolation均已在localizationKeys.js中正确定义。
- 验证 YAML 文件扫描和注册功能 - 测试配置表注册选项对象支持 - 验证空选项对象异常处理 - 测试配置目录不存在时的错误处理 - 验证部分加载失败时的回滚机制 - 测试非法 YAML 文件的错误处理 - 验证 schema 校验功能包括必填字段检查 - 测试类型不匹配的字段校验 - 验证标量 enum 限制校验 - 测试数值范围约束校验包括最小值最大值 - 验证数值特殊约束如 exclusiveMinimum/exclusiveMaximum - 测试 multipleOf 约束校验 - 验证大数值和科学计数法处理 - 测试字符串长度和正则模式校验 - 验证数组元素数量和唯一性校验 - 测试未知字段检测 - 验证嵌套对象和对象属性数量校验
- 实现配置架构解析器,支持对象、数组和标量类型的递归解析 - 添加 YAML 配置文件解析和注释提取功能 - 实现配置验证诊断系统,支持多种数据类型的校验 - 添加表单更新应用功能,支持标量和数组值的批量编辑 - 实现配置示例生成功能,包含架构描述作为 YAML 注释 - 添加国际化支持,提供中英文验证消息本地化 - 实现精确十进制运算,确保数值约束验证的准确性 - 添加批处理数组值解析和枚举值标准化功能
Summary by Sourcery
扩展共享配置验证和工具链,在运行时、VS Code 插件、源代码生成器以及文档中支持 JSON Schema 对象属性数量约束。
New Features:
minProperties与maxProperties约束。minProperties与maxProperties元数据。Enhancements:
Documentation:
minProperties和maxProperties约束的统一支持,以及它们在运行时、工具链和生成器中的行为。Tests:
minProperties和maxProperties的情况添加运行时测试。minProperties和maxProperties对象的约束文档输出。Original summary in English
Summary by Sourcery
Extend the shared config validation and tooling to support JSON Schema object property count constraints across runtime, VS Code plugin, source generator, and documentation.
New Features:
Enhancements:
Documentation:
Tests:
Summary by CodeRabbit
新功能
更改
文档
测试