test: reorganize test structure and add missing unit tests
Reorganize flat tests/ directory to mirror source code structure (tools/, gateway/, hermes_cli/, integration/). Add 11 new test files covering previously untested modules: registry, patch_parser, fuzzy_match, todo_tool, approval, file_tools, gateway session/config/ delivery, and hermes_cli config/models. Total: 147 unit tests passing, 9 integration tests gated behind pytest marker.
This commit is contained in:
parent
3c5bf5b9d8
commit
8fc28c34ce
24 changed files with 1066 additions and 16 deletions
121
tests/tools/test_registry.py
Normal file
121
tests/tools/test_registry.py
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
"""Tests for the central tool registry."""
|
||||
|
||||
import json
|
||||
|
||||
from tools.registry import ToolRegistry
|
||||
|
||||
|
||||
def _dummy_handler(args, **kwargs):
|
||||
return json.dumps({"ok": True})
|
||||
|
||||
|
||||
def _make_schema(name="test_tool"):
|
||||
return {"name": name, "description": f"A {name}", "parameters": {"type": "object", "properties": {}}}
|
||||
|
||||
|
||||
class TestRegisterAndDispatch:
|
||||
def test_register_and_dispatch(self):
|
||||
reg = ToolRegistry()
|
||||
reg.register(
|
||||
name="alpha",
|
||||
toolset="core",
|
||||
schema=_make_schema("alpha"),
|
||||
handler=_dummy_handler,
|
||||
)
|
||||
result = json.loads(reg.dispatch("alpha", {}))
|
||||
assert result == {"ok": True}
|
||||
|
||||
def test_dispatch_passes_args(self):
|
||||
reg = ToolRegistry()
|
||||
|
||||
def echo_handler(args, **kw):
|
||||
return json.dumps(args)
|
||||
|
||||
reg.register(name="echo", toolset="core", schema=_make_schema("echo"), handler=echo_handler)
|
||||
result = json.loads(reg.dispatch("echo", {"msg": "hi"}))
|
||||
assert result == {"msg": "hi"}
|
||||
|
||||
|
||||
class TestGetDefinitions:
|
||||
def test_returns_openai_format(self):
|
||||
reg = ToolRegistry()
|
||||
reg.register(name="t1", toolset="s1", schema=_make_schema("t1"), handler=_dummy_handler)
|
||||
reg.register(name="t2", toolset="s1", schema=_make_schema("t2"), handler=_dummy_handler)
|
||||
|
||||
defs = reg.get_definitions({"t1", "t2"})
|
||||
assert len(defs) == 2
|
||||
assert all(d["type"] == "function" for d in defs)
|
||||
names = {d["function"]["name"] for d in defs}
|
||||
assert names == {"t1", "t2"}
|
||||
|
||||
def test_skips_unavailable_tools(self):
|
||||
reg = ToolRegistry()
|
||||
reg.register(
|
||||
name="available",
|
||||
toolset="s",
|
||||
schema=_make_schema("available"),
|
||||
handler=_dummy_handler,
|
||||
check_fn=lambda: True,
|
||||
)
|
||||
reg.register(
|
||||
name="unavailable",
|
||||
toolset="s",
|
||||
schema=_make_schema("unavailable"),
|
||||
handler=_dummy_handler,
|
||||
check_fn=lambda: False,
|
||||
)
|
||||
defs = reg.get_definitions({"available", "unavailable"})
|
||||
assert len(defs) == 1
|
||||
assert defs[0]["function"]["name"] == "available"
|
||||
|
||||
|
||||
class TestUnknownToolDispatch:
|
||||
def test_returns_error_json(self):
|
||||
reg = ToolRegistry()
|
||||
result = json.loads(reg.dispatch("nonexistent", {}))
|
||||
assert "error" in result
|
||||
assert "Unknown tool" in result["error"]
|
||||
|
||||
|
||||
class TestToolsetAvailability:
|
||||
def test_no_check_fn_is_available(self):
|
||||
reg = ToolRegistry()
|
||||
reg.register(name="t", toolset="free", schema=_make_schema(), handler=_dummy_handler)
|
||||
assert reg.is_toolset_available("free") is True
|
||||
|
||||
def test_check_fn_controls_availability(self):
|
||||
reg = ToolRegistry()
|
||||
reg.register(
|
||||
name="t",
|
||||
toolset="locked",
|
||||
schema=_make_schema(),
|
||||
handler=_dummy_handler,
|
||||
check_fn=lambda: False,
|
||||
)
|
||||
assert reg.is_toolset_available("locked") is False
|
||||
|
||||
def test_check_toolset_requirements(self):
|
||||
reg = ToolRegistry()
|
||||
reg.register(name="a", toolset="ok", schema=_make_schema(), handler=_dummy_handler, check_fn=lambda: True)
|
||||
reg.register(name="b", toolset="nope", schema=_make_schema(), handler=_dummy_handler, check_fn=lambda: False)
|
||||
|
||||
reqs = reg.check_toolset_requirements()
|
||||
assert reqs["ok"] is True
|
||||
assert reqs["nope"] is False
|
||||
|
||||
def test_get_all_tool_names(self):
|
||||
reg = ToolRegistry()
|
||||
reg.register(name="z_tool", toolset="s", schema=_make_schema(), handler=_dummy_handler)
|
||||
reg.register(name="a_tool", toolset="s", schema=_make_schema(), handler=_dummy_handler)
|
||||
assert reg.get_all_tool_names() == ["a_tool", "z_tool"]
|
||||
|
||||
def test_handler_exception_returns_error(self):
|
||||
reg = ToolRegistry()
|
||||
|
||||
def bad_handler(args, **kw):
|
||||
raise RuntimeError("boom")
|
||||
|
||||
reg.register(name="bad", toolset="s", schema=_make_schema(), handler=bad_handler)
|
||||
result = json.loads(reg.dispatch("bad", {}))
|
||||
assert "error" in result
|
||||
assert "RuntimeError" in result["error"]
|
||||
Loading…
Add table
Add a link
Reference in a new issue