Files
correx/apps/tui-go/internal/app/transcript_test.go
T
kami ba7ac06c16 feat(tui-go): transcript message-jump + OSC52 copy
ctrl+↑/↓ jumps between your sent (user) messages in the transcript: ctrl+↑ from the
bottom selects the most recent, steps to older ones (clamping); ctrl+↓ steps back and
drops to tail-follow past the last. The selected message is highlighted and scrolled
into view (routerRows tracks per-message row offsets and windows to the selection).

`y` yanks the selected message — or the latest turn when none is selected — to the
system clipboard over OSC52 (go-osc52, tmux-wrapped under $TMUX), which is SSH/Termius-
safe unlike a mouse drag. A brief "✓ copied" footer note animates out (and self-stops
the tick). esc drops the selection; switching sessions clears it. Tests cover the
user-message jump/clamp/tail and the copy-text selection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 09:59:29 +00:00

68 lines
2.1 KiB
Go

package app
import "testing"
func transcriptModel(roles ...string) Model {
m := NewModel(nil)
m.selectedID = "s1"
msgs := make([]RouterEntry, len(roles))
for i, r := range roles {
msgs[i] = RouterEntry{Role: r, Content: r + itoa(i)}
}
m.routerMessages["s1"] = msgs
return m
}
// ctrl+↑/↓ jumps between USER messages: from no selection ↑ grabs the most recent user
// message, keeps stepping to older ones (clamping), and ↓ steps back down, dropping to
// tail-follow (-1) once past the last user message.
func TestTranscriptNavUser(t *testing.T) {
// indices: 0 1 2 3 4
m := transcriptModel("user", "router", "user", "router", "user")
if m.transcriptSel != -1 {
t.Fatalf("initial sel = %d, want -1", m.transcriptSel)
}
m.transcriptNavUser(-1) // up from bottom → newest user (idx 4)
if m.transcriptSel != 4 {
t.Fatalf("up#1 = %d, want 4", m.transcriptSel)
}
m.transcriptNavUser(-1) // → user idx 2
if m.transcriptSel != 2 {
t.Fatalf("up#2 = %d, want 2", m.transcriptSel)
}
m.transcriptNavUser(-1) // → user idx 0
if m.transcriptSel != 0 {
t.Fatalf("up#3 = %d, want 0", m.transcriptSel)
}
m.transcriptNavUser(-1) // clamp at oldest
if m.transcriptSel != 0 {
t.Fatalf("up#4 (clamp) = %d, want 0", m.transcriptSel)
}
m.transcriptNavUser(1) // → user idx 2
if m.transcriptSel != 2 {
t.Fatalf("down#1 = %d, want 2", m.transcriptSel)
}
m.transcriptNavUser(1) // → user idx 4
m.transcriptNavUser(1) // past last user → tail-follow
if m.transcriptSel != -1 {
t.Fatalf("down past last = %d, want -1 (tail-follow)", m.transcriptSel)
}
}
// `y` copies the selected message, or the latest user/router turn when nothing is selected.
func TestCopyText(t *testing.T) {
m := transcriptModel("user", "router", "tool")
// no selection → most recent user/router turn (the "router" at idx 1, since "tool"
// is skipped).
if got := m.copyText(); got != "router1" {
t.Fatalf("copyText (no sel) = %q, want %q", got, "router1")
}
m.transcriptSel = 0
if got := m.copyText(); got != "user0" {
t.Fatalf("copyText (sel idx 0) = %q, want %q", got, "user0")
}
}