1package modes
2
3import (
4 "strings"
5 "testing"
6
7 "github.com/bnema/zut/packages/core"
8 "github.com/bnema/zut/packages/provider"
9)
10
11func testClipboardImage(marker string, data string) clipboardImageAttachment {
12 return clipboardImageAttachment{
13 Marker: marker,
14 Image: provider.ImageBlock{MimeType: "image/png", Data: []byte(data)},
15 }
16}
17
18func TestRestoredQueuedImageDoesNotConsumeLiteralClipboardMarker(t *testing.T) {
19 i := NewInteractive(InteractiveConfig{})
20 message := core.QueuedMessage{
21 Text: "keep literal [clipboard image #1]",
22 Images: []provider.ImageBlock{{MimeType: "image/png", Data: []byte("png-1")}},
23 }
24
25 if !i.restoreQueuedMessageToEditor(message) {
26 t.Fatal("queued message was not restored")
27 }
28 text, images := preparePromptWithClipboardImages(i.ed.Value(), i.clipboardImages)
29
30 if text != message.Text {
31 t.Fatalf("resubmitted text = %q, want %q", text, message.Text)
32 }
33 if len(images) != 1 || string(images[0].Data) != "png-1" {
34 t.Fatalf("resubmitted images = %#v, want png-1", images)
35 }
36}
37
38func TestPreparePromptWithClipboardImagesStripsPresentMarker(t *testing.T) {
39 pending := []clipboardImageAttachment{testClipboardImage("[clipboard image #1]", "png-1")}
40
41 text, images := preparePromptWithClipboardImages("describe this [clipboard image #1] please", pending)
42
43 if text != "describe this please" {
44 t.Fatalf("text = %q, want %q", text, "describe this please")
45 }
46 if len(images) != 1 {
47 t.Fatalf("len(images) = %d, want 1", len(images))
48 }
49 if string(images[0].Data) != "png-1" {
50 t.Fatalf("image data = %q, want png-1", string(images[0].Data))
51 }
52}
53
54func TestPreparePromptWithClipboardImagesAllowsImageOnlyPrompt(t *testing.T) {
55 pending := []clipboardImageAttachment{testClipboardImage("[clipboard image #1]", "png-1")}
56
57 text, images := preparePromptWithClipboardImages("[clipboard image #1]", pending)
58
59 if text != "" {
60 t.Fatalf("text = %q, want empty", text)
61 }
62 if len(images) != 1 {
63 t.Fatalf("len(images) = %d, want 1", len(images))
64 }
65}
66
67func TestPreparePromptWithClipboardImagesIgnoresDeletedMarker(t *testing.T) {
68 pending := []clipboardImageAttachment{testClipboardImage("[clipboard image #1]", "png-1")}
69
70 text, images := preparePromptWithClipboardImages("describe this from memory", pending)
71
72 if text != "describe this from memory" {
73 t.Fatalf("text = %q, want unchanged", text)
74 }
75 if len(images) != 0 {
76 t.Fatalf("len(images) = %d, want 0", len(images))
77 }
78}
79
80func TestPreparePromptWithClipboardImagesHandlesMultipleImagesInPasteOrder(t *testing.T) {
81 pending := []clipboardImageAttachment{
82 testClipboardImage("[clipboard image #1]", "png-1"),
83 testClipboardImage("[clipboard image #2]", "png-2"),
84 }
85
86 text, images := preparePromptWithClipboardImages("compare [clipboard image #2] with [clipboard image #1]", pending)
87
88 if text != "compare with" {
89 t.Fatalf("text = %q, want %q", text, "compare with")
90 }
91 if len(images) != 2 {
92 t.Fatalf("len(images) = %d, want 2", len(images))
93 }
94 if string(images[0].Data) != "png-1" || string(images[1].Data) != "png-2" {
95 t.Fatalf("images not attached in paste order: %q, %q", string(images[0].Data), string(images[1].Data))
96 }
97}
98
99func TestPreparePromptWithClipboardImagesDuplicateMarkerAttachesOnce(t *testing.T) {
100 pending := []clipboardImageAttachment{testClipboardImage("[clipboard image #1]", "png-1")}
101
102 text, images := preparePromptWithClipboardImages("[clipboard image #1] and again [clipboard image #1]", pending)
103
104 if strings.Contains(text, "[clipboard image #1]") {
105 t.Fatalf("text still contains marker: %q", text)
106 }
107 if text != "and again" {
108 t.Fatalf("text = %q, want %q", text, "and again")
109 }
110 if len(images) != 1 {
111 t.Fatalf("len(images) = %d, want 1", len(images))
112 }
113}
114
115func TestPreparePromptWithClipboardImagesNoPendingPreservesWhitespace(t *testing.T) {
116 input := "please review:\n\nfunc main() {\n\tfmt.Println(\"hi\")\n}\n"
117
118 text, images := preparePromptWithClipboardImages(input, nil)
119
120 if text != input {
121 t.Fatalf("text changed without pending images:\n got %q\nwant %q", text, input)
122 }
123 if images != nil {
124 t.Fatalf("images = %#v, want nil", images)
125 }
126}
127
128func TestPreparePromptWithClipboardImagesPreservesMultilinePrompt(t *testing.T) {
129 pending := []clipboardImageAttachment{testClipboardImage("[clipboard image #1]", "png-1")}
130 input := "compare this image [clipboard image #1]\n\nwith this code:\n\treturn 1"
131 want := "compare this image\n\nwith this code:\n\treturn 1"
132
133 text, images := preparePromptWithClipboardImages(input, pending)
134
135 if text != want {
136 t.Fatalf("text = %q, want %q", text, want)
137 }
138 if len(images) != 1 {
139 t.Fatalf("len(images) = %d, want 1", len(images))
140 }
141}