Skip to content

Generate a schema that refers to itself from the contract's $defs (0.16.0) - #135

Merged
rasuvaeff merged 2 commits into
masterfrom
feat/defs-recursion
Sep 19, 2026
Merged

rasuvaeff merged 2 commits into
masterfrom
feat/defs-recursion

Conversation

@rasuvaeff

Copy link
Copy Markdown
Owner

Release 0.16.0. Wave 2 of the openapi-contract#159 follow-up.

rasuvaeff/openapi-contract 0.13 compiles a schema whose member is the schema itself — a tree whose children are trees — to $defs plus a local {$ref: '#/$defs/<name>'} for every reference back into the cycle. The generator now unfolds such a def three levels below the root (Gen::recursive) and ends at a leaf compiled with the def bound to nothing, where a reference back to it is unproducible: an optional property is left out, an array that may be empty is left empty, a branch of anyOf/oneOf is skipped, a member of an allOf is inlined as the def's body. A def whose only way down is a required member that is the def itself has no finite instance and is refused; so is a def that is an allOf member of itself; a $ref to anything but the schema's own $defs is refused by name.

JsonBodyEncoder follows the same references, so a nested empty object three levels down is still written as {} (the first probe wrote []).

The zoo gains tree.create (request and response are the tree; id readOnly at every depth); the recorded corpus in openapi-contract grows by its 25 cases (rasuvaeff/openapi-contract#163, merged). Every generated value is checked against the contract's SchemaCheck in the tests, and the unfolded depth is pinned.

  • composer build: 990 tests green; rector clean; roave: no BC change
  • mutation: 4 104 mutants, MSI 91% (gate 91), before the last escaping-name test
  • bin/package-audit: clean
  • constraint: rasuvaeff/openapi-contract ^0.13

openapi-contract 0.13 compiles a schema whose member is the schema itself —
a tree whose children are trees — to $defs plus a local {$ref:
'#/$defs/<name>'} for every reference back into the cycle. The generator
unfolds such a def three levels below the root (Gen::recursive) and ends
at a leaf compiled with the def bound to nothing, where a reference back
to it is unproducible: an optional property is left out, an array that may
be empty is left empty, a branch of anyOf/oneOf is skipped, a member of an
allOf is inlined as the def's body. A def whose only way down is a
required member that is the def itself has no finite instance and is
refused, as is a def that is an allOf member of itself; a $ref to anything
but the schema's own $defs is refused by name.

The JSON body encoder follows the same references, so a nested empty
object three levels down is still written as {}. The zoo gains
tree.create; the corpus recorded from it grows by 25 cases.

Requires rasuvaeff/openapi-contract ^0.13.
@coderabbitai

coderabbitai Bot commented Sep 19, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: fa0a0f5f-e495-4a70-b9aa-414555c644cc


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@rasuvaeff
rasuvaeff merged commit 1634dc5 into master Sep 19, 2026
12 checks passed
@rasuvaeff
rasuvaeff deleted the feat/defs-recursion branch September 19, 2026 23:06
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.

1 participant