84 lines
2.8 KiB
Python
84 lines
2.8 KiB
Python
|
|
"""Tests for Atlasbot's per-file coverage contract script."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import json
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
|
||
|
|
SCRIPT = Path(__file__).resolve().parents[1] / "scripts" / "check_coverage.py"
|
||
|
|
|
||
|
|
|
||
|
|
def _run_check(tmp_path: Path, coverage_payload: dict) -> subprocess.CompletedProcess[str]:
|
||
|
|
"""Run the coverage script against a temporary Atlasbot source tree."""
|
||
|
|
|
||
|
|
coverage_path = tmp_path / "coverage.json"
|
||
|
|
coverage_path.write_text(json.dumps(coverage_payload), encoding="utf-8")
|
||
|
|
return subprocess.run(
|
||
|
|
[sys.executable, str(SCRIPT), str(coverage_path), "--root", "atlasbot", "--threshold", "95"],
|
||
|
|
cwd=tmp_path,
|
||
|
|
text=True,
|
||
|
|
capture_output=True,
|
||
|
|
check=False,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_missing_source_file_fails_coverage_contract(tmp_path: Path) -> None:
|
||
|
|
"""Every non-init production source file must appear in the coverage report."""
|
||
|
|
|
||
|
|
source_root = tmp_path / "atlasbot"
|
||
|
|
source_root.mkdir()
|
||
|
|
(source_root / "__init__.py").write_text("", encoding="utf-8")
|
||
|
|
(source_root / "covered.py").write_text("value = 1\n", encoding="utf-8")
|
||
|
|
(source_root / "missing.py").write_text("value = 2\n", encoding="utf-8")
|
||
|
|
|
||
|
|
result = _run_check(
|
||
|
|
tmp_path,
|
||
|
|
{"files": {"atlasbot/covered.py": {"summary": {"percent_covered": 100.0}}}},
|
||
|
|
)
|
||
|
|
|
||
|
|
assert result.returncode == 1
|
||
|
|
assert "atlasbot/missing.py: missing from coverage report" in result.stdout
|
||
|
|
assert "atlasbot/__init__.py" not in result.stdout
|
||
|
|
|
||
|
|
|
||
|
|
def test_low_or_malformed_file_coverage_fails_contract(tmp_path: Path) -> None:
|
||
|
|
"""Covered files still fail if their per-file percentage is bad or missing."""
|
||
|
|
|
||
|
|
source_root = tmp_path / "atlasbot"
|
||
|
|
source_root.mkdir()
|
||
|
|
(source_root / "low.py").write_text("value = 1\n", encoding="utf-8")
|
||
|
|
(source_root / "malformed.py").write_text("value = 2\n", encoding="utf-8")
|
||
|
|
|
||
|
|
result = _run_check(
|
||
|
|
tmp_path,
|
||
|
|
{
|
||
|
|
"files": {
|
||
|
|
"atlasbot/low.py": {"summary": {"percent_covered": 94.9}},
|
||
|
|
"atlasbot/malformed.py": {"summary": {}},
|
||
|
|
}
|
||
|
|
},
|
||
|
|
)
|
||
|
|
|
||
|
|
assert result.returncode == 1
|
||
|
|
assert "atlasbot/low.py: 94.90% < 95.00%" in result.stdout
|
||
|
|
assert "atlasbot/malformed.py: coverage percent missing" in result.stdout
|
||
|
|
|
||
|
|
|
||
|
|
def test_complete_per_file_coverage_passes_contract(tmp_path: Path) -> None:
|
||
|
|
"""The contract passes when every production file is present above threshold."""
|
||
|
|
|
||
|
|
source_root = tmp_path / "atlasbot"
|
||
|
|
source_root.mkdir()
|
||
|
|
(source_root / "covered.py").write_text("value = 1\n", encoding="utf-8")
|
||
|
|
|
||
|
|
result = _run_check(
|
||
|
|
tmp_path,
|
||
|
|
{"files": {"atlasbot/covered.py": {"summary": {"percent_covered": 95.0}}}},
|
||
|
|
)
|
||
|
|
|
||
|
|
assert result.returncode == 0
|
||
|
|
assert result.stdout == ""
|