Skip to content

Do not mistake a grouping node for a schema because of a child's name - #47

Merged
kudima03 merged 1 commit into
mainfrom
fix/boolean-operations-dangling-refs
Aug 21, 2026
Merged

Do not mistake a grouping node for a schema because of a child's name#47
kudima03 merged 1 commit into
mainfrom
fix/boolean-operations-dangling-refs

Conversation

@kudima03

@kudima03 kudima03 commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Closes #46

Cause

CollectDefinitions told a grouping node apart from a schema node by the names of the child keys:

if (child.Any(p => SchemaKeywords.Contains(p.Key)))
{
    result[path] = child;                      // leaf — a schema
}
else
{
    CollectDefinitions(child, path, result);   // group — recurse
}

Specification node names share a namespace with JSON Schema keywords. The booleanOperations group holds or, and and not — and the single not key was enough for Any(...) to return true and for the whole group to be taken for a schema. No recursion happened, so its three members were never emitted.

Beyond the dangling refs this also produced a semantically wrong component: booleanOperations landed in the document as a schema, Microsoft.OpenApi took the not key for the keyword of the same name, and and and or ended up in unrecognizedKeywords.

What changed

A node is now checked first for children that are targets of #/definitions/... pointers. Such a node is always a group, no matter what its children are called. The keyword check stays as the fallback for nodes whose members nothing references.

The set of targets is collected by the new CollectDefinitionPointers, which walks the specification once before the main pass.

Components.Schemas is initialised separately: document.Components ??= new OpenApiComponents() already stood next to it, but on a document without a single generated schema Schemas stayed null and the transformer threw a NullReferenceException — which is what made it impossible to call directly from a test.

Result on the real specification

before after
Schemas in the document 160 162
Dangling refs 3 0
booleanOperations as a schema yes no
booleanOperations_and/_or/_not no yes

Nothing else moved: no existing schema disappeared or changed its contents — exactly three missing ones were added and exactly one wrong component was removed.

Tests

The test project held only FakeTest, so these are the first real tests, written against a minimal specification that reproduces the name collision:

  • EmitsMembersOfGroupNamedLikeSchemaKeyword (a Theory over the three members of the group)
  • DoesNotEmitGroupingNodeAsSchema
  • LeavesNoDanglingComponentReferences — serialises the document and checks that every $ref resolves

Verified that the tests are not vacuous: with the fix reverted all five fail, with the fix all six pass. Every CI step was run locally — dotnet build -warnaserror, dotnet format --verify-no-changes, csharpier check ., dotnet test.

🤖 Generated with Claude Code

@kudima03 kudima03 self-assigned this Aug 21, 2026
CollectDefinitions told a grouping node apart from a schema by the names of
its child keys, but specification node names share a namespace with JSON
Schema keywords. The booleanOperations group holds and/or/not, and the single
"not" key was enough to take the whole group for a schema: its three members
were never emitted, and the refs to booleanOperations_and/_or/_not from
booleanReturning were left dangling.

A node is now checked first for children that are targets of "#/definitions/..."
pointers; such a node is always a group. The keyword heuristic stays as the
fallback.

Components.Schemas is initialised along the way as well: on a document without
a single generated schema the transformer threw a NullReferenceException, which
made it impossible to call directly from a test.

Closes #46

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@kudima03
kudima03 force-pushed the fix/boolean-operations-dangling-refs branch from 48d2e1f to e751a7f Compare August 21, 2026 14:33
@kudima03 kudima03 changed the title Не принимать группирующий узел за схему из-за имени ребёнка Do not mistake a grouping node for a schema because of a child's name Aug 21, 2026
@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
PureQL.CSharp.Model.OpenAPI.Schema 26% 19% 282
Summary 26% (137 / 519) 19% (51 / 266) 282

Minimum allowed line rate is 0%

@kudima03
kudima03 merged commit 1158117 into main Aug 21, 2026
1 check passed
@kudima03
kudima03 deleted the fix/boolean-operations-dangling-refs branch August 21, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dangling refs to booleanOperations_and/_or/_not in the generated document

1 participant