Files
hermes-agent/tests/tools/test_search_auto_multiline.py
ethernet bd258480d3 fix(tests): make the test suite pass on Windows without regressing Linux
Gate the POSIX-only and symlink-only tests with the linux_only and
require_symlinks markers. Fix the real cross-platform bugs:

- file_operations: use the translate_path flag, send snippets as base64, and
  use sys.executable (the MS Store python3 stub and the list2cmdline
  backslash collapse both broke snippets)
- approval: treat backslash as a Windows path separator, not an escape
- registry, browser_registry, secret_sources, plugins: normalize scope-key case
- checkpoint_manager, plugins_cmd: clear read-only bits before delete
- deadline: make MAX_SAFE_TIMEOUT_S fit the Windows limit
- image_routing, acp, cua_backend, daytona: fix Windows and POSIX paths
- hermes_state: match backslash in the retag LIKE clause
- kanban, disk-cleanup: match drive paths and split command arguments
- scripts: emit host separators through as_posix

207 test files are gated or isolated.
2026-08-31 17:52:30 -04:00

53 lines
1.9 KiB
Python

"""Tests for search_files auto-multiline routing on \\n patterns."""
import json
import pytest
from tools.file_tools import search_tool
@pytest.fixture
def proj(tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
d = tmp_path / "proj"
d.mkdir()
(d / "mod.py").write_text(
"def setup():\n init_db()\n return True\n\n"
"def teardown():\n close_db()\n",
newline="\n",
)
return d
class TestAutoMultiline:
def test_newline_regex_matches_across_lines(self, proj):
r = json.loads(search_tool(r"def setup\(\):\n init_db\(\)", path=str(proj), task_id="t-ml"))
assert "error" not in r
assert r["total_count"] >= 1
assert "multiline" in r.get("warning", "")
def test_literal_newline_in_pattern_matches(self, proj):
# A raw newline in the pattern (not the \n escape) also routes to
# multiline mode. Keep the pattern free of regex metachars.
r = json.loads(search_tool("return True\n\ndef teardown", path=str(proj), task_id="t-ml"))
assert "error" not in r
assert r["total_count"] >= 1
def test_plain_pattern_unaffected(self, proj):
r = json.loads(search_tool("init_db", path=str(proj), task_id="t-ml"))
assert r["total_count"] == 1
assert "multiline" not in r.get("warning", "")
def test_escaped_backslash_n_stays_literal(self, proj):
# \\n = literal backslash+n search, not a newline: no multiline mode.
(proj / "strings.py").write_text('SEP = "a\\\\nb"\n', newline="\n")
r = json.loads(search_tool(r"a\\nb", path=str(proj), task_id="t-ml"))
assert "error" not in r
assert "multiline" not in (r.get("warning") or "")
def test_multiline_zero_match_is_clean(self, proj):
r = json.loads(search_tool(r"def missing\(\):\n nope\(\)", path=str(proj), task_id="t-ml"))
assert "error" not in r
assert r["total_count"] == 0