1package modes
2
3import (
4 "testing"
5
6 "github.com/patriceckhart/zot/packages/core"
7 "github.com/patriceckhart/zot/packages/provider"
8 "github.com/patriceckhart/zot/packages/tui"
9)
10
11func TestInputHistoryUsesUpDown(t *testing.T) {
12 ag := core.NewAgent(nil, "", "", nil)
13 ag.SetMessages([]provider.Message{
14 {Role: provider.RoleUser, Content: []provider.Content{provider.TextBlock{Text: "first"}}},
15 {Role: provider.RoleAssistant, Content: []provider.Content{provider.TextBlock{Text: "reply"}}},
16 {Role: provider.RoleUser, Content: []provider.Content{provider.TextBlock{Text: "second"}}},
17 })
18 i := &Interactive{
19 agent: ag,
20 ed: tui.NewEditor(""),
21 inputHistoryIndex: -1,
22 }
23
24 if !i.handleInputHistoryKey(tui.Key{Kind: tui.KeyUp}) {
25 t.Fatal("expected Up to enter history")
26 }
27 if got := i.ed.Value(); got != "second" {
28 t.Fatalf("Up loaded %q, want newest history item", got)
29 }
30
31 if !i.handleInputHistoryKey(tui.Key{Kind: tui.KeyUp}) {
32 t.Fatal("expected repeated Up to stay in history")
33 }
34 if got := i.ed.Value(); got != "first" {
35 t.Fatalf("second Up loaded %q, want older history item", got)
36 }
37
38 if !i.handleInputHistoryKey(tui.Key{Kind: tui.KeyDown}) {
39 t.Fatal("expected Down to move forward in history")
40 }
41 if got := i.ed.Value(); got != "second" {
42 t.Fatalf("Down loaded %q, want newer history item", got)
43 }
44
45 if !i.handleInputHistoryKey(tui.Key{Kind: tui.KeyDown}) {
46 t.Fatal("expected Down at newest item to clear editor")
47 }
48 if got := i.ed.Value(); got != "" {
49 t.Fatalf("Down past newest loaded %q, want empty editor", got)
50 }
51}
52
53func TestInputHistorySkipsShellEscapeContext(t *testing.T) {
54 ag := core.NewAgent(nil, "", "", nil)
55 ag.SetMessages([]provider.Message{
56 {Role: provider.RoleUser, Content: []provider.Content{provider.TextBlock{Text: "prompt"}}},
57 {Role: provider.RoleUser, Content: []provider.Content{provider.TextBlock{Text: "$ pwd\n\n/tmp\n\n[exit 0]"}}, Meta: map[string]string{shellEscapeMetaKey: "true"}},
58 })
59 i := &Interactive{agent: ag}
60
61 history := i.inputHistory()
62 if len(history) != 1 || history[0] != "prompt" {
63 t.Fatalf("inputHistory() = %q, want [prompt]", history)
64 }
65}
66
67func TestInputHistoryNoLongerUsesLeftRight(t *testing.T) {
68 ag := core.NewAgent(nil, "", "", nil)
69 ag.SetMessages([]provider.Message{
70 {Role: provider.RoleUser, Content: []provider.Content{provider.TextBlock{Text: "prompt"}}},
71 })
72 i := &Interactive{
73 agent: ag,
74 ed: tui.NewEditor(""),
75 inputHistoryIndex: -1,
76 }
77
78 if i.handleInputHistoryKey(tui.Key{Kind: tui.KeyLeft}) {
79 t.Fatal("Left should not browse input history")
80 }
81 if i.handleInputHistoryKey(tui.Key{Kind: tui.KeyRight}) {
82 t.Fatal("Right should not browse input history")
83 }
84 if got := i.ed.Value(); got != "" {
85 t.Fatalf("left/right changed editor to %q", got)
86 }
87}
88
89func TestInputHistoryDoesNotStealNonEmptyEditor(t *testing.T) {
90 ag := core.NewAgent(nil, "", "", nil)
91 ag.SetMessages([]provider.Message{
92 {Role: provider.RoleUser, Content: []provider.Content{provider.TextBlock{Text: "prompt"}}},
93 })
94 i := &Interactive{
95 agent: ag,
96 ed: tui.NewEditor(""),
97 inputHistoryIndex: -1,
98 }
99 i.ed.SetValue("draft")
100
101 if i.handleInputHistoryKey(tui.Key{Kind: tui.KeyUp}) {
102 t.Fatal("Up should not browse history while editing a draft")
103 }
104 if got := i.ed.Value(); got != "draft" {
105 t.Fatalf("editor changed to %q, want draft", got)
106 }
107}