Repository navigation
docs(examples): add a hand-written contract tests example for the API-Only TranscriberJ - #90
Merged
Merged
Conversation
…-Only TranscriberJ A refunds service whose request body is a oneOf with inline branches, which the generator cannot write, and whose 422 comes from a business rule the schema cannot carry. The request body is written by hand in the generated package from the generated constants, pinned to its fragment's hash; one contract test per response checks the shape with the generated REST Docs descriptors; every invalid input and rule is a behaviour test. A workflow of its own runs check on every change.
Arc-E-Tect
added a commit
to Arc-E-Tect/SoftwareEngineeringDoneRight-API
that referenced
this pull request
Sep 18, 2026
…ts (#27) A guide in `docs/guides/hand-written-contract-tests/`, with an overview, a tutorial, a Claude Code prompt and a Codex prompt, for the contract tests the TranscriberJ cannot generate. ## What it covers - **Where the generated tree stops.** Constraints are constants, not checks. Field descriptions are a projection. Some constructs degrade to methods that throw. - **What you still have when a method refuses:** provenance, the operation's path, statuses and content types, constraint constants, and the response side in full. - **Where hand-written code goes, as a design decision** (IMPORTANT box): in the generated package, in the test source set. The package-private members it reaches, `ContractJson` among them, are regenerated every build and are not a published API. - **What you own when you write it:** the values no generated class holds, and four duties that follow from typing them. - **How many tests, and why:** one contract test per response the contract lists, checking only shape. Every invalid input and business rule goes in behaviour tests, as scenarios. - **A worked example:** a `oneOf` with inline branches plus a business-rule 422. The hand-written body sits next to the generated constants it draws on, and the assertions use the generated error-response descriptors. - **When the contract changes underneath:** a removed constant breaks compilation at the line; a renamed member is caught only by the hash guard. - **The remedy:** name the branches. The guard fires, and the generated bodies take over. ## Verified - The tutorial's snippets are expanded by a script from the Library example's files, generated sources, report and scenario runs, all on TranscriberJ 0.3.3. - Regenerating it after the 0.3.3 release gave byte-identical output. - The example PR is Arc-E-Tect/SoftwareEngineeringDoneRight-Library#90. - All AsciiDoc files render without warnings, and every link and anchor resolves. ## Also - `docs/README.adoc`: a row in the Guides table. - The TranscriberJ README's "What this cannot do" section links to the guide. It links back to the #26 sections.
Owner
Author
|
🎉 This PR is included in version 1.0.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Owner
Author
|
🎉 This PR is included in version 1.0.2 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Owner
Author
|
🎉 This PR is included in version 0.2.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Owner
Author
|
🎉 This PR is included in version 1.0.2 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Owner
Author
|
🎉 This PR is included in version 1.0.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A Spring Boot 4.1.1 refunds service under
examples/api-only-transcriberj/hand-written-contract-tests, with contract tests built on the classes TranscriberJ 0.3.3 generates, including where the generator stops.What is in it
POST /orders/{orderId}/refundsanswers with 201, 400, 404 or 422.RefundRequestV1is aoneOfwith inline branches, so itsbody(...)andfields(...)are generated to throw. The report says so and gives the remedy.RefundRequests: the request body, written by hand in the generated package in the test source set.ContractJsonand the generated constraint constants.destinationvalues.RefundRequestsTest, 4 guards:RefundRequestV1.FRAGMENT_SHA256;CreateRefundContractTest, 4 contract tests: one per response. Each checks status and content type againstCreateRefundOperationand the fields against the generatedRefundV1Docs/ProblemV1Docs.responseFields().RefundsTest, 15 behaviour tests: every invalid input and every business rule, as scenarios.example-api-only-transcriberj-hand-written-contract-tests-build.yml, runs./gradlew check. actionlint is clean.Verified on 0.3.3
./gradlew checkpasses: 23 tests.maximumbreaks compilation atAmountV1.MAXIMUM;cardLast4leaves every contract test passing, and only the hash guard fails.CardRefundV1.body(...)andBankAccountRefundV1.body(...)from their own package, andcheckpasses.The tutorial that walks through this example is in the API repository,
docs/guides/hand-written-contract-tests/, in its own PR.Writing this example led to API #25 (the
oneOffixes, released as 0.3.3) and #26 (the README section on hand-written code).