Some checks failed
Test / pytest (pull_request) Failing after 16s
Add automated script that identifies changed source files, checks for corresponding test changes, and reports coverage gaps. Acceptance — #124: - Identifies changed source files (git diff --name-only HEAD) - Checks for corresponding test changes (source→test file mapping) - Reports: code without tests (lists uncovered sources) - Output: coverage gap (structured text/JSON) Closes #124 Task: 6.6 — Test Coverage Checker
117 lines
3.2 KiB
Python
117 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Tests for coverage_checker — Issue #124 acceptance validation."""
|
|
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
|
|
|
|
from coverage_checker import (
|
|
is_source_file,
|
|
is_test_file,
|
|
source_to_test_path,
|
|
analyze_coverage,
|
|
)
|
|
|
|
|
|
class TestSourceFileDetection:
|
|
def test_script_in_scripts_dir(self):
|
|
assert is_source_file("scripts/freshness.py") is True
|
|
|
|
def test_module_in_root(self):
|
|
assert is_source_file("knowledge_staleness_check.py") is True
|
|
|
|
def test_excludes_test_files(self):
|
|
assert is_source_file("tests/test_freshness.py") is False
|
|
|
|
def test_excludes_non_py(self):
|
|
assert is_source_file("README.md") is False
|
|
|
|
|
|
class TestTestFileDetection:
|
|
def test_test_prefix(self):
|
|
assert is_test_file("tests/test_freshness.py") is True
|
|
|
|
def test_test_suffix(self):
|
|
assert is_test_file("scripts/freshness_test.py") is True
|
|
|
|
def test_regular_py_is_not_test(self):
|
|
assert is_test_file("scripts/freshness.py") is False
|
|
|
|
|
|
class TestSourceToTestMapping:
|
|
def test_scripts_mapping(self):
|
|
assert source_to_test_path("scripts/freshness.py") == "tests/test_freshness.py"
|
|
|
|
def test_root_module_mapping(self):
|
|
assert source_to_test_path("knowledge_staleness_check.py") == "tests/test_knowledge_staleness_check.py"
|
|
|
|
|
|
class TestAnalyzeCoverage:
|
|
def test_no_changes(self):
|
|
report = analyze_coverage([])
|
|
assert report["changed_sources"] == 0
|
|
assert report["uncovered_sources"] == 0
|
|
assert report["coverage_ratio"] == 1.0
|
|
|
|
def test_all_covered(self):
|
|
changed = [
|
|
"scripts/freshness.py",
|
|
"tests/test_freshness.py",
|
|
"scripts/dedup.py",
|
|
"tests/test_dedup.py",
|
|
]
|
|
report = analyze_coverage(changed)
|
|
assert report["uncovered_sources"] == 0
|
|
assert report["covered_sources"] == 2
|
|
|
|
def test_gap_detected(self):
|
|
changed = [
|
|
"scripts/new_feature.py",
|
|
"README.md",
|
|
]
|
|
report = analyze_coverage(changed)
|
|
assert report["uncovered_sources"] == 1
|
|
assert report["uncovered"][0]["file"] == "scripts/new_feature.py"
|
|
assert report["uncovered"][0]["suggested_test"] == "tests/test_new_feature.py"
|
|
|
|
def test_mixed_coverage(self):
|
|
changed = [
|
|
"scripts/covered.py",
|
|
"tests/test_covered.py",
|
|
"scripts/uncovered.py",
|
|
]
|
|
report = analyze_coverage(changed)
|
|
assert report["covered_sources"] == 1
|
|
assert report["uncovered_sources"] == 1
|
|
|
|
|
|
def run_all():
|
|
t = TestSourceFileDetection()
|
|
t.test_script_in_scripts_dir()
|
|
t.test_module_in_root()
|
|
t.test_excludes_test_files()
|
|
t.test_excludes_non_py()
|
|
|
|
t2 = TestTestFileDetection()
|
|
t2.test_test_prefix()
|
|
t2.test_test_suffix()
|
|
t2.test_regular_py_is_not_test()
|
|
|
|
t3 = TestSourceToTestMapping()
|
|
t3.test_scripts_mapping()
|
|
t3.test_root_module_mapping()
|
|
|
|
t4 = TestAnalyzeCoverage()
|
|
t4.test_no_changes()
|
|
t4.test_all_covered()
|
|
t4.test_gap_detected()
|
|
t4.test_mixed_coverage()
|
|
|
|
print("All 11 tests passed!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_all()
|