78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
#!/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())
|