feat(test-fixtures): add shared domain-write fixture catalog - #63
Conversation
The shared catalog keeps Jackson-major write mapping verifiable without per-major fixture copies or closed-inventory pins; Jackson 2 must run the full catalog per the Phase 2.18 milestone.
|
Warning Review limit reached
Next review available in: 49 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughThe PR moves domain-write fixtures into a shared version-neutral module, adds an extensible scenario catalog with integrity checks, and updates Jackson 3 tests to execute the catalog. Documentation, dependency rules, and Jackson 2 milestone requirements are also updated. ChangesShared domain-write catalog
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
jsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteScenarios.java (1)
203-221: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the repeated envelope literals into constants.
The envelope at Lines 207-210 and the expected document at Lines 216-218 repeat the same
Links,Meta, andJsonApiObjectvalues. The scenario passes only when both sides stay identical. An edit to one side alone produces a silent expectation change.Bind the three values once and reuse them.
♻️ Proposed refactor
+ private static final Links ENVELOPE_LINKS = Links.ofLinks(Collections.singletonMap("self", null)); + + private static final Meta ENVELOPE_META = Meta.of(Map.of("key", "value")); + + private static final JsonApiObject ENVELOPE_JSONAPI = JsonApiObject.ofVersion("1.1");Then use them in the scenario:
- new DocumentEnvelope( - Links.ofLinks(Collections.singletonMap("self", null)), - Meta.of(Map.of("key", "value")), - JsonApiObject.ofVersion("1.1")), + new DocumentEnvelope(ENVELOPE_LINKS, ENVELOPE_META, ENVELOPE_JSONAPI), DomainWriteOutcome.document( new JsonApiDocument( new DocumentData.SingleResource( articleResource("1", "T", "B", List.of(), null)), null, - Meta.of(Map.of("key", "value")), - JsonApiObject.ofVersion("1.1"), - Links.ofLinks(Collections.singletonMap("self", null)), + ENVELOPE_META, + ENVELOPE_JSONAPI, + ENVELOPE_LINKS, null, Map.of())),Declare the constants before
SCENARIOSso static initialization order is correct.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@jsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteScenarios.java` around lines 203 - 221, In DomainWriteScenarios, extract the shared Links, Meta, and JsonApiObject values used by the “toDocument with envelope passes links, meta, and jsonapi” scenario into constants declared before SCENARIOS, then reuse those constants in both the DocumentEnvelope input and expected JsonApiDocument.jsonapi-java-jackson3/src/main/java/io/github/kazemek/jsonapi/jackson3/internal/MappingDefinitionResolver.java (1)
265-281: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueOptional: build the member array once per property.
fromcallsfindAnnotationAnywherethree times, and each call allocates a new four-element array. Resolve the members once infromand pass the array to each lookup. The behavior does not change.As per coding guidelines: "Run Spotless formatting when Spotless-covered files or formatter configuration changes: `spotlessApply` followed by `spotlessCheck`."♻️ Proposed refactor
static RoleAnnotations from(BeanPropertyDefinition propertyDefinition) { + AnnotatedMember[] members = { + propertyDefinition.getField(), + propertyDefinition.getGetter(), + propertyDefinition.getSetter(), + propertyDefinition.getConstructorParameter() + }; return new RoleAnnotations( - findAnnotationAnywhere(propertyDefinition, JsonApiId.class), - findAnnotationAnywhere(propertyDefinition, JsonApiAttribute.class), - findAnnotationAnywhere(propertyDefinition, JsonApiRelationship.class)); + findAnnotationAnywhere(members, JsonApiId.class), + findAnnotationAnywhere(members, JsonApiAttribute.class), + findAnnotationAnywhere(members, JsonApiRelationship.class)); } private static <A extends Annotation> `@Nullable` A findAnnotationAnywhere( - BeanPropertyDefinition propertyDefinition, Class<A> annotationClass) { - for (AnnotatedMember member : - new AnnotatedMember[] { - propertyDefinition.getField(), - propertyDefinition.getGetter(), - propertyDefinition.getSetter(), - propertyDefinition.getConstructorParameter() - }) { + AnnotatedMember[] members, Class<A> annotationClass) { + for (AnnotatedMember member : members) { // Jackson's getAnnotation is not `@Nullable-annotated`; use hasAnnotation as the presence // check. if (member != null && member.hasAnnotation(annotationClass)) { return member.getAnnotation(annotationClass); } } return null; }Run
spotlessApplyand thenspotlessCheckif you apply this change.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@jsonapi-java-jackson3/src/main/java/io/github/kazemek/jsonapi/jackson3/internal/MappingDefinitionResolver.java` around lines 265 - 281, Update from to construct the four-member AnnotatedMember array once per property and pass it to each annotation lookup instead of recreating it in findAnnotationAnywhere. Adjust findAnnotationAnywhere to accept the precomputed members while preserving its existing lookup order and behavior; run Spotless formatting and verification afterward.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.agentWork/milestones/phase-2-13-shared-domain-write-fixtures.md:
- Around line 39-45: Correct the catalog description around DomainWriteScenarios
to remove the claim that expected outcomes are derived from a Jackson 3 mapper.
State instead that the catalog defines explicit ResourceObject and
JsonApiDocument expectations, while preserving the surrounding explanation about
catalog growth and adapter-suite discovery.
In
`@jsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/ResourceMapperSpec.groovy`:
- Around line 26-52: Remove the shared executedScenarioIds state and separate
coverage feature from ResourceMapperSpec. Keep the full-catalog assertion
mandatory by validating the scenario IDs within the same parameterized feature
that invokes each DomainWriteScenarios entry, using the deterministic scenario
data available there.
In `@jsonapi-java-test-fixtures/README.md`:
- Around line 39-41: Update the Phase 2.13 wording in the README to describe the
flat write catalog as a deliverable rather than completed, since the milestone
remains In progress; preserve the version-neutral and later-phase fixture
statements.
In
`@jsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteScenarios.java`:
- Around line 37-38: Update the TAGS_SET declaration in DomainWriteScenarios to
wrap the LinkedHashSet with an unmodifiable Set while preserving insertion order
and the existing tag values. Keep the shared set contents unchanged so mutation
attempts fail fast.
In
`@jsonapi-java-test-fixtures/src/test/groovy/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteScenariosCatalogSpec.groovy`:
- Around line 144-146: Update the DocumentData.ResourceCollection branch in
linkageIsCollection so it considers only resources declaring relationshipName
and requires every such resource to have collection linkage, using an all-style
validation rather than any-style acceptance. Preserve the existing behavior for
non-collection data.
---
Nitpick comments:
In
`@jsonapi-java-jackson3/src/main/java/io/github/kazemek/jsonapi/jackson3/internal/MappingDefinitionResolver.java`:
- Around line 265-281: Update from to construct the four-member AnnotatedMember
array once per property and pass it to each annotation lookup instead of
recreating it in findAnnotationAnywhere. Adjust findAnnotationAnywhere to accept
the precomputed members while preserving its existing lookup order and behavior;
run Spotless formatting and verification afterward.
In
`@jsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteScenarios.java`:
- Around line 203-221: In DomainWriteScenarios, extract the shared Links, Meta,
and JsonApiObject values used by the “toDocument with envelope passes links,
meta, and jsonapi” scenario into constants declared before SCENARIOS, then reuse
those constants in both the DocumentEnvelope input and expected JsonApiDocument.
🪄 Autofix
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 Plus
Run ID: 6fd37ebc-c48e-4c55-8c39-14dba85e70c6
📒 Files selected for processing (45)
.agentWork/milestones/README.md.agentWork/milestones/phase-2-13-shared-domain-write-fixtures.md.agentWork/milestones/phase-2-18-jackson2-domain-resource-mapping.mdREADME.mddocs/adr/010-architectural-tests.mdgradle/libs.versions.tomljsonapi-java-jackson3/src/main/java/io/github/kazemek/jsonapi/jackson3/JsonApiDomainDocument.javajsonapi-java-jackson3/src/main/java/io/github/kazemek/jsonapi/jackson3/internal/MappingDefinitionResolver.javajsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/CompoundSerializationSpec.groovyjsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/DomainDocumentReaderSpec.groovyjsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/IdentifierConversionSpec.groovyjsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/ResourceBinderSpec.groovyjsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/ResourceMapperIsolationSpec.groovyjsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/ResourceMapperSpec.groovyjsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/ResourceMappingJacksonFeaturesSpec.groovyjsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/SparseFieldsetSpec.groovyjsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/AccessCountingArticle.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/AccessCountingFieldsetArticle.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/ArticleWithArray.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/ArticleWithOptionalRelationship.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/ArticleWithRenamedAuthor.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/BaseComment.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/Comment.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/ConflictArticle.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/ModeratedComment.javajsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/Person.javajsonapi-java-test-fixtures/README.mdjsonapi-java-test-fixtures/build.gradle.ktsjsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/Article.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/ArticleWithSet.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/BlogWithJsonProperty.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/Comment.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/ConventionalId.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteComparisonPolicy.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteInput.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteOperation.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteOutcome.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteScenario.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteScenarios.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/Person.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/SamplePojo.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/Tag.javajsonapi-java-test-fixtures/src/main/java/io/github/kazemek/jsonapi/testfixtures/domainwrite/package-info.javajsonapi-java-test-fixtures/src/test/groovy/io/github/kazemek/jsonapi/testfixtures/architecture/TestFixturesDependencyRulesSpec.groovyjsonapi-java-test-fixtures/src/test/groovy/io/github/kazemek/jsonapi/testfixtures/domainwrite/DomainWriteScenariosCatalogSpec.groovy
💤 Files with no reviewable changes (2)
- jsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/Comment.java
- jsonapi-java-jackson3/src/test/java/io/github/kazemek/jsonapi/jackson3/testmodel/Person.java
Addresses PR review findings: unmodifiable shared tag collection, strict to-many unordered-policy validation, deterministic coverage ordering, and envelope/member-array reuse.
Invoke every scenario supplier, exercise the SamplePojo bean surface, and cover the byId/outcome rejection branches to close the new-code coverage gap on the shared catalog.
|



