mirror of
https://github.com/unclebob/mutator.git
synced 2026-11-06 18:23:50 +00:00
Add a multi-language mutation tester that writes .metrics/mutate for uml-viewer.
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from mutator.cli import parse_args, run
|
||||
from mutator.runner import CommandResult
|
||||
|
||||
|
||||
def test_lines_option_parses_positive_numbers():
|
||||
options = parse_args(["--lines", "2, 4", "src/demo.py"])
|
||||
assert options.lines == {2, 4}
|
||||
|
||||
|
||||
def test_changed_selects_a_dirty_source_file(tmp_path, monkeypatch, capsys):
|
||||
path = tmp_path / "src" / "demo.py"
|
||||
path.parent.mkdir()
|
||||
path.write_text("def place(x):\n return x > 0\n", encoding="utf-8")
|
||||
subprocess.run(["git", "init"], cwd=tmp_path, check=True, capture_output=True)
|
||||
subprocess.run(["git", "add", "src/demo.py"], cwd=tmp_path, check=True, capture_output=True)
|
||||
monkeypatch.chdir(tmp_path)
|
||||
code = run(["--scan", "--no-coverage", "--changed", "--root", str(tmp_path)])
|
||||
captured = capsys.readouterr()
|
||||
assert code == 0
|
||||
assert "demo.py:2" in captured.out
|
||||
|
||||
|
||||
def test_a_directory_argument_skips_a_named_test_file(tmp_path, capsys):
|
||||
src = tmp_path / "pkg" / "app.py"
|
||||
src.parent.mkdir()
|
||||
src.write_text("def place(x):\n return x > 0\n", encoding="utf-8")
|
||||
test = tmp_path / "pkg" / "test_app.py"
|
||||
test.write_text("def test_place():\n assert True\n", encoding="utf-8")
|
||||
code = run(
|
||||
["--scan", "--no-coverage", "--root", str(tmp_path), str(tmp_path / "pkg"), str(test)]
|
||||
)
|
||||
captured = capsys.readouterr()
|
||||
assert code == 0
|
||||
assert "Skipping test file" in captured.err
|
||||
assert "app.py:2" in captured.out
|
||||
|
||||
|
||||
def test_help_and_conflicting_flags():
|
||||
help_options = parse_args(["--help"])
|
||||
assert help_options.exit_code == 0
|
||||
assert "uml-viewer" in help_options.message
|
||||
conflict = parse_args(["--mutate-all", "--since-last-run", "src/demo.py"])
|
||||
assert conflict.exit_code == 1
|
||||
assert run(["--help"]) == 0
|
||||
|
||||
|
||||
def test_scan_lists_sites_without_writing_metrics(tmp_path, monkeypatch):
|
||||
path = tmp_path / "src" / "demo.py"
|
||||
path.parent.mkdir()
|
||||
path.write_text("def place(x):\n return x > 0\n", encoding="utf-8")
|
||||
monkeypatch.chdir(tmp_path)
|
||||
code = run(["--scan", "--no-coverage", "--root", str(tmp_path), "src/demo.py"])
|
||||
assert code == 0
|
||||
assert not (tmp_path / ".metrics").exists()
|
||||
|
||||
|
||||
def test_real_python_mutants_update_the_snapshot(tmp_path, capsys):
|
||||
path = tmp_path / "src" / "demo.py"
|
||||
path.parent.mkdir()
|
||||
path.write_text(
|
||||
"def add(a, b):\n"
|
||||
" if a > 0:\n"
|
||||
" return a + b\n"
|
||||
" return 0\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
command = (
|
||||
f"{sys.executable} -c \"import sys; sys.path.insert(0, 'src'); "
|
||||
"from demo import add; raise SystemExit(0 if add(2, 3) == 5 else 1)\""
|
||||
)
|
||||
code = run(
|
||||
[
|
||||
"--no-coverage",
|
||||
"--mutate-all",
|
||||
"--root",
|
||||
str(tmp_path),
|
||||
"--test-command",
|
||||
command,
|
||||
"src/demo.py",
|
||||
]
|
||||
)
|
||||
captured = capsys.readouterr()
|
||||
assert code == 3
|
||||
assert "SURVIVED" in captured.out
|
||||
assert "KILLED" in captured.out
|
||||
snapshot = tmp_path / ".metrics" / "mutate" / "demo.edn"
|
||||
assert snapshot.is_file()
|
||||
text = snapshot.read_text(encoding="utf-8")
|
||||
assert ":namespace \"demo\"" in text
|
||||
assert ":id \"defn/add\"" in text
|
||||
assert path.read_text(encoding="utf-8").startswith("def add")
|
||||
Reference in New Issue
Block a user