feat(emit): --help, a --panic step, and a gate on the step list - #357
Merged
Merged
Conversation
`emit` is the fixture almost every integration test drives, and the only
description of its 27 steps was the `//!` header of its main.rs: running it
with a typo printed "see the crate doc in fixtures/emit/src/main.rs".
The step language moves to `fixtures/emit/src/steps.txt`, which the module
header includes between its `text` fences and `--help` prints after a short
banner. One copy, so the two cannot say different things. An unknown step
still exits 2 naming the step.
`--panic MESSAGE` is the 28th step, and it exists to test a claim: the
README's "What TestBackend cannot see" table and SKILL.md §1 both promise a
panicking child's message is assertable with `s.contains("panicked")`, and
nothing in fixtures/ had ever panicked. Measured, three ways, in
process.rs: the message reaches the grid from a plain child, from one that
dies inside the alternate screen (where it joins the frame it died on), and
from one that tore the alternate screen down first (where it lands on the
restored primary screen). The status is exit code 101, not a signal. The
README was right; it now has a test.
Closes #304
Closes #311
Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
steps.txt and `emit --help` cannot disagree — they are one file. What they could still disagree with is the match that parses the steps, and a step added to one side only is invisible until it costs a test author an afternoon. check-emit-steps.sh compares the two sets and names the difference in either direction. It runs in the gates-listed job because it needs no toolchain, and is listed in CONTRIBUTING §1 with the other scripts. Proven to fail three ways before being trusted to pass: a documented step with no arm, an arm with no documentation, and a rename on one side (which reports both halves). It also refuses to pass when either pattern matches nothing, so a future edit that breaks the extraction cannot make the gate silently vacuous. Closes #318 Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
vyncint
added a commit
that referenced
this pull request
Sep 16, 2026
…359) Two races in tests added on 2026-09-16, both found by stress.yml and neither reproducible on an idle machine. Test-only. The panic test (#357) waited for `contains("panicked")` and then asserted the message. The Rust runtime writes the location line and the message as separate writes, so the predicate was true one line before the message existed; the `features` job caught it with the grid holding the location line and nothing under it. Every wait now names the message — rule 3 of the wait-semantics contract — and "panicked" is asserted rather than waited on. `with_stdin` (#356) wrote the input with `.expect(…)`. `diff - -` refuses before reading anything, so the child can close the pipe first and the helper panicked on BrokenPipe; stress hit it on both Linux shards. A broken pipe there is a result, not a failure — the callers assert exit code and stderr. Proven both ways by forcing the race with a sleep before the write. Stress on this branch: 15/15 shards green. The Windows queries.rs failure seen earlier is a pre-existing class and is #360.
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.
Three issues about the fixture almost every integration test drives.
emit --help(#304)The step language moves to
fixtures/emit/src/steps.txt. The module headerincludes it between its
```textfences and--helpprints itafter a short banner, so there is one copy and the flag and the header
cannot say different things — which is what #304 asked for, and what makes
#318 possible at all.
--helpis handled before any step is parsed, so it explains itselfwhatever follows it, and it never becomes a
Step.--panic MESSAGE, and what it found (#311)The README's "What
TestBackendcannot see" table andskills/termlens/SKILL.md§1 both promise a panicking child's message is assertable with
s.contains("panicked"). No fixture had ever panicked, so neither claim hada test. #311 asked me to write down what I observe, not what I expect,
and to correct the README if the message did not survive.
The README is right. Measured three ways, all now asserted in
crates/termlens/tests/process.rs:alternate_screen()still trueThe status is an exit code of 101 — the Rust runtime's value — and not a
signal, which is the part the issue asked to take from observation rather
than assumption. No README change is needed.
The test uses a 100-column grid on purpose: the runtime's own
panicked at <file>:<line>line wraps on a narrow one, and a wrapped needlewould make the test about the width instead of the panic.
check-emit-steps.sh(#318)steps.txt and
--helpare one file, so they cannot drift. What they couldstill drift from is the
matchthat parses the steps. The script comparesthe documented set against the implemented arms and names the difference in
either direction. It runs in the
gates-listedjob — no toolchain, just twogreps and a
comm— and is listed in CONTRIBUTING §1 with the other scripts.Proven to fail before being trusted to pass:
It also refuses to pass when either pattern matches nothing, so a future
edit that breaks the extraction cannot quietly turn the gate into a
tautology — the failure mode a grep-based gate actually has.
On
maintoday: 28 documented, 28 implemented, the same set.bash 3.2 clean: no
declare -A, no GNU-only flags, and thecommoutputgoes through files rather than a process substitution so the loop's
status=1is the one that gets read.Verification
cargo test --workspace --all-featuresgreen,fmt,clippy … -D warnings,RUSTDOCFLAGS='-D warnings' cargo doc --no-deps -p emitclean — the lastone matters because the module header is now an
#![doc = include_str!].check-ci-gates-listed.shgreen with the new line in CONTRIBUTING §1.emit --help, an unknown step, and--panicall exercised by hand at aprompt before any test was written; the panic behaviour was observed
through
termlens inspectfirst.What this does not do
fixtures/emitispublish = falseand the script is repo infrastructure.pipxon this machine. The ci.ymlchange is one
- run:with a literal path, no expressions and no newpermissions, so the
zizmorjob is the check on it.fixtures/emit/src/main.rs" are left alone; they still resolve, since theheader is in main.rs. Only
tests/common/mod.rs, the shared helper therest echo, was repointed at steps.txt and the new gate.
--helpis not itself in steps.txt and not counted by the gate: it is nota step, and its arm does not have the shape the script matches. The script
says so where a reader would otherwise wonder.
Closes #304
Closes #311
Closes #318