-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_context_tool.py
More file actions
113 lines (96 loc) · 3.51 KB
/
Copy pathtest_context_tool.py
File metadata and controls
113 lines (96 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
"""Test for B-scheme GetContextTool."""
import asyncio
import json
import sys
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock
sys.path.insert(0, str(Path(__file__).parent.parent))
from src.core.di_container import create_service_collection
from src.mcp.tools.context_tool import GetContextTool
async def test_collect_sections():
ROOT = Path(__file__).parent.parent
services = create_service_collection(ROOT)
# Mock readiness check
GetContextTool.require_ready_project = AsyncMock()
tool = GetContextTool(services)
# Mock the underlying tools
from src.mcp.tools.search_tools import (
GetSymbolInfoTool,
ImpactAnalysisTool,
SearchCodeTool,
)
symbol_tool = GetSymbolInfoTool(services)
impact_tool = MagicMock()
impact_tool.execute = AsyncMock(
return_value={
"status": "ok",
"symbol": "build_call_graph",
"depth": 3,
"direct_callers": 2,
"transitive_callers": 5,
"direct_callees": 3,
"transitive_callees": 1,
"affected_files": ["src/core/indexing/symbol_index.py"],
"risk_level": "low",
"risk_score": 12,
}
)
search_tool = MagicMock()
search_tool.execute = AsyncMock(return_value="search fallback result")
# Mock symbol_tool.execute
async def mock_symbol_execute(query, kwargs=None):
return (
"🔍 **build_call_graph** — 1 defs, 2 callers, 3 callees\n\n"
"📄 Definition: `src/core/indexing/symbol_index.py` line 480\n\n"
"⬆️ **Called from:**\n"
" • `SymbolIndex.get_impact_analysis`\n"
" • `SymbolIndex.get_callees`"
)
symbol_tool = GetSymbolInfoTool(services)
symbol_tool.execute = AsyncMock(
return_value=(
"🔍 **build_call_graph** — 1 defs, 2 callers, 3 callees\n\n"
"📄 Definition: `src/core/indexing/symbol_index.py` line 480\n\n"
"⬆️ **Called from:**\n"
" • `SymbolIndex.get_impact_analysis`\n"
" • `SymbolIndex.get_callees`"
)
)
impact_tool = MagicMock()
impact_tool.execute = AsyncMock(
return_value={
"status": "ok",
"symbol": "build_call_graph",
"depth": 3,
"direct_callers": 2,
"transitive_callers": 5,
"direct_callees": 3,
"transitive_callees": 1,
"affected_files": ["src/core/indexing/symbol_index.py"],
"risk_level": "low",
"risk_score": 12,
}
)
search_tool = MagicMock()
search_tool.execute = AsyncMock(return_value="search fallback result")
# Test _collect_sections
sections = await tool._collect_sections(
"build_call_graph",
["source", "symbols", "git"],
symbol_tool,
impact_tool,
search_tool,
)
print(f"Sections: {len(sections)}")
for s in sections:
print(f" {s['name']}: {s['tokens']} tokens")
if s["text"]:
print(f" Preview: {s['text'][:100]}")
assert len(sections) >= 3, f"Expected at least 3 sections, got {len(sections)}"
section_names = {s["name"] for s in sections}
assert "symbols" in section_names, "Missing symbols section"
assert "source" in section_names, "Missing source section"
assert "git" in section_names, "Missing git section"
print("\n✅ All tests passed!")
if __name__ == "__main__":
asyncio.run(test_collect_sections())