hermes-agent/tests/agent/test_display.py
Teknium 6b81590c55
test: prune low-value tests suite-wide (wave 1) — 46,820 → 28,106 test functions
Systematic prune per AGENTS.md test policy, one pass over every major
test tree (gateway, hermes_cli, tools, agent, run_agent, plugins, cli,
cron, tui_gateway, honcho/openviking, root-level):

- DELETE: source-reading tests (read_text/getsource on prod files),
  change-detector tests (exact catalog counts, model-name snapshots,
  config version literals), mock-echo tests (assert a mock returns what
  it was told), assertion-free/trivial tests, near-duplicate
  parametrizations (boundaries + one representative kept), async/sync
  twin duplicates, cosmetic within-file variations.
- KEEP (mandatory): security/redaction/approval guards, message-role
  alternation invariants, prompt-caching/deterministic-call-id
  invariants, issue-number regression tests (deduped), E2E tests.
- 6 test files deleted outright (script-style/no-assert or fully
  redundant); conftest.py, fakes/, fixtures/ untouched.
- tests/acp/conftest.py added: autouse fixture stubs the live
  models.dev/GitHub/Copilot/Anthropic inventory fetches that ACP server
  tests performed on every session create — test_server.py 147s → 3.4s,
  and the tests are now genuinely hermetic.
- Sleep-based slowness shrunk where safe (codex_ttfb_watchdog,
  compression_concurrent_fork, etc.); no wall-clock assertion tightened.

Verification: full hermetic suite via scripts/run_tests.sh —
2439 files, 31,130 tests passed, 0 failed, 0 flaky retries, 315s wall
(baseline: 583s wall, 13,564s subprocess CPU).
2026-07-29 13:10:23 -07:00

278 lines
8.1 KiB
Python

