-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy pathtest_examples.py
More file actions
108 lines (87 loc) · 3.99 KB
/
test_examples.py
File metadata and controls
108 lines (87 loc) · 3.99 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
"""Tests for example servers"""
# TODO(Marcelo): The `examples` directory needs to be importable as a package.
# pyright: reportMissingImports=false
# pyright: reportUnknownVariableType=false
# pyright: reportUnknownArgumentType=false
# pyright: reportUnknownMemberType=false
from pathlib import Path
import pytest
from inline_snapshot import snapshot
from pytest_examples import CodeExample, EvalExample, find_examples
from mcp import Client
from mcp.types import CallToolResult, TextContent, TextResourceContents
@pytest.mark.anyio
async def test_simple_echo():
"""Test the simple echo server"""
from examples.mcpserver.simple_echo import mcp
async with Client(mcp) as client:
result = await client.call_tool("echo", {"text": "hello"})
assert result == snapshot(
CallToolResult(content=[TextContent(text="hello")], structured_content={"result": "hello"})
)
@pytest.mark.anyio
async def test_complex_inputs():
"""Test the complex inputs server"""
from examples.mcpserver.complex_inputs import mcp
async with Client(mcp) as client:
tank = {"shrimp": [{"name": "bob"}, {"name": "alice"}]}
result = await client.call_tool("name_shrimp", {"tank": tank, "extra_names": ["charlie"]})
assert result == snapshot(
CallToolResult(
content=[
TextContent(text="bob"),
TextContent(text="alice"),
TextContent(text="charlie"),
],
structured_content={"result": ["bob", "alice", "charlie"]},
)
)
@pytest.mark.anyio
async def test_direct_call_tool_result_return():
"""Test the CallToolResult echo server"""
from examples.mcpserver.direct_call_tool_result_return import mcp
async with Client(mcp) as client:
result = await client.call_tool("echo", {"text": "hello"})
assert result == snapshot(
CallToolResult(
meta={"some": "metadata"}, # type: ignore[reportUnknownMemberType]
content=[TextContent(text="hello")],
structured_content={"text": "hello"},
)
)
@pytest.mark.anyio
async def test_desktop(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
"""Test the desktop server"""
# Build a real Desktop directory under tmp_path rather than patching
# Path.iterdir — a class-level patch breaks jsonschema_specifications'
# import-time schema discovery when this test happens to be the first
# tool call in an xdist worker.
desktop = tmp_path / "Desktop"
desktop.mkdir()
(desktop / "file1.txt").touch()
(desktop / "file2.txt").touch()
monkeypatch.setattr(Path, "home", lambda: tmp_path)
from examples.mcpserver.desktop import mcp
async with Client(mcp) as client:
# Test the sum function
result = await client.call_tool("sum", {"a": 1, "b": 2})
assert result == snapshot(CallToolResult(content=[TextContent(text="3")], structured_content={"result": 3}))
# Test the desktop resource
result = await client.read_resource("dir://desktop")
assert len(result.contents) == 1
content = result.contents[0]
assert isinstance(content, TextResourceContents)
assert isinstance(content.text, str)
assert "file1.txt" in content.text
assert "file2.txt" in content.text
# TODO(v2): Change back to README.md when v2 is released
@pytest.mark.parametrize("example", find_examples("README.v2.md"), ids=str)
def test_docs_examples(example: CodeExample, eval_example: EvalExample):
ruff_ignore: list[str] = ["F841", "I001", "F821"] # F821: undefined names (snippets lack imports)
# Use project's actual line length of 120
eval_example.set_config(ruff_ignore=ruff_ignore, target_version="py310", line_length=120)
# Use Ruff for both formatting and linting (skip Black)
if eval_example.update_examples: # pragma: no cover
eval_example.format_ruff(example)
else:
eval_example.lint_ruff(example)