test(compilers/openapi): consolidate the duplicated test fixtures - #328
Merged
Conversation
Nine PRs landed on main after this branch was opened, and two of them added tests to files this branch rewrites. Git reconciled the two edits without a textual conflict, so the merged tree compiled nowhere: the new tests call the package-local helpers this branch deletes. Resolved by pointing those call sites at the package that now owns them — 26 in operations_test.go and schema_test.go across requireNoErrorDiags, findOp, hasDiagCodeAt, pathsSpec, componentSpec and propsByWire. The one real conflict, conformance_test.go's import block, keeps both: the branch added openapitest and #322 added diag, and the file needs each. No test was lost in the merge — the name list gains the new package's 22 and loses nothing against main.
OmarAlJarrah
added a commit
that referenced
this pull request
Aug 9, 2026
Clean merge, and a tree that compiled nowhere: #328 consolidated the openapi test scaffolding into internal/openapitest, and this branch's new tests call six of those helpers by their old package-local names. Git reconciles both edits without a conflict, so the failure only shows on a build. Repointed the eight call sites — componentSpec, requireNoErrorDiags, propsByWire, emptyEitherSchema — across conformance_test.go, compose_test.go, schema_test.go and schema_internal_test.go. Signatures are unchanged, so these are renames. The archtest pin composed on its own: #331 widened loweringRecursions to see methods and this branch adds the four-function nullability cycle, and the merged order already satisfies #331's length-then-first-member comparator. TestLoweringRecursion_IsOnlyTheKnownCycles passes on the result, which is what checks that rather than the eye.
OmarAlJarrah
added a commit
that referenced
this pull request
Aug 9, 2026
Clean merge, and a tree that compiled nowhere: #328 consolidated the openapi test scaffolding into internal/openapitest, and this branch's new tests call six of those helpers by their old package-local names. Git reconciles both edits without a conflict, so the failure only shows on a build. Resolved by repointing the eight call sites — componentSpec, requireNoErrorDiags, propsByWire, emptyEitherSchema — across conformance_test.go, compose_test.go, schema_test.go and schema_internal_test.go. The signatures are unchanged, so these are renames. The archtest pin composed on its own: #331 widened loweringRecursions to see methods and this branch adds the four-function nullability cycle, and the merged order already satisfies #331's length-then-first-member comparator. TestLoweringRecursion_IsOnlyTheKnownCycles passing on the result is what checks that, rather than the eye.
OmarAlJarrah
added a commit
that referenced
this pull request
Aug 9, 2026
The conflict this branch predicted, resolved as it said: #304's TestDetectCycles_EmptyPointerSegmentIsRefused calls Cycles(0, []byte(src)), and Cycles now takes a sourceindex.Index, so the call becomes scanBytes(t, ...). Two the branch could not predict. cycles_test.go: #304 and #310 added a test where this branch adds a scanIndex helper, both at the same offset sharing a closing brace — kept both. And #328 consolidated the openapi test scaffolding into internal/openapitest after this branch was written, so its new entry_internal_test.go calls sourceOf by the package-local name that no longer exists; repointed, with the import added. Byte-identical output re-proven against the merged tree rather than carried over from the branch: 115 sources under testdata compiled through binaries built from main and from this merge, capturing document, stderr and exit code each. diff -r over the two trees is empty.
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.
Summary
Every test package under
compilers/openapicarried its own copy of the same scaffolding.Before this change there were 84 definitions of helpers that exist once now:
sourceOffive times byte for byte,
requireNoErrorDiagsseven times,componentSpecfour,countDiagsAtfive,indexByfive, and so on down a list of 26 names.The duplication is worth stating plainly, because the last word on this issue was that it
would resolve itself. The extraction of the compiler into one package per lowering stage was
expected to retire the fixture; it multiplied it instead. Go test files cannot share
unexported helpers across packages, so every package the split created needed the same
scaffolding and got it by copy.
newRawLowerer, the specific drift the issue named, wentfrom one hand-constructed copy to four.
The change adds
compilers/openapi/internal/openapitest, holding the vocabulary every one ofthose packages needs — building a spec, driving it, and asserting on the diagnostics it
produced — and deletes the copies. Net −660 lines.
What openapitest may hold is bounded by an import rule, not by taste. A helper belongs
there only if every test package under
compilers/openapican import it, internal testpackages included, and an internal test file may not import a package that imports its own.
That caps the imports at
ir,compilers,diagand third-party libraries, and it is whytwo families stay where they are:
parseFull(4 copies). It drives the whole compiler, so it needscompilers/openapi— and
compilers/openapi's own internal tests could then not importopenapitestat all.The four are now written identically so a reader comparing them finds no difference to
account for.
lowererfixture (4 copies). It needslowering.Ctxandschema.AnchorIndex,which would shut out the internal tests of
load,resolve,annotation,schemaandeverything beneath them.
For the second, the issue's actual acceptance criterion is met a different way: within each
of the four packages,
newRawLowererand its sibling entry point now both build on onefield-initialising constructor, so a field added to the struct cannot reach one and miss the
other. That was the drift; hand-construction beside a constructor was the mechanism.
A third family —
componentIDandtypeByName— stays in test files on purpose.internal/archtest's ID-grammar sweep permits a spelled-out type ID in a test file andrefuses one in a production file, which
openapitest's are. Deriving the ID throughcompileto satisfy the sweep would make the lookup agree with the compiler byconstruction, and a lookup that cannot disagree is no longer an oracle. Both the package doc
and each copy record this.
internal/openapitestgets its own entry ininternal/archtest'srulesmap, with theimport ceiling above written down as the reason the entry is narrow.
Left for #326: the six yaml-node builders
internal/nodeviewandinternal/scanshare.ymergeneedsnodeview.MergeTag, so it cannot move;mergeChainis built on it. Splittinga six-function family across two homes reads worse than the duplication, so the family stayed
whole and the constraint is filed rather than lost.
Test plan
This is a refactor with no behaviour change, so the load-bearing evidence is that no test
changed meaning. Comparing
go test ./... -list '.*'before and after, the only differenceis additions — 22 new tests, all in the new package, and zero removals or renames:
(1271 test names before, 1293 after; the raw
-listoutput also differs in per-packagetiming lines, which are not test names.)
The new tests were checked against planted defects rather than read:
ComponentSpecVerstops writingpaths: {}TestComponentSpec_WrapsSchemasInAMinimalDocumentFindOpreturns the first operation whatever the nameTestFindOp_FindsTheOperationBySourceNamelowererOverstops initialisingoperationIDsTestPreserve_AllReasonsReachableincompilers/openapiThe first of those is why an assertion was added: the original test asserted the prefix and
the schemas block but not the
pathskey, and dropping the key reddened nothing anywhere inthe repository — 3.1 makes
pathsoptional while 3.0 requires it, and callers pass bothversions.
Full gate green, coverage gate at exactly 100% including the new package:
The new package needs its own tests rather than riding on its callers': without
-coverpkg,a package is instrumented only by its own test binary, and one with statements and no test
files contributes zero-count blocks to the profile — which fails the gate. That is the same
constraint
internal/testspec's doc comment records, verified here by adding a statement toit and watching the profile.
Closes #87