Skip to content

Mutation testing: uncovered git workflow and check-execution survivors (no-tests bucket) #41

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 second half of the no-tests bucket: the git ref-management workflow and check-execution paths in hooks/post-turn-quality-stop-hook.py, plus the main() composition root. 378 no-tests mutants fall in this group. All bar main() are category-1 gaps testable with the suite's existing mocked-run pattern; none of them requires a new seam.

Uncovered functions (no-tests mutant counts)

  • hooks/post-turn-quality-stop-hook.py:953-1010evaluate_changes (75): category detection wiring, target filtering against the Makefile, code/markdown command grouping, and the block-on-failure decision.
  • hooks/post-turn-quality-stop-hook.py:678-716run_make (65): empty-target early return, make argv, missing-make fallback (exit 127), and output truncation wiring.
  • hooks/post-turn-quality-stop-hook.py:426-465changed_files (46): the three git commands (diff, cached diff, ls-files), line stripping, and result merging.
  • hooks/post-turn-quality-stop-hook.py:331-368ensure_origin_main_ref (39): always-fetch versus fetch-if-missing branching and the "still missing after fetch" path.
  • hooks/post-turn-quality-stop-hook.py:258-278ref_exists (24): the 0/1/other returncode trichotomy.
  • hooks/post-turn-quality-stop-hook.py:302-328ensure_origin_main (22); :239-255fetch_origin_main (20); :218-236ensure_origin_remote (20); :281-299verify_ref (17); :371-399ensure_base_ref (18): the remainder of the base-ref pipeline, including the non-origin/main base-ref branch.
  • hooks/post-turn-quality-stop-hook.py:402-423merge_base (18).
  • hooks/post-turn-quality-stop-hook.py:1167-1184main (14): see below.

Analysis

Nothing in the suite executes the base-ref pipeline or the check-execution layer, so mutmut records every mutant there as "no tests". These paths decide whether the hook fetches, what diff base it uses, which make targets run, and whether a stop is blocked — the core of the hook's contract. All of them are deterministic functions over run() results and are directly testable with the mocked-run pattern already used for has_uncommitted_changes, or against a temporary git repository for higher fidelity.

main() (14 mutants) is assessed as an accepted composition-root boundary rather than a unit-test target: it only composes parse_hook_input, resolve_start_cwd, parse_env, and run_stop_checks. The proposed seam is one end-to-end subprocess test — run the script in a temporary git repository with hook JSON on stdin and assert the exit code and stdout — which covers main() incidentally without unit-testing it.

Suggested tests

  1. ref_exists / verify_ref / fetch_origin_main / ensure_origin_remote: mocked-run cases for each returncode branch, asserting argv and the exact error strings.
  2. ensure_origin_main_ref / ensure_origin_main / ensure_base_ref: parametrized cases for always-fetch, ref-already-present, fetch-then-present, fetch-then-still-missing, and the non-default base-ref branch, asserting the (ok, err, fetched) triples exactly.
  3. merge_base / changed_files: mocked-run success and failure cases; assert the merged, sorted file list including untracked entries.
  4. evaluate_changes: cases for no categories, targets missing from the Makefile (skipped), code and markdown groupings running separately, and a failing command producing a block payload (assert JSON via capsys and the populated HookState).
  5. run_make: empty targets, successful run, failing run (assert truncation applied), and the FileNotFoundError fallback with exit_code == 127.
  6. End-to-end subprocess test of the script itself in a temporary git repository (covers main(), exit code, and the silent-success contract).

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