#!/usr/bin/env python3 """Tests for regen-readme.py. Dependency-free: run with `python code-reviews/test_regen_readme.py`. Exits 0 if all tests pass, 1 otherwise. """ from __future__ import annotations import importlib.util import tempfile import traceback from pathlib import Path HERE = Path(__file__).resolve().parent # regen-readme.py is not an importable module name (hyphen), so load it by path. _spec = importlib.util.spec_from_file_location("regen_readme", HERE / "regen-readme.py") regen = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(regen) FIXTURE = """# Code Review — Demo | Field | Value | |---|---| | Module | `src/Demo` | | Reviewer | Tester | | Review date | 2026-05-18 | | Commit reviewed | `abc1234` | | Status | Reviewed | | Open findings | 1 | ## Findings ### Demo-001 | Field | Value | |---|---| | Severity | High | | Category | Security | | Location | `src/Demo/File.cs:10` | | Status | Open | **Description:** A first problem that matters. **Recommendation:** Fix it. **Resolution:** _(open)_ ### Demo-002 | Field | Value | |---|---| | Severity | Low | | Category | Documentation & comments | | Location | `src/Demo/File.cs:20` | | Status | Resolved | **Description:** A second, minor problem. **Recommendation:** Tidy it. **Resolution:** Fixed in def5678 on 2026-05-18. """ def _parse_fixture() -> dict: """Write FIXTURE to a temp Demo/findings.md and parse it.""" with tempfile.TemporaryDirectory() as tmp: path = Path(tmp) / "Demo" / "findings.md" path.parent.mkdir() path.write_text(FIXTURE, encoding="utf-8") return regen.parse_module(path) def test_first_table_skips_separator_and_field_header(): table = regen.first_table("| Field | Value |\n|---|---|\n| Severity | High |\n") assert table == {"Severity": "High"}, table def test_parse_module_header(): m = _parse_fixture() assert m["module"] == "Demo", m["module"] assert m["header"]["Reviewer"] == "Tester" assert m["header"]["Status"] == "Reviewed" assert m["header"]["Open findings"] == "1" def test_parse_module_findings(): m = _parse_fixture() assert len(m["findings"]) == 2, len(m["findings"]) first = m["findings"][0] assert first["id"] == "Demo-001" assert first["severity"] == "High" assert first["category"] == "Security" assert first["location"] == "`src/Demo/File.cs:10`" assert first["status"] == "Open" assert first["description"] == "A first problem that matters." assert m["findings"][1]["status"] == "Resolved" def test_build_readme_splits_pending_and_closed(): readme = regen.build_readme([_parse_fixture()]) assert "## Pending findings" in readme assert "## Closed findings" in readme pending, closed = readme.split("## Closed findings", 1) assert "Demo-001" in pending # Open -> pending assert "Demo-001" not in closed assert "Demo-002" in closed # Resolved -> closed assert "_No pending findings._" not in pending def test_build_readme_handles_no_modules(): readme = regen.build_readme([]) assert "no modules reviewed yet" in readme assert "_No pending findings._" in readme assert "_No closed findings._" in readme def test_find_inconsistencies_clean_fixture(): assert regen.find_inconsistencies([_parse_fixture()]) == [] def test_find_inconsistencies_detects_wrong_open_count(): m = _parse_fixture() m["header"]["Open findings"] = "7" issues = regen.find_inconsistencies([m]) assert len(issues) == 1 and "Open findings" in issues[0], issues def test_find_inconsistencies_detects_unknown_status(): m = _parse_fixture() m["findings"][0]["status"] = "Bogus" issues = regen.find_inconsistencies([m]) # Wrong status also shifts the open count, so expect the status issue present. assert any("unrecognised Status" in i for i in issues), issues def test_summarize_truncates_long_text(): long = "x" * 500 out = regen.summarize(long) assert len(out) <= 240 and out.endswith("…"), len(out) assert regen.summarize("short") == "short" def main() -> int: tests = sorted( (name, fn) for name, fn in globals().items() if name.startswith("test_") and callable(fn) ) failed = 0 for name, fn in tests: try: fn() print(f"PASS {name}") except Exception: # noqa: BLE001 - test runner reports all failures failed += 1 print(f"FAIL {name}") traceback.print_exc() print(f"\n{len(tests) - failed}/{len(tests)} passed.") return 1 if failed else 0 if __name__ == "__main__": raise SystemExit(main())