"""Tests for agent/display.py — build_tool_preview() and inline diff previews."""
import json
import pytest
from unittest.mock import MagicMock
import agent.display as display_module
from agent.display import (
build_tool_preview,
capture_local_edit_snapshot,
extract_edit_diff,
get_cute_tool_message,
redact_tool_args_for_display,
set_tool_preview_max_len,
_render_inline_unified_diff,
_summarize_rendered_diff_sections,
render_edit_diff_with_delta,
)
@pytest.fixture(autouse=True)
def reset_tool_preview_max_len():
set_tool_preview_max_len(0)
yield
set_tool_preview_max_len(0)
def test_cute_tool_message_falls_back_when_renderer_raises(monkeypatch):
def _boom(*_args, **_kwargs):
raise RuntimeError("cosmetic failure")
monkeypatch.setattr(display_module, "_get_cute_tool_message", _boom)
assert get_cute_tool_message("web_extract", {"urls": []}, 0.25) == (
"┊ ⚡ web_extra completed 0.2s"
)
class TestBuildToolPreview:
"""Tests for build_tool_preview defensive handling and normal operation."""
def test_none_args_returns_none(self):
"""PR #453: None args should not crash, should return None."""
assert build_tool_preview("terminal", None) is None
def test_empty_dict_returns_none(self):
"""Empty dict has no keys to preview."""
assert build_tool_preview("terminal", {}) is None
def test_browser_type_preview_redacts_api_key(self):
secret = "sk-proj-ABCD1234567890EFGH"
result = build_tool_preview("browser_type", {"ref": "@e3", "text": secret})
assert result is not None
assert secret not in result
assert "sk-pro" in result and "..." in result
def test_browser_type_preview_keeps_normal_text(self):
text = "hello world search query"
result = build_tool_preview("browser_type", {"ref": "@e3", "text": text})
assert result is not None
assert text in result
def test_browser_type_display_args_redact_api_key(self):
secret = "ghp_ABCDEFGHIJ1234567890"
safe_args = redact_tool_args_for_display(
"browser_type", {"ref": "@e3", "text": secret}
)
assert secret not in str(safe_args)
assert safe_args["ref"] == "@e3"
assert safe_args["text"].startswith("ghp_AB")
def test_delegate_task_batch_preview_respects_max_len(self):
result = build_tool_preview(
"delegate_task",
{"tasks": [{"goal": "A" * 80}, {"goal": "B" * 80}]},
max_len=30,
)
assert result == "2 tasks: AAAAAAAAAAAAAAAAAA..."
assert len(result) == 30
def test_false_like_args_zero(self):
"""Non-dict falsy values should return None, not crash."""
assert build_tool_preview("terminal", 0) is None
assert build_tool_preview("terminal", "") is None
assert build_tool_preview("terminal", []) is None
class TestCuteToolMessagePreviewLength:
def test_search_files_preview_uses_positive_configured_limit_not_default(self):
set_tool_preview_max_len(80)
pattern = "function.formatToolCall.context.preview.compactPreview.maxLength.truncate"
line = get_cute_tool_message("search_files", {"pattern": pattern}, 0.1)
assert pattern in line
assert "..." not in line
def test_browser_type_cute_message_redacts_api_key(self):
secret = "sk-proj-ABCD1234567890EFGH"
line = get_cute_tool_message(
"browser_type",
{"ref": "@password", "text": secret},
0.1,
result='{"success": true, "typed": "sk-pro...EFGH"}',
)
assert secret not in line
assert "sk-pro" in line
def test_browser_type_cute_message_keeps_normal_text(self):
text = "hello world"
line = get_cute_tool_message(
"browser_type",
{"ref": "@search", "text": text},
0.1,
result='{"success": true, "typed": "hello world"}',
)
assert text in line
class TestEditDiffPreview:
def test_extract_edit_diff_uses_local_snapshot_for_write_file(self, tmp_path):
target = tmp_path / "note.txt"
target.write_text("old\n", encoding="utf-8")
snapshot = capture_local_edit_snapshot("write_file", {"path": str(target)})
target.write_text("new\n", encoding="utf-8")
diff = extract_edit_diff(
"write_file",
'{"bytes_written": 4}',
function_args={"path": str(target)},
snapshot=snapshot,
)
assert diff is not None
assert "--- a/" in diff
assert "+++ b/" in diff
assert "-old" in diff
assert "+new" in diff
def test_render_edit_diff_with_delta_handles_renderer_errors(self, monkeypatch):
printer = MagicMock()
monkeypatch.setattr("agent.display._summarize_rendered_diff_sections", MagicMock(side_effect=RuntimeError("boom")))
rendered = render_edit_diff_with_delta(
"patch",
'{"diff": "--- a/x\\n+++ b/x\\n"}',
print_fn=printer,
)
assert rendered is False
assert printer.call_count == 0
def test_summarize_rendered_diff_sections_limits_file_count(self):
diff = "".join(
f"--- a/file{i}.py\n+++ b/file{i}.py\n+line{i}\n"
for i in range(8)
)
rendered = _summarize_rendered_diff_sections(diff, max_files=3, max_lines=50)
assert any("a/file0.py" in line for line in rendered)
assert any("a/file1.py" in line for line in rendered)
assert any("a/file2.py" in line for line in rendered)
assert not any("a/file7.py" in line for line in rendered)
assert "additional file" in rendered[-1]
class TestBuildToolLabel:
"""Friendly human-phrased tool labels for built-in tools."""
@pytest.fixture(autouse=True)
def _enable_friendly(self):
from agent.display import set_friendly_tool_labels
set_friendly_tool_labels(True)
yield
set_friendly_tool_labels(True)
def test_web_search_uses_for_connector(self):
from agent.display import build_tool_label
label = build_tool_label("web_search", {"query": "weather in NYC"})
assert label == 'Searching the web for weather in NYC'
def test_web_extract_reads_url(self):
from agent.display import build_tool_label
label = build_tool_label("web_extract", {"urls": ["https://example.com/page"]})
assert label is not None
assert label.startswith("Reading ")
assert "example.com/page" in label
def test_disabled_falls_back_to_preview(self):
from agent.display import (
build_tool_label,
build_tool_preview,
set_friendly_tool_labels,
)
set_friendly_tool_labels(False)
args = {"query": "weather in NYC"}
label = build_tool_label("web_search", args)
# With the feature off, must match the raw preview exactly
assert label == build_tool_preview("web_search", args)
assert "Searching the web" not in (label or "")
class TestBuildStatusPhrase:
"""build_status_phrase — live working-state text for Slack's status line."""
def test_verb_only_when_args_none(self):
# live_status: "verb" mode passes args=None to suppress previews.
from agent.display import build_status_phrase
assert build_status_phrase("terminal", None) == "is running…"
assert build_status_phrase("read_file", None) == "is reading…"
def test_caps_length_for_slack_status_line(self):
from agent.display import build_status_phrase
phrase = build_status_phrase(
"terminal", {"command": "x" * 300}, max_len=49
)
assert phrase is not None and len(phrase) <= 49
assert phrase.endswith("")
def test_respects_friendly_labels_toggle(self):
from agent.display import build_status_phrase, set_friendly_tool_labels
set_friendly_tool_labels(False)
try:
assert build_status_phrase("terminal", {"command": "ls"}) is None
finally:
set_friendly_tool_labels(True)