#!/usr/bin/env python3 """Mutation-test for the probe_forge refactor verifier. Thin wrapper around the shared :func:`_mutant_scanner.run_scan` harness. This module declares only what is specific to the probe-forge subject: the file set, the subject module name, the verifier command, the label column width, and the mutant transforms. The scan loop itself lives in ``_mutant_scanner.py`` and is shared with the triage scanner. Exit 0 = every mutant killed (verifier robust). Exit 1 = at least one mutant survived (verifier too weak). """ from __future__ import annotations import sys from _mutant_scanner import run_scan # noqa: E402 SUBJECT = "_probe_forge_refactored.py" VERIFIER = "python3 verify_probe_forge_refactor.py" LABEL_WIDTH = 26 SRC_FILES = [ "verify_probe_forge_refactor.py", "_probe_forge.py", "_probe_forge_refactored.py", "chunker.py", ] mutants = [] def mutant(label, fn): mutants.append((label, fn)) mutant("guardless", lambda s: s.replace( 'if __name__ == "__main__":\n sys.exit(main())', 'main() # guard-less mutant\n')) mutant("no_main_guard", lambda s: s.replace( 'if __name__ == "__main__":\n sys.exit(main())', 'sys.exit(main()) # no_main_guard mutant\n')) mutant("ffd_flip", lambda s: s.replace( "if actual[i] != expected[i]:", "if actual[i] == expected[i]:")) mutant("ffd_return_none", lambda s: s.replace( " return i\n", " return None # mutant\n")) mutant("ffd_return_i_plus_1", lambda s: s.replace( " return i\n", " return i + 1 # mutant\n")) mutant("ffd_delete_return", lambda s: s.replace( " return i\n", " pass # mutant\n")) mutant("ffd_skip_index_zero", lambda s: s.replace( "for i in range(min(len(actual), len(expected))):", "for i in range(1, min(len(actual), len(expected))):")) mutant("ffd_extend_range", lambda s: s.replace( "for i in range(min(len(actual), len(expected))):", "for i in range(min(len(actual), len(expected)) + 1):")) mutant("ffd_always_return_none", lambda s: s.replace( " for i in range(min(len(actual), len(expected))):\n", " return None # mutant\n for i in range(min(len(actual), len(expected))):\n")) mutant("hardcode_equal", lambda s: s.replace( 'print("equal:", actual == expected)', 'print("equal:", True)')) mutant("reconstruct_overlap_zero", lambda s: s.replace( "actual = chunker.reconstruct(cs, 8)", "actual = chunker.reconstruct(cs, 0)")) def main() -> int: return run_scan(SRC_FILES, SUBJECT, VERIFIER, mutants, LABEL_WIDTH) if __name__ == "__main__": sys.exit(main())