test(mutants): the cursor rule's row clause and the end-of-line clause get a mutant each

The catalogue goes 45 to 47 and the runner stays `killed N of N`, exit 0.

`P8` is PM's own survivor from `44ad845`: the cursor rule one row too lenient
(`height - 1` -> `height - 2`), which survived 51 tests because no arm in
`CURSOR_CASES` stopped a row early. `P13` removes the clause this round added,
so the round leaves a mutant behind and not only a test. Both are judged by
`tests/test_asset_viewable.py`, which is why the per-mutant suite added in the
previous round was worth having.

CHANGELOG under 0.10.1, no new version and no tag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-19 22:57:50 +02:00
commit ce4ff70a21
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
2 changed files with 66 additions and 0 deletions

View file

@ -366,6 +366,24 @@ MUTANTS: tuple[Mutant, ...] = (
" if False:",
suite="tests/test_asset_viewable.py",
),
# PM's P8 from `44ad845`: the cursor rule was held by no arm that could
# see its ROW clause, so a rule one row too lenient survived 51 tests.
Mutant(
"P8 the cursor rule is one row too lenient (height - 1 -> height - 2)",
"src/llm_ingestion_okf/assets.py",
" if y < height - 1 or (y == height - 1 and x < width):",
" if y < height - 2 or (y == height - 1 and x < width):",
suite="tests/test_asset_viewable.py",
),
# And the clause added beside it, so the round that wrote it leaves a
# mutant behind rather than only a test.
Mutant(
"P13 an end-of-line escape may claim a row it never started",
"src/llm_ingestion_okf/assets.py",
" if value == 0:\n if x == 0:",
" if value == 0:\n if False:",
suite="tests/test_asset_viewable.py",
),
# PM's three survivors from `43331fc`, held until now by ordinary tests
# and not by what runs AS the gate.
Mutant(