""" Tests for advanced_search_system/tools/base_tool.py Tests cover: - TYPE_MAP constant - BaseTool class initialization and methods - Parameter validation """ from unittest.mock import patch class TestTypeMap: """Tests for TYPE_MAP constant.""" def test_type_map_exists(self): """Test that TYPE_MAP is defined.""" from local_deep_research.advanced_search_system.tools.base_tool import ( TYPE_MAP, ) assert TYPE_MAP is not None assert isinstance(TYPE_MAP, dict) def test_contains_common_types(self): """Test that common types are mapped.""" from local_deep_research.advanced_search_system.tools.base_tool import ( TYPE_MAP, ) assert TYPE_MAP["str"] is str assert TYPE_MAP["int"] is int assert TYPE_MAP["float"] is float assert TYPE_MAP["bool"] is bool assert TYPE_MAP["list"] is list assert TYPE_MAP["dict"] is dict def test_contains_collection_types(self): """Test that collection types are mapped.""" from local_deep_research.advanced_search_system.tools.base_tool import ( TYPE_MAP, ) assert TYPE_MAP["tuple"] is tuple assert TYPE_MAP["set"] is set class ConcreteTool: """Concrete implementation of BaseTool for testing.""" def __init__(self, name="test_tool", description="A test tool"): # We can't subclass ABC directly in tests, so we'll access methods self.name = name self.description = description self.parameters = {} def execute(self, **kwargs): return f"Executed with {kwargs}" class TestBaseTool: """Tests for BaseTool class.""" def test_init_sets_name_and_description(self): """Test that __init__ sets name and description.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) # Create a minimal concrete subclass class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="my_tool", description="Does something") assert tool.name == "my_tool" assert tool.description == "Does something" assert tool.parameters == {} def test_get_schema_returns_correct_format(self): """Test that get_schema returns proper format.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="my_tool", description="Does something") tool.parameters = { "query": {"type": "str", "required": True}, } schema = tool.get_schema() assert schema["name"] == "my_tool" assert schema["description"] == "Does something" assert "query" in schema["parameters"] def test_validate_parameters_returns_true_for_valid(self): """Test validation returns True for valid parameters.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="test", description="test") tool.parameters = { "query": {"type": "str", "required": True}, } result = tool.validate_parameters(query="hello") assert result is True def test_validate_parameters_returns_false_for_missing_required(self): """Test validation returns False for missing required parameter.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="test", description="test") tool.parameters = { "query": {"type": "str", "required": True}, } result = tool.validate_parameters() # Missing 'query' assert result is False def test_validate_parameters_allows_optional_missing(self): """Test validation allows missing optional parameters.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="test", description="test") tool.parameters = { "query": {"type": "str", "required": False}, } result = tool.validate_parameters() # Missing optional param assert result is True def test_validate_parameters_returns_false_for_wrong_type(self): """Test validation returns False for wrong parameter type.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="test", description="test") tool.parameters = { "count": {"type": "int", "required": True}, } result = tool.validate_parameters(count="not an int") assert result is False def test_validate_parameters_checks_enum_values(self): """Test validation checks enum values.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="test", description="test") tool.parameters = { "mode": {"type": "str", "enum": ["fast", "slow"]}, } # Valid enum value assert tool.validate_parameters(mode="fast") is True # Invalid enum value assert tool.validate_parameters(mode="medium") is False def test_validate_parameters_ignores_unknown_types(self): """Test validation ignores unknown type strings.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="test", description="test") tool.parameters = { "custom": {"type": "unknown_type"}, # Unknown type } # Should not fail validation for unknown types result = tool.validate_parameters(custom="anything") assert result is True def test_log_execution_logs_info(self): """Test that _log_execution logs properly.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="test_tool", description="test") with patch( "local_deep_research.advanced_search_system.tools.base_tool.logger" ) as mock_logger: tool._log_execution(param1="value1", param2="value2") mock_logger.info.assert_called() # Should mention tool name and parameter count call_args = mock_logger.info.call_args[0][0] assert "test_tool" in call_args assert "2" in call_args def test_log_result_logs_info(self): """Test that _log_result logs properly.""" from local_deep_research.advanced_search_system.tools.base_tool import ( BaseTool, ) class TestTool(BaseTool): def execute(self, **kwargs): return "result" tool = TestTool(name="test_tool", description="test") with patch( "local_deep_research.advanced_search_system.tools.base_tool.logger" ) as mock_logger: tool._log_result("my_result") mock_logger.info.assert_called() call_args = mock_logger.info.call_args[0][0] assert "test_tool" in call_args assert "my_result" in call_args