1package modes
2
3import (
4 "strings"
5 "testing"
6
7 "github.com/mattn/go-runewidth"
8
9 "github.com/bnema/zut/packages/agent/subagents"
10 "github.com/bnema/zut/packages/tui"
11)
12
13func assertRowsFitWidth(t *testing.T, rows []string, width int) {
14 t.Helper()
15 for i, row := range rows {
16 if got := runewidth.StringWidth(stripANSIBytes(row)); got > width {
17 t.Errorf("row %d width = %d, want <= %d: %q", i, got, width, stripANSIBytes(row))
18 }
19 }
20}
21
22func TestBtwDialogWrapsAssistantAndKeepsCursorAligned(t *testing.T) {
23 const width = 80
24 response := "This response is deliberately long enough to require several wrapped display rows without losing any words."
25 d := &btwDialog{
26 active: true,
27 lineInput: true,
28 turns: []btwTurn{{
29 User: "check wrapping",
30 Assistant: response,
31 }},
32 editor: tui.NewEditor(""),
33 }
34
35 rows := d.Render(tui.Theme{}, width)
36 assertRowsFitWidth(t, rows, width)
37 plain := strings.Join(rows, "\n")
38 for _, word := range strings.Fields(response) {
39 if !strings.Contains(plain, word) {
40 t.Fatalf("wrapped response lost word %q:\n%s", word, plain)
41 }
42 }
43
44 cursorRow, _ := d.CursorPos(width)
45 if want := len(rows) - 3; cursorRow != want {
46 t.Fatalf("cursor row = %d, want editor row %d", cursorRow, want)
47 }
48}
49
50func TestSupervisorTranscriptWrapsAssistantAndDiagnosticRows(t *testing.T) {
51 const width = 80
52 long := strings.Repeat("long response text ", 8)
53 rows := renderSupervisorTranscriptBlocks([]string{
54 long,
55 "stderr: " + long,
56 "error: " + long,
57 }, tui.Theme{}, width, false)
58
59 assertRowsFitWidth(t, rows, width)
60 plain := strings.Join(rows, "\n")
61 for _, want := range []string{"long", "stderr", "✖"} {
62 if !strings.Contains(plain, want) {
63 t.Fatalf("wrapped transcript missing %q:\n%s", want, plain)
64 }
65 }
66}
67
68func TestSubagentsDialogViewingWrapsSpawnedAgentResponse(t *testing.T) {
69 const width = 80
70 response := strings.Repeat("spawned agent response ", 6)
71 rows := []subagents.AgentSnapshot{{
72 ID: "agent-1",
73 Status: subagents.StatusDone,
74 Lines: []string{response},
75 }}
76 d := newSubagentsDialog()
77 d.Open(staticSnapshots(rows...), nil, nil, nil, nil, nil, "")
78 _ = d.Render(tui.Theme{}, width)
79 d.HandleKey(tui.Key{Kind: tui.KeyEnter})
80
81 rendered := d.Render(tui.Theme{}, width)
82 assertRowsFitWidth(t, rendered, width)
83 if !strings.Contains(strings.Join(rendered, "\n"), "response") {
84 t.Fatal("spawned agent response missing from transcript")
85 }
86}