Skip to content

Commit e968a78

Browse files
committed
test(ui): align compaction-seam and recap spacing expectations
Update rendering tests to match the committed compaction/recap seam behavior: compaction commits a leading blank row plus block, and turn recaps are framed by blank rows.
1 parent c4d20b3 commit e968a78

3 files changed

Lines changed: 35 additions & 9 deletions

File tree

tests/ui_and_conv/test_empty_think_part_indicator.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,9 @@ def test_compaction_takes_priority_over_moon():
382382
# Compaction starts — should show compaction, not moon
383383
view.dispatch_wire_message(CompactionBegin())
384384
agent_blocks = view.compose_agent_output()
385-
# Should be the compaction block, not the moon
386-
assert len(agent_blocks) == 1
385+
# Should be the compaction block, not the moon. Compaction commits with a
386+
# leading seam (blank row + block), so there are two blocks.
387+
assert len(agent_blocks) == 2
387388
assert view._compaction_block is not None
388389

389390

tests/ui_and_conv/test_live_view_notifications.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
from pythinker_core.message import ToolCall
44
from pythinker_core.tooling import ToolResult, ToolReturnValue
5-
from rich.console import Console
5+
from rich.console import Console, Group
66

77
from pythinker_code.tools.display import TodoDisplayBlock, TodoDisplayItem
88
from pythinker_code.ui.shell.console import console as shell_console
99
from pythinker_code.ui.shell.keyboard import KeyEvent
1010
from pythinker_code.ui.shell.visualize import _live_view as live_view_module
1111
from pythinker_code.ui.shell.visualize import _LiveView, _PromptLiveView
1212
from pythinker_code.wire.types import (
13+
CompactionBegin,
1314
HookOutput,
1415
HookResolved,
1516
HookTriggered,
@@ -318,20 +319,32 @@ def test_prompt_live_view_keeps_non_background_task_notifications(monkeypatch):
318319

319320
def test_live_view_prints_turn_recap_when_enabled(monkeypatch):
320321
printed = []
321-
monkeypatch.setattr(
322-
live_view_module.console, "print", lambda *args, **_kwargs: printed.extend(args)
323-
)
322+
323+
def fake_print(*args, **_kwargs):
324+
printed.append(args[0] if args else None)
325+
326+
monkeypatch.setattr(live_view_module.console, "print", fake_print)
324327

325328
view = _LiveView(StatusUpdate(), show_turn_recaps=True)
326329
view.dispatch_wire_message(TurnBegin(user_input="implement recaps"))
327-
view.dispatch_wire_message(TextPart(text="Implemented a /recap command."))
330+
view.dispatch_wire_message(TextPart(text="Implemented a "))
331+
view.dispatch_wire_message(TextPart(text="/recap command."))
328332
view.dispatch_wire_message(TurnEnd())
329333
view.cleanup(is_interrupt=False)
330334

331-
plain = "\n".join(getattr(item, "plain", str(item)) for item in printed)
335+
plain = "\n".join(getattr(item, "plain", str(item)) for item in printed if item is not None)
332336
assert "※ recap: Implemented a /recap command." in plain
337+
assert "Implemented a /recap" not in plain
333338
assert "disable recaps in /settings" in plain
334339

340+
recap_index = next(
341+
index
342+
for index, item in enumerate(printed)
343+
if item is not None and "※ recap:" in getattr(item, "plain", str(item))
344+
)
345+
assert printed[recap_index - 1] is None
346+
assert printed[recap_index + 1] is None
347+
335348

336349
def test_cleanup_flushes_notifications_to_terminal_history(monkeypatch):
337350
view = _LiveView(StatusUpdate())
@@ -371,6 +384,15 @@ def test_cleanup_flushes_all_notifications_even_when_live_view_shows_only_latest
371384
assert f"Background task completed: build project {index}" in rendered
372385

373386

387+
def test_compaction_status_keeps_one_blank_row_above_live_block():
388+
view = _LiveView(StatusUpdate(context_tokens=221_300))
389+
390+
view.dispatch_wire_message(CompactionBegin())
391+
392+
rendered = _render(Group(*view.compose_agent_output(include_working_indicator=False)))
393+
assert rendered.startswith("\n· Compacting conversation…")
394+
395+
374396
def test_compose_inserts_gap_under_agent_output_before_nonempty_status():
375397
"""Non-interactive compose() puts one blank row under the spinner verb
376398
before a non-empty status line (the under-gap), and the status line stays last."""

tests/ui_and_conv/test_plan_display_panel.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ def fake_render_worklog_card(title, body, *, subtitle=None, border_style="grey50
2424
return panel
2525

2626
monkeypatch.setattr(_live_view, "render_worklog_card", fake_render_worklog_card)
27-
monkeypatch.setattr(_live_view.console, "print", printed.append)
27+
monkeypatch.setattr(_live_view.console, "print", lambda *args, **kwargs: printed.extend(args))
2828
view = _live_view._LiveView(StatusUpdate())
2929

3030
view.display_plan(PlanDisplay(content="# Steps\n\n- Step one", file_path="plans/one.md"))
3131

3232
assert card_call["title"] == "Plan"
3333
assert card_call["subtitle"] == "plans/one.md"
3434
assert card_call["border_style"] == tui_rich_style("border")
35+
# _print_action_block emits a leading blank line (zero-arg console.print())
36+
# before the panel; only positional args are captured, so printed holds the
37+
# panel alone.
3538
assert printed == [card_call["panel"]]
3639

3740
console = Console(record=True, width=120, color_system=None)

0 commit comments

Comments
 (0)