"""Extended tests for timmy.tools — covers stats, type aliases, and aider tool.""" from unittest.mock import MagicMock, patch from timmy.tools import ( AgentTools, PersonaTools, ToolStats, create_aider_tool, ) class TestToolStats: """Test ToolStats dataclass.""" def test_defaults(self): ts = ToolStats(tool_name="calc") assert ts.call_count == 0 assert ts.last_used is None assert ts.errors == 0 class TestAgentTools: """Test AgentTools dataclass and backward compat alias.""" def test_persona_tools_alias(self): assert PersonaTools is AgentTools class TestAiderTool: """Test AiderTool created by create_aider_tool.""" def test_create_aider_tool(self, tmp_path): tool = create_aider_tool(tmp_path) assert hasattr(tool, "run_aider") assert tool.base_dir == tmp_path @patch("subprocess.run") def test_aider_success(self, mock_run, tmp_path): tool = create_aider_tool(tmp_path) mock_run.return_value = MagicMock(returncode=0, stdout="Changes applied") result = tool.run_aider("add fibonacci function") assert "Changes applied" in result @patch("subprocess.run") def test_aider_error(self, mock_run, tmp_path): tool = create_aider_tool(tmp_path) mock_run.return_value = MagicMock(returncode=1, stderr="something broke") result = tool.run_aider("bad prompt") assert "error" in result.lower() @patch("subprocess.run", side_effect=FileNotFoundError) def test_aider_not_installed(self, mock_run, tmp_path): tool = create_aider_tool(tmp_path) result = tool.run_aider("test") assert "not installed" in result.lower() @patch("subprocess.run") def test_aider_timeout(self, mock_run, tmp_path): import subprocess mock_run.side_effect = subprocess.TimeoutExpired(cmd="aider", timeout=120) tool = create_aider_tool(tmp_path) result = tool.run_aider("slow task") assert "timed out" in result.lower()