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