Skip to content

feat: Implement combinators#42

Merged
thced merged 14 commits into
masterfrom
feat/combinators
May 8, 2026
Merged

feat: Implement combinators#42
thced merged 14 commits into
masterfrom
feat/combinators

Conversation

@thced

@thced thced commented May 8, 2026

Copy link
Copy Markdown
Contributor

No description provided.

thced and others added 14 commits May 8, 2026 13:30
Specifies validator and parser changes to implement OpenAPI 3.1
allOf / anyOf / oneOf / not, including composition with sibling
base assertions via implicit AllOf.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three-task plan: validator branches, parser composition, and
integration test for the polymorphic-body case. Mirrors the
combinators design spec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the four UnsupportedOperationException branches for allOf /
anyOf / oneOf / not with real validation. allOf propagates the first
failing branch; anyOf short-circuits on first match; oneOf evaluates
all branches and asserts exactly one matches; not inverts the inner
result. Adds 9 unit tests covering pass/fail per combinator.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Corrected misleading comment in validateOneOf (was "count misses",
  now "branch did not match; continue")
- Added empty-options regression tests for allOf, anyOf, and oneOf
  to pin JSON Schema vacuous-truth / immediate-failure behaviour
- Added null-value tests for not(NullSchema) and anyOf-with-NullSchema
  to document combinator null-passthrough behaviour
- Replaced verbose fully-qualified org.assertj.core.api.Assertions.assertThat
  calls with static import in DefaultValidatorDispatchTest

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously the parser dispatched in priority order and emitted exactly
one schema record, silently discarding combinators that coexisted with
type / properties / etc. Now each combinator and any base assertion
contribute to an assertions list; multiple assertions wrap in an
implicit AllOfSchema. allOf branches flatten into the outer list.

Adds 7 parser tests for the composition path and a regression guard
that a lone combinator still returns the bare combinator record.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reordered `parseBaseIfPresent` so that `primary` (the dominant
non-null TypeName) is only computed after the two implicit-shape
early-return branches (object/array keyword detection), ensuring
it is never evaluated unnecessarily.

Pinned the empty-schema → permissive ObjectSchema behaviour with a
new `parsesEmptySchemaAsPermissiveObject` test, which documents the
intentional deviation from the old NullSchema return.

Added a `parsesEmptyAllOfAsPermissiveObject` regression test to
confirm that `allOf: []` (zero assertions) falls through to the
permissive-object fallback.

Strengthened `allOfBranchesFlattenIntoOuterAllOf` with per-part
instanceof assertions and concrete minLength/maxLength constraint
checks on the flattened StringSchema parts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace stub /anyOf and /allOf fixture routes with a real /shapes
endpoint that uses oneOf to discriminate between circle and square
request bodies. Adds an integration test verifying both valid
branches return 200 and that bodies matching zero branches return
400 application/problem+json with the oneOf keyword in the body.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Delete PolymorphicHandler, which had no unique behaviour over EchoHandler
(both return 200 and reflect the request body). Update all four handler
references in the Shapes nested class to use EchoHandler directly. Adjust
the circle body assertion to check the echoed payload ("kind":"circle")
instead of the old hard-coded {"ok":true} response. Strengthen the
missing-discriminator test with Content-Type and body assertions to mirror
the unknown-kind case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add /filters (anyOf) and /blocked (not) fixture endpoints in both the
YAML and JSON test-spec twins. Register five new IT tests across two new
nested classes (Filters, Blocked) in OpenApiServerIT: valid string,
valid integer, and short-string-rejected for anyOf; accepted-token and
forbidden-token for not. Also clarify the empty-schema comment in
SchemaParserTest to be more precise about what permissive ObjectSchema
means.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the underscore between operation and scenario in the new Shapes,
Filters, and Blocked nested-class tests. Matches the project's
camelCase test-name convention. Older underscore-style tests in this
file are not touched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Strip the underscore between operation and scenario in the existing
Data, ListObjects, QueryParams, and PathParams nested-class tests
(12 methods). Brings the file in line with the project's pure-camelCase
test-method convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All three tasks plus the final verification checklist are done; flip
every step in the plan to [x] to reflect the merged state of the
branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add five tests for parser semantics that previously survived only by
code inspection: $ref ignores siblings, nested allOf is not auto-
flattened past one level, const acts as a base assertion when
siblings exist, not: {} wraps the permissive object, and combinator
branches recurse through parse() so nested combinators stay intact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented May 8, 2026

Copy link
Copy Markdown

@thced thced merged commit 4fd7f68 into master May 8, 2026
4 checks passed
@thced thced deleted the feat/combinators branch May 8, 2026 14:11
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