Files
mutator/tests/test_coverage.py
Robert C. Martin ba4065f3f1 Stop shelling generated test commands and fail closed on git and coverage.
A package path is one argument. Git status uses NUL records and returns git's status. A failed coverage command leaves reports unread, coverage keeps the longest path match, and site walks no longer recurse.
2026-10-03 17:48:32 -05:00

99 lines
3.7 KiB
Python

from mutator.coverage import covered_lines
def test_jacoco_marks_lines_with_covered_instructions(tmp_path):
report = tmp_path / "target" / "site" / "jacoco" / "jacoco.xml"
report.parent.mkdir(parents=True)
report.write_text(
"""<?xml version="1.0"?>
<report name="demo">
<package name="demo">
<sourcefile name="Board.java">
<line nr="3" mi="0" ci="2" mb="0" cb="0"/>
<line nr="4" mi="4" ci="0" mb="1" cb="0"/>
<line nr="5" mi="0" ci="0" mb="0" cb="1"/>
</sourcefile>
</package>
</report>
""",
encoding="utf-8",
)
source = tmp_path / "src" / "demo" / "Board.java"
source.parent.mkdir(parents=True)
source.write_text("package demo;\nclass Board {}\n", encoding="utf-8")
assert covered_lines(tmp_path, source, "java") == {3, 5}
def test_go_profile_marks_hit_lines(tmp_path):
profile = tmp_path / "target" / "coverage" / "go" / "coverage.out"
profile.parent.mkdir(parents=True)
profile.write_text(
"mode: set\n"
"demo/widget.go:2.1,4.2 1 1\n"
"demo/widget.go:5.1,6.2 1 0\n",
encoding="utf-8",
)
source = tmp_path / "demo" / "widget.go"
source.parent.mkdir()
source.write_text("package demo\nfunc Run() {}\n", encoding="utf-8")
assert covered_lines(tmp_path, source, "go") == {2, 3, 4}
assert covered_lines(tmp_path, tmp_path / "other" / "missing.go", "go") is None
empty = tmp_path / "empty"
empty.mkdir()
assert covered_lines(empty, empty / "demo" / "widget.go", "go") is None
def test_lcov_marks_executed_lines(tmp_path):
report = tmp_path / "target" / "coverage" / "python" / "lcov.info"
report.parent.mkdir(parents=True)
report.write_text(
"SF:src/demo/app.py\nDA:1,3\nDA:2,0\nend_of_record\n",
encoding="utf-8",
)
source = tmp_path / "src" / "demo" / "app.py"
source.parent.mkdir(parents=True)
source.write_text("def place():\n return 1\n", encoding="utf-8")
assert covered_lines(tmp_path, source, "python") == {1}
assert covered_lines(tmp_path, source, "clojure") == {1}
def test_lcov_does_not_let_a_shorter_path_steal_hits(tmp_path):
report = tmp_path / "target" / "coverage" / "python" / "lcov.info"
report.parent.mkdir(parents=True)
report.write_text(
"SF:b/app.py\nDA:2,1\nend_of_record\n"
"SF:a/b/app.py\nDA:1,1\nend_of_record\n",
encoding="utf-8",
)
short = tmp_path / "b" / "app.py"
long = tmp_path / "a" / "b" / "app.py"
short.parent.mkdir(parents=True)
long.parent.mkdir(parents=True)
short.write_text("def place():\n return 1\n", encoding="utf-8")
long.write_text("def place():\n return 1\n", encoding="utf-8")
assert covered_lines(tmp_path, long, "python") == {1}
assert covered_lines(tmp_path, short, "python") == {2}
def test_go_profile_does_not_cross_files(tmp_path):
profile = tmp_path / "target" / "coverage" / "go" / "coverage.out"
profile.parent.mkdir(parents=True)
profile.write_text(
"mode: set\n"
"b/widget.go:2.1,2.2 1 1\n"
"a/b/widget.go:3.1,3.2 1 0\n",
encoding="utf-8",
)
short = tmp_path / "b" / "widget.go"
long = tmp_path / "a" / "b" / "widget.go"
short.parent.mkdir(parents=True)
long.parent.mkdir(parents=True)
short.write_text("package b\nfunc Run() {}\n", encoding="utf-8")
long.write_text("package b\nfunc Run() {}\n", encoding="utf-8")
assert covered_lines(tmp_path, short, "go") == {2}
assert covered_lines(tmp_path, long, "go") == set()
profile.write_text("mode: set\na/b/widget.go:2.1,2.2 1 1\n", encoding="utf-8")
assert covered_lines(tmp_path, short, "go") is None
assert covered_lines(tmp_path, long, "go") == {2}