test(compilers/openapi): stop the reproducer tables drifting - #359
Merged
Conversation
The danglingDir comment said the directory holds twelve issue-#14 reproducers. It holds fourteen -- f31-discriminator-empty-name.yaml and f32-ref-noncanonical-escape.yaml postdate the number -- and the test's own table names all fourteen. A count in a comment beside the list it counts has no way to stay true, so drop it. Dropping the number leaves the drift it came from: the table is hand-maintained, so a fixture copied into the directory and not added to it is compiled by nothing while the suite stays green. Move the table into danglingReproducers() and hold it to the directory in both directions, which is what the comment now points at instead of a count.
OmarAlJarrah
force-pushed
the
docs/dangling-drop-fixture-count
branch
from
August 9, 2026 03:19
b18d5bd to
b3fdf3d
Compare
The drift this PR closes for the dangling reproducers has two more sites. cycleReproducers is a hand-maintained list of cycle_*.yaml fixtures, kept twice — once in this package for the compiler's refusal and once in scan for the pre-parse scan's diagnosis — and neither was held to the directory, so a fixture added to the corpus and left out of a table was exercised by nothing while the suite stayed green. Both tables now carry the twin of the dangling guard. Holding each to the same directory is also what keeps the two from drifting apart, which neither package can check directly since a test package cannot import another's. The path each reads fixtures from is spelled once as reproducerDir, so a guard and its reader cannot disagree about where they are looking. Beside them, two things in the guard this PR added: the length assertion catches a table row naming no fixture *and* fires beside the check above when the directory holds the extra, so its message no longer names one direction as though it were the only one; and the table is read once into a local rather than rebuilt for each of the three uses.
The constant introduced with the table guard said the fixture directory was spelled once, and it was not: the fuzz seed loader in the same file still spelled it twice, so the guard and the seeds could have ended up looking in different places. They matter differently. readReproducer requires the read to succeed, so a wrong path there fails loudly; the seed loader ignores the error and adds nothing, so a wrong path there costs the fuzzer its seeds in silence. Both derive from the constant now, and the bomb fixture uses the constant the package already keeps for it. Seed count is unchanged at 36.
The danglingDir comment credited the enumeration to TestDanglingRefs_Reproducers' table, which is where it was before this branch moved it into danglingReproducers and left the comment behind.
OmarAlJarrah
added a commit
that referenced
this pull request
Aug 11, 2026
The parenthetical listing the invariants read as the set and was not one: it was extended by #119, #271 and #329 as checks landed, then not by #319, which added three. This PR would have been the next to leave it behind. Verify's body and walkChecks are the enumeration and cannot fall out of step with themselves. The comment names a few invariants to orient a reader and points at them for the rest, which is what #359 did to the count beside a table for the same reason.
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
danglingDir's doc comment said the directory holds twelve issue-#14reproducers. It holds fourteen, and the test's own table names all fourteen:
f31-discriminator-empty-name.yamlandf32-ref-noncanonical-escape.yamlarethe two the count predates. The number was true when written and rotted as
fixtures were added.
The count is dropped: a count in a comment beside the list it counts has no way
to stay true, and the table below it is the enumeration.
Dropping the number leaves the drift it came from, though — the table itself is
hand-maintained, so a fixture copied into the directory and not added to the
table is compiled by nothing and the suite stays green while the corpus grows
past it. So the table moves into
danglingReproducers()and a new test holds itto the directory in both directions. That is what the comment now points at
instead of a number.
Test plan
TestDanglingRefs_EveryReproducerIsExercised, confirmed to redden against aplanted defect in each direction rather than accepted because it went green:
f32row fails withf32-ref-noncanonical-escape.yaml is in ../../testdata/dangling/openapi but not in danglingReproducers.f99-ghost.yamlrowfails with
should have 14 item(s), but has 15. That length check catches bothdirections, so its message names neither: it fires beside the check above when
the directory is the side holding the extra, and saying "the table names a
fixture the directory does not hold" there would be false.
The same drift, at its other two sites
cycleReproducersis the same shape: a hand-maintained list ofcycle_*.yamlfixtures, kept twice — in
compilers/openapifor the compiler's refusal, and ininternal/scanfor the pre-parse scan's diagnosis — with nothing holding eitherto the directory. Both were complete when checked (24 rows against 24 fixtures,
verified in both directions), so nothing had drifted yet; what was missing was
anything to stop it.
Both now carry the twin of the guard above. Holding each to the same directory is
also what keeps the two tables from drifting apart, which neither package can
check directly since a test package cannot import another's. Each package spells
its fixture path once as
reproducerDir, so a guard and its reader cannotdisagree about where they are looking.
Planting a
cycle_*.yamlthat no table names reddens both packages; adding a rownaming no fixture reddens both on the count.
mainis merged in, and the full gate is green on the merged branch:gofmt,go vet ./...,golangci-lint run(0 issues),go build ./...,./scripts/check-coverage.sh.Closes #314