"""Tests for normalized retained test and quality evidence.""" from __future__ import annotations import pytest from scripts import write_test_evidence def _coverage(line: float = 80.0, branch: float = 75.0): return { "totals": { "percent_statements_covered": line, "percent_branches_covered": branch, }, "files": { "obliteratus/example.py": { "summary": { "covered_lines": 8, "num_statements": 10, "covered_branches": 3, "num_branches": 4, }, }, }, } def _risk_map(): return {"modules": [{"path": "obliteratus/example.py"}]} def test_coverage_snapshot_records_repository_and_risk_module_metrics(): snapshot = write_test_evidence.coverage_snapshot(_coverage(), _risk_map()) assert snapshot == { "line_percent": 80.0, "branch_percent": 75.0, "risk_modules": { "obliteratus/example.py": { "line_percent": 80.0, "branch_percent": 75.0, }, }, } def test_junit_snapshot_records_failures_skips_and_slowest_tests(tmp_path): junit = tmp_path / "junit.xml" junit.write_text( '' '' '' '' '' '', ) snapshot = write_test_evidence.junit_snapshot(junit) assert snapshot["total"] == 3 assert snapshot["passed"] == 1 assert snapshot["failures"] == ["tests.test_a::test_fail"] assert snapshot["skipped"] == ["tests.test_b::test_skip"] assert snapshot["duration_seconds"] == 0.6 assert snapshot["slowest"][0] == { "nodeid": "tests.test_a::test_fail", "seconds": 0.3, } def test_evidence_records_base_deltas_repeat_and_mutation(): evidence = write_test_evidence.build_evidence( head_sha="b" * 40, base_sha="a" * 40, python_version="3.12", coverage=_coverage(80, 75), base_coverage=_coverage(79, 74), risk_map=_risk_map(), repeat={"schema_version": 1, "status": "passed", "passes": []}, mutation={"killed": 8, "total": 10}, generated_at="2026-08-14T00:00:00+00:00", ) assert evidence["coverage"]["delta"] == { "line_percentage_points": 1.0, "branch_percentage_points": 1.0, } assert evidence["repeat"]["status"] == "passed" assert evidence["mutation"] == { "killed": 8, "total": 10, "score_percent": 80.0, } def test_evidence_rejects_missing_inputs_and_malformed_measurements(): with pytest.raises(ValueError, match="at least one"): write_test_evidence.build_evidence( head_sha="local", base_sha="", python_version="3.12", ) malformed = _coverage() malformed["files"]["obliteratus/example.py"]["summary"]["covered_lines"] = True with pytest.raises(ValueError, match="invalid covered_lines"): write_test_evidence.coverage_snapshot(malformed, _risk_map()) malformed = _coverage(line=float("nan")) with pytest.raises(ValueError, match="numeric line"): write_test_evidence.coverage_snapshot(malformed, _risk_map()) def test_base_snapshot_allows_risk_module_added_by_head(): snapshot = write_test_evidence.coverage_snapshot( {"totals": _coverage()["totals"], "files": {}}, _risk_map(), allow_missing_risk_modules=True, ) assert snapshot["risk_modules"]["obliteratus/example.py"] == { "line_percent": None, "branch_percent": None, } def test_mutation_snapshot_rejects_impossible_counts(): with pytest.raises(ValueError, match="valid killed and total"): write_test_evidence.mutation_snapshot({"killed": 2, "total": 1})