okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

Aly Raffaufrefactor(cli): require explicit daemon client dependencies2ce1ecd

main
2.9 KiB102 linesraw
1// Queued and failed continue events must not corrupt the TUI transcript.
2package tui
3
4import (
5	"errors"
6	"strings"
7	"testing"
8	"time"
9
10	"albedo/cli/internal/daemon"
11	tea "charm.land/bubbletea/v2"
12	"github.com/charmbracelet/x/ansi"
13)
14
15func TestDotContinueDoesNotAppearInUI(t *testing.T) {
16	m := newTestChatModel(t, &daemon.Session{ID: "s"})
17	m.SetSize(80, 30)
18	m.appendSettledEntry(HistoryEntry{Kind: EntryAssistant, Speaker: "albedo", Text: "ready", Timestamp: time.Now().UnixMilli() - 1000})
19
20	var cmds []tea.Cmd
21	m.submitInput(".", &cmds)
22
23	if len(m.pendingUsers) != 0 {
24		t.Fatalf("expected 0 pending users for dot continue, got %d", len(m.pendingUsers))
25	}
26	if len(m.pendingRows()) != 0 {
27		t.Fatalf("expected 0 pending rows for dot continue, got %d", len(m.pendingRows()))
28	}
29	afterView := ansi.Strip(m.Viewport.View())
30	if strings.Contains(afterView, "│ .") || strings.Contains(afterView, "│ continue") || strings.Contains(afterView, "│ you") {
31		t.Fatalf("transcript should not contain dot or continue prompt:\n%s", afterView)
32	}
33	if !m.isSending {
34		t.Fatal("expected isSending to be true")
35	}
36	if len(cmds) == 0 {
37		t.Fatal("expected cmds to be returned for continue submission")
38	}
39}
40
41func TestDotContinueErrorDoesNotCorruptPendingUsers(t *testing.T) {
42	m := newTestChatModel(t, &daemon.Session{ID: "s"})
43	m.pendingUsers = []PendingUserTurn{{Text: "real user prompt", At: time.Now().UnixMilli()}}
44	m.TextArea.SetValue("")
45
46	errMsg := ChatTurnSentMsg{
47		SessionID:  "s",
48		Generation: m.Generation,
49		Prompt:     ".",
50		Continue:   true,
51		Err:        errors.New("network failure"),
52	}
53
54	um, _ := m.Update(errMsg)
55
56	if len(um.pendingUsers) != 1 || um.pendingUsers[0].Text != "real user prompt" {
57		t.Fatalf("pending user turn was corrupted or popped: %+v", um.pendingUsers)
58	}
59	if um.TextArea.Value() == "." {
60		t.Fatalf("text area was overwritten with dot: %q", um.TextArea.Value())
61	}
62}
63
64func TestMessageSubmitClearsTurnFailed(t *testing.T) {
65	m := newTestChatModel(t, &daemon.Session{ID: "s"})
66	m.SetSize(80, 30)
67	m.TurnFailed = true
68	m.Stopped = true
69
70	var cmds []tea.Cmd
71	m.submitInput("retry prompt", &cmds)
72
73	if m.TurnFailed {
74		t.Fatal("expected TurnFailed to be false after submitting input")
75	}
76	if m.Stopped {
77		t.Fatal("expected Stopped to be false after submitting input")
78	}
79	if !m.isSending || len(m.pendingUsers) != 1 || m.pendingUsers[0].Text != "retry prompt" || len(cmds) == 0 {
80		t.Fatal("retry did not start a new submission")
81	}
82}
83
84func TestDotContinueClearsTurnFailed(t *testing.T) {
85	m := newTestChatModel(t, &daemon.Session{ID: "s"})
86	m.SetSize(80, 30)
87	m.TurnFailed = true
88	m.Stopped = true
89
90	var cmds []tea.Cmd
91	m.submitInput(".", &cmds)
92
93	if m.TurnFailed {
94		t.Fatal("expected TurnFailed to be false after submitting dot continue")
95	}
96	if m.Stopped {
97		t.Fatal("expected Stopped to be false after submitting dot continue")
98	}
99	if !m.isSending || len(cmds) == 0 {
100		t.Fatal("continue did not start a new submission")
101	}
102}