Spaces:
Runtime error
Runtime error
| """Tests for notes-coverage guard. | |
| These tests pin the deterministic behaviour of the coverage check that | |
| ``_generate_section_text`` and ``run_inspector_tool_loop`` use to decide | |
| whether to regenerate. The whole point of the guard is to be reliable | |
| without an LLM, so the assertions are exact thresholds, not loose bounds. | |
| """ | |
| from __future__ import annotations | |
| from app.generator.notes_coverage import ( | |
| coverage_regenerate_hint, | |
| coverage_report, | |
| extract_bullet_facts, | |
| ) | |
| def test_extract_bullet_facts_drops_stopword_only() -> None: | |
| facts = extract_bullet_facts(["the and of"]) | |
| assert facts == [] | |
| def test_extract_bullet_facts_keeps_factish_tokens() -> None: | |
| facts = extract_bullet_facts(["damp at rear elevation; postcode SW1A 1AA"]) | |
| assert len(facts) == 1 | |
| keys = facts[0].key_tokens | |
| assert "damp" in keys | |
| assert "rear" in keys | |
| assert "elevation" in keys | |
| assert "SW1A1AA" in keys | |
| def test_coverage_report_full_match() -> None: | |
| bullets = ["roof tiles slipped at south elevation"] | |
| text = "Roof tiles slipped at the south elevation; replacement recommended." | |
| rep = coverage_report(bullets, text) | |
| assert rep.coverage_ratio == 1.0 | |
| assert rep.bullets_poorly_covered == 0 | |
| assert not rep.needs_regenerate | |
| def test_coverage_report_detects_dropped_facts() -> None: | |
| bullets = [ | |
| "boiler 22 years old, no service record", | |
| "consumer unit lacks RCD protection on lighting circuits", | |
| "rising damp at rear hallway", | |
| ] | |
| text = "The property is generally well maintained." | |
| rep = coverage_report(bullets, text) | |
| assert rep.bullets_total == 3 | |
| assert rep.bullets_poorly_covered == 3 | |
| assert rep.coverage_ratio < 0.3 | |
| assert rep.needs_regenerate | |
| hint = coverage_regenerate_hint(rep) | |
| assert "COVERAGE VIOLATION" in hint | |
| assert "boiler" in hint or "rcd" in hint.lower() or "damp" in hint.lower() | |
| def test_coverage_report_stemming_does_not_misflag() -> None: | |
| """Bullet says 'cracks' but text says 'cracking' — should still cover.""" | |
| bullets = ["cracks to rear chimney stack"] | |
| text = "Cracking observed to the rear chimney stack." | |
| rep = coverage_report(bullets, text) | |
| assert rep.coverage_ratio >= 0.7 | |
| def test_coverage_report_empty_bullets_safe() -> None: | |
| rep = coverage_report([], "any text") | |
| assert rep.bullets_total == 0 | |
| assert rep.coverage_ratio == 1.0 | |
| assert not rep.needs_regenerate | |
| def test_coverage_regenerate_hint_lists_missing_tokens() -> None: | |
| bullets = ["smoke alarm missing in hallway", "lead paint on window frames"] | |
| text = "General property condition fair." | |
| rep = coverage_report(bullets, text) | |
| hint = coverage_regenerate_hint(rep) | |
| assert "smoke" in hint.lower() or "alarm" in hint.lower() | |
| assert "lead" in hint.lower() or "paint" in hint.lower() | |