test: a program node nothing produces is caught, rather than waiting for a consumer to meet it - #201
Merged
Merged
Conversation
…for a consumer to meet it Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 28, 2026
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.
Note
The following content was generated by AI.
cases:reached a release candidate in #168 with no lowering at all —CasesNodejoined the AST, nothing produced a program node for it, and the suite was green on 780 tests.assert_nevercatches that only where some test happens to lower a file using the construct, and none did.This is the fence that would have caught it on the first commit:
It is the sibling of
test_the_golden_model_carries_every_node_kind_the_walk_renders, one state along: that one holds the renderer to the AST, this holds the lowering to the program.The two fixtures cannot be one
The obvious move is to point this at
tests/typesetting/golden/model.yaml, which already exists to carry every construct. It does not lower:That is correct, not a bug — rendering accepts more than lowering does, so a fixture proving every render arm is reached cannot also prove every lowering arm is.
tests/fixtures/every_program_node.yamlis the second one, and it is a file that lowers to all thirteen nodes and nothing else.examples/cannot serve either: the gallery reaches twelve of thirteen, missingPower. Adding a**to a teaching model to satisfy a test would be the harness showing through the modelling.Both directions
The reverse assertion — the fixture lowers to nothing that is not a program node — is what stops the fixture drifting into asserting nothing, the way five fences went vacuous at the language cut by scanning a directory that no longer existed.
Mutation table
Taken by hand —
tools/mutate.pycannot express an added class — with a clean tree,git checkout --to restore and__pycache__dropped on both sides.ExpressionNodewith nothing producing itThat is the whole point of the fence, so it is the whole table: the mutation reproduces the exact shape
cases:shipped in.Verified separately, before writing it, that the fence is not vacuous: run over
examples/*.yamlit goes red onmaintoday, missingPower.Verified:
pixi run ci— lint, tests,docs-build --strict, 26 TeX documents. The fixture lives undertests/and is not a gallery model, so nothing renders it.Not done: the same fence for
Predicate. The program's masks are the language's ownWhereNodes since #177, so they are already held by the where-parser's tests — there is no second set to drift. Worth revisiting only if the program ever grows a mask type of its own.