Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions tests/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ Lessons that cost iterations getting the patch-coverage and mutation tail gates
- **Help text and docstrings are pinned by the syrupy snapshots, not unit asserts** — a
mutated help string is killed by the regenerated `.ambr`, so `--snapshot-update` and commit
rather than adding redundant `--help` substring asserts.
- **Render width is pinned suite-wide (`COLUMNS=80`), so a `--help` substring assert is
deterministic** — the autouse `fixed_render_size` fixture (`conftest.py`) sets `COLUMNS`/`LINES`
for *every* test, because the no-clip help table ellipsizes a long flag name
(`--end-of-turn-c…`) once its column overflows. Without the pin a `--with-api-key`-style
substring assert passes at a wide local terminal and fails at CI's narrower width — that gap
cost a PR three CI rounds. Don't fight it: a local green is now a CI green for output tests.
A test that genuinely needs a different width passes it on the call
(`runner.invoke(app, argv, env={"COLUMNS": "300"})`), which overrides the default.
- **Typer's `CliRunner` merges stderr into `result.output`, and not in call order**, so don't
assume `splitlines()[-1]` is the command payload. In `--json` mode the env-mismatch warning
is its own `{"warning": …}` line, so filter parsed lines by a key the payload carries
Expand Down
21 changes: 16 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,23 @@ def pin_timezone(monkeypatch):
time.tzset()


@pytest.fixture
@pytest.fixture(autouse=True)
def fixed_render_size(monkeypatch):
# Pin the render width/height so the CLI-surface goldens (the
# test_snapshots_* modules) are byte-identical across machines and CI.
# Named (not autouse): only the snapshot modules opt in via
# `pytestmark = pytest.mark.usefixtures("fixed_render_size")`.
# Pin the render width/height for the *whole* suite so anything that renders
# CLI/help output is byte-identical across machines and CI. Rich/Click derive
# the help width from COLUMNS (falling back to the inherited terminal size),
# and the no-clip table ellipsizes long flag names ("--end-of-turn-c…") once
# the column overflows — so a `--help` substring assertion that passes at a
# contributor's wide local terminal can silently fail at CI's narrower width.
# That exact gap (a hidden `--with-api-key` flag asserted present, clipped away
# in CI) burned three CI rounds on one PR; autouse closes it so a local green
# means a CI green.
#
# Autouse, not opt-in: every test gets the pinned size. A test that needs a
# different width passes it explicitly to the invocation (the canonical pattern
# in test_help_rendering.py: `runner.invoke(app, argv, env={"COLUMNS": "80"})`),
# which CliRunner merges over this default. The snapshot modules still carry an
# explicit `usefixtures("fixed_render_size")` marker to document the dependency.
monkeypatch.setenv("COLUMNS", "80")
monkeypatch.setenv("LINES", "40")

Expand Down
Loading