import pytest from services.registry import get_registered_tools, mcp_for_unity_tool import services.registry.tool_registry as tool_registry_module @pytest.fixture(autouse=True) def restore_tool_registry_state(): original_registry = list(tool_registry_module._tool_registry) try: yield finally: tool_registry_module._tool_registry[:] = original_registry def test_tool_registry_defaults_unity_target_to_tool_name(): @mcp_for_unity_tool() def _default_target_tool(): return None registered_tools = get_registered_tools() tool_info = next(item for item in registered_tools if item["name"] == "_default_target_tool") assert tool_info["unity_target"] == "_default_target_tool" def test_tool_registry_supports_server_only_and_alias_targets(): @mcp_for_unity_tool(unity_target=None) def _server_only_tool(): return None @mcp_for_unity_tool(unity_target="manage_script") def _manage_script_alias_tool(): return None registered_tools = get_registered_tools() server_only = next(item for item in registered_tools if item["name"] == "_server_only_tool") alias_tool = next(item for item in registered_tools if item["name"] == "_manage_script_alias_tool") assert server_only["unity_target"] is None assert alias_tool["unity_target"] == "manage_script" def test_tool_registry_does_not_leak_unity_target_into_tool_kwargs(): @mcp_for_unity_tool(unity_target="manage_script", annotations={"title": "x"}) def _non_leaking_target_tool(): return None registered_tools = get_registered_tools() tool_info = next(item for item in registered_tools if item["name"] == "_non_leaking_target_tool") assert tool_info["unity_target"] == "manage_script" assert "unity_target" not in tool_info["kwargs"] assert tool_info["kwargs"]["annotations"] == {"title": "x"} def test_tool_registry_rejects_invalid_unity_target_values(): with pytest.raises(ValueError, match="Invalid unity_target"): @mcp_for_unity_tool(unity_target="") def _invalid_empty_target_tool(): return None with pytest.raises(ValueError, match="Invalid unity_target"): @mcp_for_unity_tool(unity_target=123) # type: ignore[arg-type] def _invalid_non_string_target_tool(): return None