- Stringify Object.signature() instead of str()-ing the bound method, which produced "<bound method Class.signature of ...>" reprs - Skip alias members that cannot resolve (stdlib/third-party imports) while preserving resolvable package re-exports; return None for empty signatures (classes without __init__ args) - Add MCP renderer regression tests for signature cleanliness, alias filtering, and package re-export preservation
74 lines
2.4 KiB
Python
74 lines
2.4 KiB
Python
import json
|
|
from pathlib import Path
|
|
|
|
from docforge import MCPRenderer
|
|
from docforge.loaders import GriffeLoader, discover_module_paths
|
|
|
|
|
|
def _load_docforge_bundle(tmp_path: Path) -> Path:
|
|
project_root = Path(__file__).resolve().parents[3]
|
|
loader = GriffeLoader()
|
|
paths = discover_module_paths("docforge", project_root=project_root)
|
|
project = loader.load_project(paths)
|
|
|
|
out_dir = tmp_path / "mcp"
|
|
MCPRenderer().generate_sources(project, out_dir)
|
|
return out_dir
|
|
|
|
|
|
def test_mcp_signatures_are_clean(tmp_path: Path) -> None:
|
|
out_dir = _load_docforge_bundle(tmp_path)
|
|
|
|
object_payload = json.loads(
|
|
(out_dir / "modules" / "docforge.models.object.json").read_text(
|
|
encoding="utf-8"
|
|
)
|
|
)
|
|
|
|
cls = object_payload["content"]["objects"]["DocObject"]
|
|
assert isinstance(cls["signature"], str)
|
|
assert "bound method" not in cls["signature"]
|
|
assert cls["signature"].startswith("DocObject(")
|
|
|
|
renderer_payload = json.loads(
|
|
(out_dir / "modules" / "docforge.renderers.mcp_renderer.json").read_text(
|
|
encoding="utf-8"
|
|
)
|
|
)
|
|
|
|
method = renderer_payload["content"]["objects"]["MCPRenderer"]["members"][
|
|
"generate_sources"
|
|
]
|
|
assert isinstance(method["signature"], str)
|
|
assert "bound method" not in method["signature"]
|
|
assert method["signature"].startswith("generate_sources(")
|
|
|
|
|
|
def test_mcp_skips_unresolvable_import_aliases(tmp_path: Path) -> None:
|
|
out_dir = _load_docforge_bundle(tmp_path)
|
|
|
|
renderer_payload = json.loads(
|
|
(out_dir / "modules" / "docforge.renderers.mcp_renderer.json").read_text(
|
|
encoding="utf-8"
|
|
)
|
|
)
|
|
|
|
object_names = set(renderer_payload["content"]["objects"])
|
|
assert "json" not in object_names
|
|
assert "Path" not in object_names
|
|
|
|
|
|
def test_mcp_keeps_resolvable_package_reexports(tmp_path: Path) -> None:
|
|
out_dir = _load_docforge_bundle(tmp_path)
|
|
|
|
root_payload = json.loads(
|
|
(out_dir / "modules" / "docforge.json").read_text(encoding="utf-8")
|
|
)
|
|
|
|
discover = root_payload["content"]["objects"]["discover_module_paths"]
|
|
assert discover["name"] == "discover_module_paths"
|
|
assert isinstance(discover["signature"], str)
|
|
assert "bound method" not in discover["signature"]
|
|
assert discover["signature"].startswith("discover_module_paths(")
|
|
assert discover["docstring"] is not None
|