feat: extraction coverage summary in report

This commit is contained in:
2026-08-18 13:20:29 -05:00
parent 06e108142e
commit 23f6d7fe89
2 changed files with 129 additions and 11 deletions
+84
View File
@@ -0,0 +1,84 @@
"""Unit tests for the extraction_coverage block in the report summary.
Both the classic pipeline and the agent runner build their summary via
backend.pipeline.report.build_report, so unit tests on that function cover
every summary-producing path.
"""
from backend.pipeline.report import build_report
def _sheet(page, coverage=None, assertions=None):
sheet = {
"page_number": page,
"sheet_number": f"S{page:03d}",
"discipline": "S",
"assertions": assertions if assertions is not None else [
{"text": "NOTE ALPHA", "object_type": "note"},
{"text": "NOTE BETA", "object_type": "note"},
],
}
if coverage is not None:
sheet["coverage"] = coverage
return sheet
def _cov(total, covered):
return {
"total_lines": total,
"covered_lines": covered,
"ratio": covered / total if total else 0.0,
}
def test_extraction_coverage_omitted_without_coverage_data():
report = build_report(conflicts=[], sheets=[_sheet(1), _sheet(2)], clusters=[])
assert "extraction_coverage" not in report["summary"]
def test_extraction_coverage_healthy():
sheets = [_sheet(1, _cov(100, 95)), _sheet(2, _cov(80, 76))]
report = build_report(conflicts=[], sheets=sheets, clusters=[])
cov = report["summary"]["extraction_coverage"]
assert cov["pages_measured"] == 2
assert cov["pages_below_floor"] == []
assert cov["fallback_pages"] == []
assert cov["mean_ratio"] == round((0.95 + 0.95) / 2, 3)
def test_extraction_coverage_flags_below_floor():
sheets = [
_sheet(1, _cov(100, 95)),
_sheet(2, _cov(100, 40)), # ratio 0.4 < 0.6 floor
_sheet(3, _cov(100, 59)), # ratio 0.59 < 0.6 floor
]
report = build_report(conflicts=[], sheets=sheets, clusters=[])
cov = report["summary"]["extraction_coverage"]
assert cov["pages_measured"] == 3
assert cov["pages_below_floor"] == [2, 3]
assert cov["mean_ratio"] == round((0.95 + 0.4 + 0.59) / 3, 3)
def test_extraction_coverage_flags_fallback_pages():
fallback_assertions = [
{"text": "NOTE ALPHA", "object_type": "note"},
{"text": "NOTE BETA", "object_type": "note",
"grounding": "text_layer_fallback"},
]
sheets = [
_sheet(1, _cov(100, 90), assertions=fallback_assertions),
_sheet(2, _cov(100, 90)),
]
report = build_report(conflicts=[], sheets=sheets, clusters=[])
cov = report["summary"]["extraction_coverage"]
assert cov["fallback_pages"] == [1]
def test_extraction_coverage_mixed_sheets_only_counts_measured():
# Sheet 2 has no coverage dict (e.g. scanned page / older path).
sheets = [_sheet(1, _cov(100, 50)), _sheet(2)]
report = build_report(conflicts=[], sheets=sheets, clusters=[])
cov = report["summary"]["extraction_coverage"]
assert cov["pages_measured"] == 1
assert cov["pages_below_floor"] == [1]
assert cov["mean_ratio"] == 0.5