Private
Public Access
refactor(mcp_client): obliterate legacy _resolve_and_check wrapper; migrate 5 callers to _resolve_and_check_result (Phase 3)
Phase 3 (1 of 9 cruft sites obliterated):
The legacy wrapper _resolve_and_check(raw_path) returned tuple[Path|None, str],
dropping the structured ErrorInfo from _resolve_and_check_result. Callers in
dispatch_tool_call (py_remove_def, py_add_def, py_move_def, py_region_wrap) used
the pattern 'p, err = _resolve_and_check(path); if err: return err' which is
exactly the false drain the user wants obliterated.
Migration:
- DELETED: _resolve_and_check wrapper (lines 175-188 in src/mcp_client.py)
- UPDATED: 5 callers in dispatch_tool_call now call _resolve_and_check_result
directly with .ok check + NilPath check + structured error routing
- UPDATED: 4 test files that monkey-patched _resolve_and_check to mock the
Result helper instead:
- test_mcp_ts_integration.py (1 mock)
- test_ts_c_tools.py (2 mocks)
- test_ts_cpp_tools.py (8 mocks)
- test_cruft_removal.py (NEW; 4 tests including the wrapper-obliterated
invariant + the audit-script-finds-zero invariant + 2 dispatch tests)
Test result: 51/51 pass (31 baseline + 16 heuristic + 4 cruft).
Audit gate: src/mcp_client.py --strict exits 0 (no new violations introduced).
Baseline audit: --include-baseline --strict exits 1 only due to 4 pre-existing
non-baseline INTERNAL_RETHROW sites in outline_tool.py / warmup.py /
vendor_capabilities.py (out of scope per spec).
The wrapper IS DELETED. No pass-through. No backward compat. The dead code dies.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""Wrapper-obliteration tests for result_migration_cruft_removal_20260620.
|
||||
|
||||
Phase 3 (mcp_client._resolve_and_check): the legacy wrapper is DELETED;
|
||||
callers in dispatch_tool_call use _resolve_and_check_result(...).ok directly.
|
||||
The test mocks _resolve_and_check_result (the proper Result helper).
|
||||
"""
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from src.mcp_client import dispatch
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_resolve_result():
|
||||
"""Mock the proper Result helper to always succeed."""
|
||||
from src import mcp_client
|
||||
original = mcp_client._resolve_and_check_result
|
||||
mcp_client._resolve_and_check_result = lambda path: __import__("src").mcp_client.Result(
|
||||
data=Path(path),
|
||||
errors=[],
|
||||
)
|
||||
yield
|
||||
mcp_client._resolve_and_check_result = original
|
||||
|
||||
|
||||
def test_resolve_and_check_wrapper_obliterated():
|
||||
"""Phase 3 invariant: the legacy _resolve_and_check wrapper is DELETED."""
|
||||
from src import mcp_client
|
||||
assert not hasattr(mcp_client, "_resolve_and_check"), (
|
||||
"_resolve_and_check legacy wrapper must be OBLITERATED (deleted). "
|
||||
"Callers must use _resolve_and_check_result(...).ok directly."
|
||||
)
|
||||
|
||||
|
||||
def test_dispatch_py_remove_def_uses_result_helper(mock_resolve_result, tmp_path):
|
||||
"""dispatch_tool_call for py_remove_def uses _resolve_and_check_result(...).ok."""
|
||||
from src import mcp_client
|
||||
|
||||
c_file = tmp_path / "test.py"
|
||||
c_file.write_text("def foo(): pass\n")
|
||||
|
||||
with patch("src.mcp_client.py_struct_tools") as mock_struct:
|
||||
mock_struct.py_remove_def.return_value = "removed"
|
||||
# dispatch routes through _resolve_and_check_result now
|
||||
result = dispatch("py_remove_def", {"path": str(c_file), "name": "foo"})
|
||||
assert result == "removed", f"expected 'removed', got {result!r}"
|
||||
|
||||
|
||||
def test_dispatch_py_move_def_uses_result_helper(mock_resolve_result, tmp_path):
|
||||
"""dispatch_tool_call for py_move_def (multi-path) uses _resolve_and_check_result."""
|
||||
from src import mcp_client
|
||||
|
||||
src_file = tmp_path / "src.py"
|
||||
src_file.write_text("def foo(): pass\n")
|
||||
dest_file = tmp_path / "dest.py"
|
||||
dest_file.write_text("# dest\n")
|
||||
|
||||
with patch("src.mcp_client.py_struct_tools") as mock_struct:
|
||||
mock_struct.py_move_def.return_value = "moved"
|
||||
result = dispatch(
|
||||
"py_move_def",
|
||||
{
|
||||
"src_path": str(src_file),
|
||||
"dest_path": str(dest_file),
|
||||
"name": "foo",
|
||||
"dest_name": "App",
|
||||
"anchor_type": "before",
|
||||
},
|
||||
)
|
||||
assert result == "moved", f"expected 'moved', got {result!r}"
|
||||
|
||||
|
||||
def test_audit_script_finds_zero_mcp_client_wrappers():
|
||||
"""Phase 3 invariant: scripts/audit_legacy_wrappers.py reports 0 wrappers in src/mcp_client.py."""
|
||||
r = subprocess.run(
|
||||
["uv", "run", "python", "scripts/audit_legacy_wrappers.py"],
|
||||
capture_output=True, text=True,
|
||||
)
|
||||
assert "src\\mcp_client.py" not in r.stdout, (
|
||||
f"expected 0 wrappers in src/mcp_client.py, but found:\n{r.stdout}"
|
||||
)
|
||||
Reference in New Issue
Block a user