"""Tests for the terminal tool-call renderer (action-aware cards)."""
from __future__ import annotations
from rich.console import Console
from rich.text import Text
from clients.terminal.tui.renderers.terminal import TerminalToolResultRenderer
from clients.terminal.tui.themes import get_active_theme, set_active_theme
def _render_text(renderable) -> str:
console = Console(record=True, width=80, force_terminal=True, color_system=None)
console.print(renderable)
return console.export_text()
def _body(panel):
r = panel.renderable
if isinstance(r, Text):
return r
return r
def _msg(action, **kw):
msg = {"type": "tool_call", "tool": "terminal", "args": {"action": action}, "success": True}
msg.update(kw)
return msg
def test_accepts_only_terminal_tool_call() -> None:
r = TerminalToolResultRenderer()
assert r.accepts(_msg("run"))
assert not r.accepts({"type": "tool_call", "tool": "filesystem", "args": {"action": "read"}})
assert not r.accepts({"type": "tool_started", "tool": "terminal"})
def test_run_shows_command_and_exit_code() -> None:
set_active_theme("gnexus-dark")
theme = get_active_theme()
panel = TerminalToolResultRenderer().render(
_msg("run", args={"action": "run", "command": "echo hi"}, result="hi", success=True, metadata={"returncode": 0})
)
text = _render_text(panel)
assert "$ echo hi" in text
assert "hi" in text
assert "exit 0" in text
assert "✓" in str(panel.title)
def test_run_failure_marks_exit_code_red() -> None:
set_active_theme("gnexus-dark")
panel = TerminalToolResultRenderer().render(
_msg("run", args={"action": "run", "command": "false"}, result="", success=False, metadata={"returncode": 1})
)
text = _render_text(panel)
assert "$ false" in text
assert "exit 1" in text
assert "✗" in str(panel.title)
def test_open_shows_name_description_pid() -> None:
set_active_theme("gnexus-dark")
panel = TerminalToolResultRenderer().render(
_msg(
"open",
args={"action": "open", "terminal_name": "dev", "description": "dev server", "background": True},
result="Terminal 'dev' opened in background. PID: 123.",
success=True,
metadata={"name": "dev", "description": "dev server", "pid": 123},
)
)
text = _render_text(panel)
assert "dev" in text
assert "dev server" in text
assert "background" in text
assert "123" in text
def test_list_renders_output_dim() -> None:
set_active_theme("gnexus-dark")
panel = TerminalToolResultRenderer().render(
_msg("list", result="Active terminals (1):\n 🟢 dev: server", success=True)
)
text = _render_text(panel)
assert "Active terminals" in text
assert "dev" in text
def test_status_renders_output() -> None:
set_active_theme("gnexus-dark")
panel = TerminalToolResultRenderer().render(
_msg("status", result="Terminal: dev\nStatus: busy\nPID: 7", success=True)
)
text = _render_text(panel)
assert "Terminal: dev" in text
assert "busy" in text
def test_send_input_echo() -> None:
set_active_theme("gnexus-dark")
panel = TerminalToolResultRenderer().render(
_msg("send_input", result="Sent input to 'dev'.", success=True)
)
text = _render_text(panel)
assert "Sent input" in text
def test_close_message() -> None:
set_active_theme("gnexus-dark")
panel = TerminalToolResultRenderer().render(
_msg("close", result="Terminal 'dev' closed.", success=True)
)
text = _render_text(panel)
assert "closed" in text
def test_run_truncates_long_output() -> None:
set_active_theme("gnexus-dark")
big = "\n".join(f"line {i}" for i in range(300))
panel = TerminalToolResultRenderer().render(
_msg("run", args={"action": "run", "command": "heavy"}, result=big, success=True, metadata={"returncode": 0})
)
text = _render_text(panel)
assert "lines truncated]" in text
assert "line 299" in text
assert "line 0" not in text