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.
This commit is contained in:
ed
2026-06-19 22:56:00 -04:00
parent a213677cf0
commit 19c534e54b
+57 -4
View File
@@ -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}'."
)