From 19c534e54b996b8b886328f44c94a59e832b2871 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 19 Jun 2026 22:56:00 -0400 Subject: [PATCH] TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase 4: test(gui_2): add 2 Phase 4 invariant tests + relax Phase 3 invariant for decreasing count The Phase 3 invariant test (test_phase_3_invariant_batch_a_count_dropped) asserted exactly 17 INTERNAL_BROAD_CATCH sites, the post-Phase 3 baseline. After Phase 4 migrates 3 more sites, the count drops to 14. The test now asserts <= 17 (the upper bound; the Phase 3 boundary). Adds test_phase_4_invariant_batch_b_count_dropped: locks in <= 14 sites (post-Phase 4 baseline; down from 17). Adds test_phase_4_invariant_all_3_migration_sites_have_tests: ensures each of the 3 Batch B sites (L3398, L3718, L3740) has both _success and _failure tests. All 30 tests pass. --- tests/test_gui_2_result.py | 61 +++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/tests/test_gui_2_result.py b/tests/test_gui_2_result.py index 5bfafec0..5eb80f89 100644 --- a/tests/test_gui_2_result.py +++ b/tests/test_gui_2_result.py @@ -505,10 +505,13 @@ def test_phase_3_invariant_batch_a_count_dropped(): data = json.loads(result.stdout) gui2 = [f for f in data.get("files", []) if "gui_2" in f.get("filename", "")][0] broad_catches = [f for f in gui2.get("findings", []) if f.get("category") == "INTERNAL_BROAD_CATCH"] - assert len(broad_catches) == 17, ( - f"Phase 3 invariant: expected 17 INTERNAL_BROAD_CATCH sites in src/gui_2.py " - f"(down from 25); found {len(broad_catches)}. The 8 Batch A sites must be " - f"migrated to Result[T] helpers. Lines: {[f.get('line') for f in broad_catches]}" + # Post-Phase 3 baseline was 17. As subsequent phases (Phase 4+) migrate more + # sites, the count decreases. This test asserts the upper bound (the Phase 3 + # boundary); per-phase invariant tests track the decreasing count. + assert len(broad_catches) <= 17, ( + f"Phase 3 invariant: expected <= 17 INTERNAL_BROAD_CATCH sites in src/gui_2.py " + f"(post-Phase 3 baseline); found {len(broad_catches)}. The count grew, which " + f"means a regression or new site was introduced. Lines: {[f.get('line') for f in broad_catches]}" ) @@ -737,3 +740,53 @@ def test_phase_4_l3740_render_ast_inspector_file_content_result_failure(): err = result.errors[0] assert err.source == "gui_2._render_ast_inspector_file_content_result" assert result.data is None + + +def test_phase_4_invariant_batch_b_count_dropped(): + """ + Phase 4 invariant: the audit's INTERNAL_BROAD_CATCH count for src/gui_2.py + has dropped from 17 (post-Phase 3) to 14 (a drop of 3 sites). + + The 3 migrated sites are: L3398 (render_persona_editor_window Save), + L3718 (render_ast_inspector_modal outline fetch), + L3740 (render_ast_inspector_modal file content read). + """ + result = subprocess.run( + ["uv", "run", "python", "scripts/audit_exception_handling.py", "--src", "src", "--json"], + capture_output=True, + text=True, + ) + assert result.returncode == 0, ( + f"audit_exception_handling.py exited {result.returncode}; stderr:\n" + f"{result.stderr[:2000]}" + ) + data = json.loads(result.stdout) + gui2 = [f for f in data.get("files", []) if "gui_2" in f.get("filename", "")][0] + broad_catches = [f for f in gui2.get("findings", []) if f.get("category") == "INTERNAL_BROAD_CATCH"] + assert len(broad_catches) <= 14, ( + f"Phase 4 invariant: expected <= 14 INTERNAL_BROAD_CATCH sites in src/gui_2.py " + f"(post-Phase 4 baseline, down from 17); found {len(broad_catches)}. " + f"The 3 Batch B sites (L3398, L3718, L3740) must be migrated to Result[T] helpers. " + f"Lines: {[f.get('line') for f in broad_catches]}" + ) + + +def test_phase_4_invariant_all_3_migration_sites_have_tests(): + """ + Phase 4 invariant: each of the 3 Batch B sites has both success and + failure tests in this test file. + """ + import re + text = Path(__file__).read_text(encoding="utf-8") + expected_lines = [3398, 3718, 3740] + for line in expected_lines: + success_pattern = f"test_phase_4_l{line}_.*_success" + failure_pattern = f"test_phase_4_l{line}_.*_failure" + assert re.search(success_pattern, text), ( + f"Phase 4 invariant: missing success test for L{line}. " + f"Expected a test matching '{success_pattern}'." + ) + assert re.search(failure_pattern, text), ( + f"Phase 4 invariant: missing failure test for L{line}. " + f"Expected a test matching '{failure_pattern}'." + )