mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-01 01:51:44 +00:00
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
99
tests/tools/test_file_tools.py
Normal file
99
tests/tools/test_file_tools.py
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
"""Tests for the file tools module (schema and handler wiring).
|
||||
|
||||
These tests verify the tool schemas and handler wiring without
|
||||
requiring a running terminal environment. The actual file operations
|
||||
(ShellFileOperations) depend on a terminal backend, so we mock
|
||||
_get_file_ops to test the handler logic in isolation.
|
||||
"""
|
||||
|
||||
import json
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from tools.file_tools import (
|
||||
FILE_TOOLS,
|
||||
READ_FILE_SCHEMA,
|
||||
WRITE_FILE_SCHEMA,
|
||||
PATCH_SCHEMA,
|
||||
SEARCH_FILES_SCHEMA,
|
||||
)
|
||||
|
||||
|
||||
class TestSchemas:
|
||||
def test_read_file_schema(self):
|
||||
assert READ_FILE_SCHEMA["name"] == "read_file"
|
||||
props = READ_FILE_SCHEMA["parameters"]["properties"]
|
||||
assert "path" in props
|
||||
assert "offset" in props
|
||||
assert "limit" in props
|
||||
|
||||
def test_write_file_schema(self):
|
||||
assert WRITE_FILE_SCHEMA["name"] == "write_file"
|
||||
assert "path" in WRITE_FILE_SCHEMA["parameters"]["properties"]
|
||||
assert "content" in WRITE_FILE_SCHEMA["parameters"]["properties"]
|
||||
|
||||
def test_patch_schema(self):
|
||||
assert PATCH_SCHEMA["name"] == "patch"
|
||||
props = PATCH_SCHEMA["parameters"]["properties"]
|
||||
assert "mode" in props
|
||||
assert "old_string" in props
|
||||
assert "new_string" in props
|
||||
|
||||
def test_search_files_schema(self):
|
||||
assert SEARCH_FILES_SCHEMA["name"] == "search_files"
|
||||
props = SEARCH_FILES_SCHEMA["parameters"]["properties"]
|
||||
assert "pattern" in props
|
||||
assert "target" in props
|
||||
|
||||
|
||||
class TestFileToolsList:
|
||||
def test_file_tools_has_expected_entries(self):
|
||||
names = {t["name"] for t in FILE_TOOLS}
|
||||
assert names == {"read_file", "write_file", "patch", "search_files"}
|
||||
|
||||
|
||||
class TestReadFileHandler:
|
||||
@patch("tools.file_tools._get_file_ops")
|
||||
def test_read_file_returns_json(self, mock_get):
|
||||
mock_ops = MagicMock()
|
||||
result_obj = MagicMock()
|
||||
result_obj.to_dict.return_value = {"content": "hello", "total_lines": 1}
|
||||
mock_ops.read_file.return_value = result_obj
|
||||
mock_get.return_value = mock_ops
|
||||
|
||||
from tools.file_tools import read_file_tool
|
||||
|
||||
result = json.loads(read_file_tool("/tmp/test.txt"))
|
||||
assert result["content"] == "hello"
|
||||
mock_ops.read_file.assert_called_once_with("/tmp/test.txt", 1, 500)
|
||||
|
||||
|
||||
class TestWriteFileHandler:
|
||||
@patch("tools.file_tools._get_file_ops")
|
||||
def test_write_file_returns_json(self, mock_get):
|
||||
mock_ops = MagicMock()
|
||||
result_obj = MagicMock()
|
||||
result_obj.to_dict.return_value = {"status": "ok", "path": "/tmp/test.txt"}
|
||||
mock_ops.write_file.return_value = result_obj
|
||||
mock_get.return_value = mock_ops
|
||||
|
||||
from tools.file_tools import write_file_tool
|
||||
|
||||
result = json.loads(write_file_tool("/tmp/test.txt", "content"))
|
||||
assert result["status"] == "ok"
|
||||
mock_ops.write_file.assert_called_once_with("/tmp/test.txt", "content")
|
||||
|
||||
|
||||
class TestPatchHandler:
|
||||
@patch("tools.file_tools._get_file_ops")
|
||||
def test_replace_mode_missing_path_errors(self, mock_get):
|
||||
from tools.file_tools import patch_tool
|
||||
|
||||
result = json.loads(patch_tool(mode="replace", path=None, old_string="a", new_string="b"))
|
||||
assert "error" in result
|
||||
|
||||
@patch("tools.file_tools._get_file_ops")
|
||||
def test_unknown_mode_errors(self, mock_get):
|
||||
from tools.file_tools import patch_tool
|
||||
|
||||
result = json.loads(patch_tool(mode="unknown"))
|
||||
assert "error" in result
|
||||
Loading…
Add table
Add a link
Reference in a new issue