Files
zk-data-agent/tests/test_tool_pool.py
T
copilot-swe-agent[bot] b4269ecd88 Add comprehensive tests for ToolPool and assemble_tool_pool
Tests cover:
- assemble_tool_pool returns ToolPool with correct types
- Default mode produces non-empty tools
- simple_mode and include_mcp flags stored correctly
- simple_mode reduces tool set to BashTool/FileReadTool/FileEditTool
- include_mcp=False excludes MCP tools
- Permission context filters blocked tools
- as_markdown includes header, flags, and tool count
- as_markdown shows at most 15 tools
- Empty tools tuple renders correctly
- Tool lines contain name and source_hint
- Frozen dataclass prevents mutation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: abdoelsayed2016 <27821589+abdoelsayed2016@users.noreply.github.com>
2026-04-05 15:56:57 +00:00

107 lines
4.2 KiB
Python

from __future__ import annotations
import unittest
from src.models import PortingModule
from src.permissions import ToolPermissionContext
from src.tool_pool import ToolPool, assemble_tool_pool
class TestAssembleToolPool(unittest.TestCase):
def test_returns_tool_pool_with_tools(self) -> None:
pool = assemble_tool_pool()
self.assertIsInstance(pool, ToolPool)
self.assertIsInstance(pool.tools, tuple)
self.assertTrue(all(isinstance(t, PortingModule) for t in pool.tools))
def test_default_mode_includes_tools(self) -> None:
pool = assemble_tool_pool()
self.assertGreater(len(pool.tools), 0)
def test_simple_mode_flag_stored(self) -> None:
pool_default = assemble_tool_pool()
pool_simple = assemble_tool_pool(simple_mode=True)
self.assertFalse(pool_default.simple_mode)
self.assertTrue(pool_simple.simple_mode)
def test_include_mcp_flag_stored(self) -> None:
pool_default = assemble_tool_pool()
pool_no_mcp = assemble_tool_pool(include_mcp=False)
self.assertTrue(pool_default.include_mcp)
self.assertFalse(pool_no_mcp.include_mcp)
def test_simple_mode_reduces_tools(self) -> None:
pool_full = assemble_tool_pool(simple_mode=False)
pool_simple = assemble_tool_pool(simple_mode=True)
self.assertGreater(len(pool_full.tools), len(pool_simple.tools))
simple_names = {t.name for t in pool_simple.tools}
self.assertTrue(simple_names.issubset({'BashTool', 'FileReadTool', 'FileEditTool'}))
def test_include_mcp_false_excludes_mcp_tools(self) -> None:
pool = assemble_tool_pool(include_mcp=False)
for tool in pool.tools:
self.assertNotIn('mcp', tool.name.lower())
self.assertNotIn('mcp', tool.source_hint.lower())
def test_permission_context_filters_blocked_tools(self) -> None:
ctx = ToolPermissionContext.from_iterables(deny_names=['BashTool'])
pool = assemble_tool_pool(permission_context=ctx)
tool_names = {t.name for t in pool.tools}
self.assertNotIn('BashTool', tool_names)
pool_unfiltered = assemble_tool_pool()
unfiltered_names = {t.name for t in pool_unfiltered.tools}
self.assertIn('BashTool', unfiltered_names)
class TestToolPoolAsMarkdown(unittest.TestCase):
def test_includes_header_and_tool_count(self) -> None:
pool = assemble_tool_pool()
md = pool.as_markdown()
self.assertIn('# Tool Pool', md)
self.assertIn(f'Tool count: {len(pool.tools)}', md)
def test_includes_mode_flags(self) -> None:
pool = assemble_tool_pool(simple_mode=True, include_mcp=False)
md = pool.as_markdown()
self.assertIn('Simple mode: True', md)
self.assertIn('Include MCP: False', md)
def test_shows_at_most_15_tools(self) -> None:
pool = assemble_tool_pool()
self.assertGreater(len(pool.tools), 15, 'Need >15 tools for this test')
md = pool.as_markdown()
tool_lines = [line for line in md.splitlines() if line.startswith('- ')]
self.assertEqual(len(tool_lines), 15)
def test_empty_tools_renders_correctly(self) -> None:
pool = ToolPool(tools=(), simple_mode=False, include_mcp=True)
md = pool.as_markdown()
self.assertIn('# Tool Pool', md)
self.assertIn('Tool count: 0', md)
self.assertIn('Simple mode: False', md)
self.assertIn('Include MCP: True', md)
tool_lines = [line for line in md.splitlines() if line.startswith('- ')]
self.assertEqual(len(tool_lines), 0)
def test_tool_lines_contain_name_and_source_hint(self) -> None:
tool = PortingModule(
name='TestTool',
responsibility='testing',
source_hint='test/path.ts',
)
pool = ToolPool(tools=(tool,), simple_mode=False, include_mcp=False)
md = pool.as_markdown()
self.assertIn('- TestTool — test/path.ts', md)
class TestToolPoolFrozen(unittest.TestCase):
def test_cannot_mutate_fields(self) -> None:
pool = ToolPool(tools=(), simple_mode=False, include_mcp=True)
with self.assertRaises(AttributeError):
pool.simple_mode = True # type: ignore[misc]
if __name__ == '__main__':
unittest.main()