Added Application HolidayViewer
This commit is contained in:
248
tests/test_mcp_server.py
Normal file
248
tests/test_mcp_server.py
Normal file
@@ -0,0 +1,248 @@
|
||||
import pytest
|
||||
import inspect
|
||||
from typing import Dict, Any, List, Optional, Callable
|
||||
|
||||
from ai.mcp_server import DummyMCPServer
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mcp_server(session):
|
||||
return DummyMCPServer(session, None)
|
||||
|
||||
|
||||
def test_register_tool_basic(mcp_server):
|
||||
"""Test basic tool registration"""
|
||||
|
||||
# Define a simple test function
|
||||
def test_func(param1: str, param2: int):
|
||||
return f"Test {param1} {param2}"
|
||||
|
||||
# Register the tool
|
||||
result = mcp_server.register_tool("test_tool", test_func)
|
||||
|
||||
# Verify the tool was registered
|
||||
assert "test_tool" in mcp_server.available_tools
|
||||
assert mcp_server.available_tools["test_tool"]["name"] == "test_tool"
|
||||
assert mcp_server.available_tools["test_tool"]["handler"] == test_func
|
||||
|
||||
# Verify method chaining works
|
||||
assert result is mcp_server
|
||||
|
||||
|
||||
def test_register_tool_with_description(mcp_server):
|
||||
"""Test tool registration with a custom description"""
|
||||
|
||||
def test_func():
|
||||
return "test"
|
||||
|
||||
mcp_server.register_tool("test_tool", test_func, description="Custom description")
|
||||
|
||||
assert mcp_server.available_tools["test_tool"]["description"] == "Custom description"
|
||||
|
||||
|
||||
def test_register_tool_without_description(mcp_server):
|
||||
"""Test tool registration without a description"""
|
||||
|
||||
def test_func():
|
||||
return "test"
|
||||
|
||||
mcp_server.register_tool("test_tool", test_func)
|
||||
|
||||
assert mcp_server.available_tools["test_tool"]["description"] == "Tool test_tool"
|
||||
|
||||
|
||||
def test_register_tool_parameter_types(mcp_server):
|
||||
"""Test parameter type inference"""
|
||||
|
||||
def test_func(str_param: str, int_param: int, float_param: float, bool_param: bool, untyped_param):
|
||||
return "test"
|
||||
|
||||
mcp_server.register_tool("test_tool", test_func)
|
||||
|
||||
params = mcp_server.available_tools["test_tool"]["parameters"]
|
||||
|
||||
assert params["str_param"]["type"] == "string"
|
||||
assert params["int_param"]["type"] == "integer"
|
||||
assert params["float_param"]["type"] == "number"
|
||||
assert params["bool_param"]["type"] == "boolean"
|
||||
assert params["untyped_param"]["type"] == "string" # Default type for untyped parameters
|
||||
|
||||
|
||||
def test_register_tool_parameter_descriptions(mcp_server):
|
||||
"""Test parameter descriptions"""
|
||||
|
||||
def test_func(param1, param2):
|
||||
return "test"
|
||||
|
||||
mcp_server.register_tool("test_tool", test_func)
|
||||
|
||||
params = mcp_server.available_tools["test_tool"]["parameters"]
|
||||
|
||||
assert params["param1"]["description"] == "Parameter param1"
|
||||
assert params["param2"]["description"] == "Parameter param2"
|
||||
|
||||
|
||||
def test_register_tool_with_sphinx_docstring(mcp_server):
|
||||
"""Test parameter descriptions from Sphinx-style docstrings"""
|
||||
|
||||
def test_func(name: str, age: int):
|
||||
"""Test function with Sphinx docstring
|
||||
|
||||
:param name: The person's name
|
||||
:param age: The person's age in years
|
||||
:return: A greeting message
|
||||
"""
|
||||
return f"Hello {name}, you are {age} years old!"
|
||||
|
||||
mcp_server.register_tool("sphinx_doc_tool", test_func)
|
||||
|
||||
params = mcp_server.available_tools["sphinx_doc_tool"]["parameters"]
|
||||
|
||||
assert params["name"]["description"] == "The person's name"
|
||||
assert params["age"]["description"] == "The person's age in years"
|
||||
|
||||
|
||||
def test_register_tool_with_google_docstring(mcp_server):
|
||||
"""Test parameter descriptions from Google-style docstrings"""
|
||||
|
||||
def test_func(name: str, age: int, height: float):
|
||||
"""Test function with Google-style docstring
|
||||
|
||||
Args:
|
||||
name: The person's name
|
||||
age: The person's age in years
|
||||
height: The person's height in meters
|
||||
|
||||
Returns:
|
||||
A greeting message
|
||||
"""
|
||||
return f"Hello {name}, you are {age} years old and {height}m tall!"
|
||||
|
||||
mcp_server.register_tool("google_doc_tool", test_func)
|
||||
|
||||
params = mcp_server.available_tools["google_doc_tool"]["parameters"]
|
||||
|
||||
assert params["name"]["description"] == "The person's name"
|
||||
assert params["age"]["description"] == "The person's age in years"
|
||||
assert params["height"]["description"] == "The person's height in meters"
|
||||
|
||||
|
||||
def test_register_tool_with_parameters_keyword(mcp_server):
|
||||
"""Test parameter descriptions with 'Parameters:' keyword instead of 'Args:'"""
|
||||
|
||||
def test_func(x: int, y: int):
|
||||
"""Test function with Parameters keyword
|
||||
|
||||
Parameters:
|
||||
x: The x coordinate
|
||||
y: The y coordinate
|
||||
|
||||
Returns:
|
||||
The sum of coordinates
|
||||
"""
|
||||
return x + y
|
||||
|
||||
mcp_server.register_tool("parameters_doc_tool", test_func)
|
||||
|
||||
params = mcp_server.available_tools["parameters_doc_tool"]["parameters"]
|
||||
|
||||
assert params["x"]["description"] == "The x coordinate"
|
||||
assert params["y"]["description"] == "The y coordinate"
|
||||
|
||||
|
||||
def test_register_tool_with_mixed_docstrings(mcp_server):
|
||||
"""Test parameter descriptions with mixed docstring styles"""
|
||||
|
||||
def test_func(a: int, b: str, c: float):
|
||||
"""Test function with mixed docstring styles
|
||||
|
||||
:param a: Parameter a from Sphinx style
|
||||
|
||||
Args:
|
||||
b: Parameter b from Google style
|
||||
c: Parameter c from Google style
|
||||
"""
|
||||
return f"{a} {b} {c}"
|
||||
|
||||
mcp_server.register_tool("mixed_doc_tool", test_func)
|
||||
|
||||
params = mcp_server.available_tools["mixed_doc_tool"]["parameters"]
|
||||
|
||||
assert params["a"]["description"] == "Parameter a from Sphinx style"
|
||||
assert params["b"]["description"] == "Parameter b from Google style"
|
||||
assert params["c"]["description"] == "Parameter c from Google style"
|
||||
|
||||
|
||||
def test_register_tool_with_missing_docstrings(mcp_server):
|
||||
"""Test parameter descriptions when some parameters are missing from docstring"""
|
||||
|
||||
def test_func(a: int, b: str, c: float):
|
||||
"""Test function with incomplete docstring
|
||||
|
||||
Args:
|
||||
a: Parameter a description
|
||||
"""
|
||||
return f"{a} {b} {c}"
|
||||
|
||||
mcp_server.register_tool("incomplete_doc_tool", test_func)
|
||||
|
||||
params = mcp_server.available_tools["incomplete_doc_tool"]["parameters"]
|
||||
|
||||
assert params["a"]["description"] == "Parameter a description"
|
||||
assert params["b"]["description"] == "Parameter b" # Default description
|
||||
assert params["c"]["description"] == "Parameter c" # Default description
|
||||
|
||||
|
||||
async def test_tool_can_be_called(mcp_server):
|
||||
"""Test that a registered tool can be called through call_tool method"""
|
||||
|
||||
# Define a simple test function
|
||||
def test_func(value: int):
|
||||
return value * 2
|
||||
|
||||
# Register the tool
|
||||
mcp_server.register_tool("multiply", test_func)
|
||||
|
||||
# Call the tool
|
||||
result = await mcp_server.call_tool("multiply", {"value": 5})
|
||||
|
||||
# Verify the result
|
||||
assert result["success"] is True
|
||||
assert result["result"] == 10
|
||||
assert result["tool_name"] == "multiply"
|
||||
|
||||
|
||||
async def test_async_tool_can_be_called(mcp_server):
|
||||
"""Test that a registered async tool can be called through call_tool method"""
|
||||
|
||||
# Define an async test function
|
||||
async def async_test_func(value: int):
|
||||
return value * 3
|
||||
|
||||
# Register the async tool
|
||||
mcp_server.register_tool("async_multiply", async_test_func)
|
||||
|
||||
# Call the async tool
|
||||
result = await mcp_server.call_tool("async_multiply", {"value": 5})
|
||||
|
||||
# Verify the result
|
||||
assert result["success"] is True
|
||||
assert result["result"] == 15
|
||||
assert result["tool_name"] == "async_multiply"
|
||||
|
||||
|
||||
def test_multiple_tools_registration(mcp_server):
|
||||
"""Test registering multiple tools"""
|
||||
|
||||
def tool1(): return "tool1"
|
||||
|
||||
def tool2(): return "tool2"
|
||||
|
||||
nb_internal_tools = len(mcp_server.available_tools)
|
||||
mcp_server.register_tool("tool1", tool1)
|
||||
mcp_server.register_tool("tool2", tool2)
|
||||
|
||||
# Check both tools were registered
|
||||
assert "tool1" in mcp_server.available_tools
|
||||
assert "tool2" in mcp_server.available_tools
|
||||
assert len(mcp_server.available_tools) == nb_internal_tools + 2
|
||||
Reference in New Issue
Block a user