Skip to content

Mutation testing: uncovered pure helper survivors (no-tests bucket) #40

Description

@leynos

Context

Mutation-testing run against main (b850e2fec11b1966d2b73670ae56b5eff195284e), mutmut 3.6.0, local run 2026-07-10: 1025 mutants, 151 killed, 235 survived, 639 no-tests.

This issue covers the first half of the no-tests bucket: pure or trivially harnessed helpers in hooks/post-turn-quality-stop-hook.py with zero executing tests. These are not untestable boundaries — every function below is deterministic and unit-testable with plain pytest (plus capsys/monkeypatch where noted). 261 no-tests mutants fall in this group.

Uncovered functions (no-tests mutant counts)

  • hooks/post-turn-quality-stop-hook.py:719-786format_reason (146 mutants): the entire blocked-reason renderer, including the 60-file truncation boundary and failure-block formatting.
  • hooks/post-turn-quality-stop-hook.py:167-192truncate (18): head/tail split arithmetic and the max_chars <= 0 / marker-length boundaries.
  • hooks/post-turn-quality-stop-hook.py:579-607parse_make_targets (22): the rule regex, comment/indent skipping, and %-pattern exclusion.
  • hooks/post-turn-quality-stop-hook.py:554-576detect_categories (19): extension-to-category mapping.
  • hooks/post-turn-quality-stop-hook.py:807-833targets_for_categories (13): category expansion and the include filter.
  • hooks/post-turn-quality-stop-hook.py:655-675dedup_preserve_order (6).
  • hooks/post-turn-quality-stop-hook.py:610-624is_missing_makefile (5).
  • hooks/post-turn-quality-stop-hook.py:888-904parse_hook_input (4): stdin JSON parsing (monkeypatch stdin).
  • hooks/post-turn-quality-stop-hook.py:907-930resolve_start_cwd (13): hook-input cwd versus CLAUDE_PROJECT_DIR versus os.getcwd() precedence.
  • hooks/post-turn-quality-stop-hook.py:789-804block_and_print (11): JSON payload shape (capsys).
  • hooks/post-turn-quality-stop-hook.py:933-950fail_state (4): state flagging plus blocked payload (capsys).

Analysis

The co-located suite exercises only the compush family, run()'s missing-cwd branch, get_make_targets's missing-make branch, and parse_env's compush flag; mutmut therefore records every mutant in the functions above as "no tests". These helpers carry real behaviour (output truncation arithmetic, Makefile parsing, category detection, the hook's block-payload contract) and mutations here change what agents see when the hook blocks.

Suggested tests

  1. truncate: boundary cases (max_chars = 0, shorter-than-limit, limit shorter than the marker, and an exact head/tail split assertion).
  2. parse_make_targets: a representative make -qp fixture asserting the exact target set, including %-pattern and comment exclusion; is_missing_makefile truthy/falsy cases.
  3. detect_categories / targets_for_categories / dedup_preserve_order: parametrized equality assertions covering every extension set and the include filter.
  4. format_reason: snapshot-style assertions (syrupy is already a dev dependency) for the error, >60-files, detected-categories, and failed-command variants.
  5. parse_hook_input / resolve_start_cwd: valid JSON, invalid JSON, non-dict JSON; cwd key present, CLAUDE_PROJECT_DIR fallback, bare os.getcwd() fallback.
  6. block_and_print / fail_state: parse the emitted JSON and assert decision == "block" and the reason verbatim.

Full worklist: triage worklist.md; dataset SHA b850e2f.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions