mirror of
https://github.com/unclebob/mutator.git
synced 2026-11-07 10:43:49 +00:00
Count multi-line statement sites as covered from their start line; skip TypeScript type positions
This commit is contained in:
@@ -921,3 +921,12 @@ def test_snapshots_keep_other_files_empty_directories_and_odd_records(tmp_path):
|
||||
assert not (base / "empty").exists()
|
||||
assert (full / "keep.edn").is_file()
|
||||
_remove_empty_dirs(tmp_path / "missing-metrics")
|
||||
|
||||
|
||||
def test_scan_counts_a_site_inside_a_covered_multi_line_statement(tmp_path):
|
||||
path = tmp_path / "src" / "demo.py"
|
||||
path.parent.mkdir()
|
||||
path.write_text("def add(a, b):\n return (a\n + b)\n", encoding="utf-8")
|
||||
scanned = scan_file(path, tmp_path, covered_lines={2}, ignore_coverage=False, lines=None)
|
||||
assert "uncovered" not in scanned
|
||||
assert "+ -> -" in scanned
|
||||
|
||||
@@ -113,6 +113,29 @@ def test_uncovered_sites_are_not_executed(tmp_path):
|
||||
assert result.forms[0].sites == 4
|
||||
|
||||
|
||||
def test_a_site_inside_a_covered_multi_line_statement_is_run(tmp_path):
|
||||
# LCOV marks only the line a statement starts on.
|
||||
path = tmp_path / "src" / "demo.py"
|
||||
path.parent.mkdir()
|
||||
path.write_text("def add(a, b):\n return (a\n + b)\n", encoding="utf-8")
|
||||
runner = FakeRunner()
|
||||
result = mutate_file(
|
||||
path,
|
||||
tmp_path,
|
||||
runner=runner,
|
||||
covered_lines={2},
|
||||
ignore_coverage=False,
|
||||
mutate_all=True,
|
||||
lines=None,
|
||||
test_command="fake",
|
||||
timeout_factor=10,
|
||||
mutation_warning=50,
|
||||
baselines={},
|
||||
)
|
||||
assert result.forms[0].uncovered == 0
|
||||
assert result.forms[0].killed == 1
|
||||
|
||||
|
||||
def test_a_failed_baseline_does_not_rewrite_metrics(tmp_path):
|
||||
path = tmp_path / "src" / "demo.py"
|
||||
path.parent.mkdir()
|
||||
|
||||
@@ -203,3 +203,34 @@ def test_a_deep_expression_is_walked(tmp_path):
|
||||
assert discover_raw(python, "python", "app.py")
|
||||
go = f"package p\nfunc place() int {{ return {expr} }}\n"
|
||||
assert discover_raw(go, "go", "app.go")
|
||||
|
||||
|
||||
def test_typescript_types_are_not_mutation_sites(tmp_path):
|
||||
source = """type Flag = { on: true };
|
||||
interface Box { open: false }
|
||||
export function check(n: number): { ok: true } | { ok: false; used?: true } {
|
||||
const seen: Promise<{ done: false }> | null = null;
|
||||
return { ok: n > 0 };
|
||||
}
|
||||
"""
|
||||
sites = _sites(tmp_path, "src/demo/check.ts", source)
|
||||
described = {(site.line, site.original, site.mutant) for site in sites}
|
||||
assert described == {(5, ">", ">="), (5, "0", "1")}
|
||||
|
||||
|
||||
def test_a_site_remembers_where_its_statement_starts(tmp_path):
|
||||
source = """export function save(db: Db, now: number) {
|
||||
db
|
||||
.prepare("x")
|
||||
.bind(now + 1)
|
||||
.run();
|
||||
return {
|
||||
ok: true,
|
||||
};
|
||||
}
|
||||
"""
|
||||
sites = _sites(tmp_path, "src/demo/save.ts", source)
|
||||
anchors = {(site.line, site.original, site.anchor_line) for site in sites}
|
||||
assert (4, "+", 2) in anchors
|
||||
assert (4, "1", 2) in anchors
|
||||
assert (7, "true", 6) in anchors
|
||||
|
||||
Reference in New Issue
Block a user