v0.3.21 7fe8dbc

clipboard_images_test.go RawHistoryFolder

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

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 477

↑↓ moveenter openesc close