Summary
Implements Phase 2.13 — Shared Domain Write Test Fixtures: one version-neutral flat domain-to-resource write fixture catalog in
jsonapi-java-test-fixtures, consumed by Jackson-major contract tests.Article,ArticleWithSet,BlogWithJsonProperty,Comment,ConventionalId,Person,Tag,SamplePojo) into the new@NullMarkedio.github.kazemek.jsonapi.testfixtures.domainwritepackage, with the contract@Nullablemembers; deletes the 7 records from the jackson3testmodelpackage and repoints every adapter-local spec/helper import (behavior unchanged).DomainWriteScenarioscatalog (14 scenarios;all()/byId(String)), theDomainWriteOperation/DomainWriteInput/DomainWriteOutcome/DomainWriteComparisonPolicytypes, and Jackson 3ResourceMapperSpecmigrated onto it with a full-catalog coverage assertion (executedScenarioIds == catalogScenarioIds,@Stepwisefor deterministic ordering).TestFixturesDependencyRulesSpecArchUnit rule (ADR-010) enforcing the major-neutral boundary, amends ADR-010's allowlists, and updates module docs + root README.DomainWriteScenariosCatalogSpec. The Jackson 2 full-catalog coverage requirement is pinned contractually in the (refined,Not started) Phase 2.18 milestone.Verification
./gradlew spotlessApply/spotlessCheck— pass./gradlew clean build— pass (incl. ArchUnit + catalog-integrity + coverage specs)Notes
phase-2-13is Complete (final fresh-context review skipped by maintainer decision; the review loop's last finding was fixed and verified closed).phase-2-18(Jackson 2 mandate) refined and plan-reviewed (Pass).