diff --git a/tests/test_baseline_result.py b/tests/test_baseline_result.py index 3ea13bf0..a7ab5750 100644 --- a/tests/test_baseline_result.py +++ b/tests/test_baseline_result.py @@ -1,11 +1,11 @@ -"""Phase 1 invariant tests for result_migration_baseline_cleanup_20260620. +"""Phase 1 + Phase 2 invariant tests for result_migration_baseline_cleanup_20260620. -Asserts: -1. The 3 baseline files have the expected site counts (audit per-file totals) -2. Migration-target total = 88 (46 + 33 + 9) -3. PHASE1_AUDIT_BASELINE.json + 3 inventory docs exist and have correct counts +Phase 1: 4 tests assert the audit + inventory docs match expected counts. +Phase 2: 3 tests assert the BASELINE state is correct (88 migration-target sites + in 3 files; the migration is starting from this exact state). """ import json +import subprocess from collections import Counter from pathlib import Path @@ -23,8 +23,15 @@ EXPECTED = { "src\\ai_client.py": (17, 9, 0, 7, 0, 33), "src\\rag_engine.py": (5, 1, 0, 3, 0, 9), } +TARGETS = ("src\\mcp_client.py", "src\\ai_client.py", "src\\rag_engine.py") +def _load_audit(): + return json.loads(AUDIT_PATH.read_text(encoding="utf-8")) + + +# ============ Phase 1 tests (4) ============ + def test_phase1_audit_json_exists(): assert AUDIT_PATH.exists(), f"missing audit json at {AUDIT_PATH}" @@ -32,12 +39,11 @@ def test_phase1_audit_json_exists(): def test_phase1_inventory_docs_exist(): for p in [INV_MCP, INV_AI, INV_RAG]: assert p.exists(), f"missing inventory doc at {p}" - # Each inventory doc should have at least 1 KB of content assert p.stat().st_size > 500, f"inventory doc {p} too small" def test_phase1_total_migration_target_is_88(): - data = json.loads(AUDIT_PATH.read_text(encoding="utf-8")) + data = _load_audit() files = {f["filename"]: f for f in data["files"]} total = 0 for key in EXPECTED: @@ -49,7 +55,7 @@ def test_phase1_total_migration_target_is_88(): def test_phase1_per_file_site_counts(): """mcp=46, ai=33, rag=9 = (BC, SS, OPT, RETHROW, UNCLEAR, total)""" - data = json.loads(AUDIT_PATH.read_text(encoding="utf-8")) + data = _load_audit() files = {f["filename"]: f for f in data["files"]} for key, expected in EXPECTED.items(): findings = files[key]["findings"] @@ -64,4 +70,46 @@ def test_phase1_per_file_site_counts(): f"{key}: expected BC={expected[0]} SS={expected[1]} OPT={expected[2]} " f"RETHROW={expected[3]} UNCLEAR={expected[4]} MIG={expected[5]}, " f"got BC={bc} SS={ss} OPT={opt} RETHROW={rethrow} UNCLEAR={unclear} MIG={mig}" + ) + + +# ============ Phase 2 tests (3) ============ + +def test_phase2_baseline_audit_runs(): + """The audit --include-baseline --json command exits 0.""" + r = subprocess.run( + ["uv", "run", "python", "scripts/audit_exception_handling.py", + "--include-baseline", "--json"], + capture_output=True, text=True + ) + assert r.returncode == 0, f"audit failed: {r.stderr[:500]}" + data = json.loads(r.stdout) + assert "files" in data + assert len(data["files"]) >= 40, f"expected 40+ files, got {len(data['files'])}" + + +def test_phase2_all_3_targets_have_migration_sites(): + """Each of the 3 baseline files has at least 1 migration-target site.""" + data = _load_audit() + files = {f["filename"]: f for f in data["files"]} + for target in TARGETS: + assert target in files, f"missing target file: {target}" + mig = [f for f in files[target]["findings"] if f["category"] in MIG] + assert len(mig) > 0, f"{target} has 0 migration-target sites (expected >0)" + + +def test_phase2_per_file_baseline_counts_match_inventory(): + """The baseline per-file counts match the Phase 1 inventory docs.""" + data = _load_audit() + files = {f["filename"]: f for f in data["files"]} + BASELINE = { + "src\\mcp_client.py": 46, + "src\\ai_client.py": 33, + "src\\rag_engine.py": 9, + } + for target, expected in BASELINE.items(): + mig = [f for f in files[target]["findings"] if f["category"] in MIG] + assert len(mig) == expected, ( + f"{target}: baseline expected {expected}, got {len(mig)} " + f"(a previous phase may have introduced a violation)" ) \ No newline at end of file