File size: 3,304 Bytes
6c2642f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a137ca3
 
 
 
 
6c2642f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a137ca3
 
 
 
 
 
 
 
 
6c2642f
 
 
 
 
 
 
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
from __future__ import annotations

import ast
import json
import unittest
from pathlib import Path


class MCPMetadataTests(unittest.TestCase):
    def test_every_dashboard_tool_has_public_name_and_description(self) -> None:
        tree = ast.parse(Path("renderer_app.py").read_text(encoding="utf-8-sig"))
        functions = {
            node.name: node
            for node in tree.body
            if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))
        }
        formatter_module = ast.Module(body=[functions["_mcp_description"]], type_ignores=[])
        ast.fix_missing_locations(formatter_module)
        namespace = {"json": json, "Any": object}
        exec(compile(formatter_module, "renderer_app.py", "exec"), namespace)
        format_description = namespace["_mcp_description"]
        events = [
            node
            for node in ast.walk(tree)
            if isinstance(node, ast.Call)
            and isinstance(node.func, ast.Attribute)
            and node.func.attr == "click"
        ]

        self.assertEqual(len(events), 25)
        for event in events:
            keywords = {item.arg: item.value for item in event.keywords if item.arg}
            callback = keywords.get("fn")
            self.assertIsInstance(callback, ast.Name, "MCP callbacks must be named functions")
            callback_name = callback.id
            self.assertFalse(callback_name.startswith("_"), f"Private MCP callback: {callback_name}")
            self.assertIn(callback_name, functions)
            self.assertTrue(ast.get_docstring(functions[callback_name]), f"Missing docstring: {callback_name}")

            api_name = keywords.get("api_name")
            description = keywords.get("api_description")
            self.assertIsInstance(api_name, ast.Constant, f"Missing api_name: {callback_name}")
            self.assertTrue(api_name.value, f"Empty api_name: {callback_name}")
            self.assertIsInstance(description, ast.Call, f"Missing structured api_description: {callback_name}")
            self.assertIsInstance(description.func, ast.Name)
            self.assertEqual(description.func.id, "_mcp_description")
            self.assertEqual(len(description.args), 2)

            summary = ast.literal_eval(description.args[0])
            example = ast.literal_eval(description.args[1])
            self.assertTrue(summary, f"Empty description: {callback_name}")
            self.assertIsInstance(example, dict, f"Example must be an object: {callback_name}")

            rendered = format_description(summary, example)
            marker = "\n\nExample JSON:\n```json\n"
            self.assertIn(marker, rendered, f"Missing JSON code block: {callback_name}")
            self.assertTrue(rendered.endswith("\n```"), f"Unclosed JSON code block: {callback_name}")
            json_payload = rendered.split(marker, 1)[1][:-4]
            self.assertEqual(json.loads(json_payload), example)
            if example:
                self.assertIn('\n  "', json_payload, f"Example is not indented: {callback_name}")

            parameters = [argument.arg for argument in functions[callback_name].args.args]
            self.assertEqual(set(example), set(parameters), f"Example keys do not match: {callback_name}")


if __name__ == "__main__":
    unittest.main()