v2.5.0 b9b6391

routes_test.go RawHistoryFolder

1package cli
2
3import (
4	"testing"
5
6	"github.com/stretchr/testify/assert"
7)
8
9func TestTruncateImage(t *testing.T) {
10	tests := []struct {
11		name     string
12		image    string
13		maxLen   int
14		expected string
15	}{
16		// Basic cases - no truncation needed
17		{
18			name:     "short image fits",
19			image:    "nginx:latest",
20			maxLen:   20,
21			expected: "nginx:latest",
22		},
23		{
24			name:     "exact fit",
25			image:    "nginx:latest",
26			maxLen:   12,
27			expected: "nginx:latest",
28		},
29
30		// Regular tag truncation
31		{
32			name:     "truncate long tag with ellipsis",
33			image:    "registry.test.com/test:v1234567890",
34			maxLen:   30,
35			expected: "registry.test.com/test:v123...",
36		},
37		{
38			name:     "truncate very long image",
39			image:    "registry.example.com/organization/project/image:v1.2.3-beta.4",
40			maxLen:   35,
41			expected: "registry.example.com/organizatio...",
42		},
43
44		// Digest truncation
45		{
46			name:     "digest shortened to 12 chars",
47			image:    "myapp@sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4",
48			maxLen:   50,
49			expected: "myapp@sha256:a3ed95caeb02",
50		},
51		{
52			name:     "digest truncated with ellipsis when too long",
53			image:    "registry.example.com/org/app@sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4",
54			maxLen:   35,
55			expected: "registry.example.com/org/app@sha...",
56		},
57		{
58			name:     "short digest fits",
59			image:    "app@sha256:abc123",
60			maxLen:   30,
61			expected: "app@sha256:abc123",
62		},
63
64		// Edge cases
65		{
66			name:     "maxLen zero returns empty",
67			image:    "nginx:latest",
68			maxLen:   0,
69			expected: "",
70		},
71		{
72			name:     "maxLen negative returns empty",
73			image:    "nginx:latest",
74			maxLen:   -1,
75			expected: "",
76		},
77		{
78			name:     "maxLen 3 or less - no ellipsis",
79			image:    "nginx:latest",
80			maxLen:   3,
81			expected: "ngi",
82		},
83		{
84			name:     "maxLen 4 - truncate with ellipsis",
85			image:    "nginx:latest",
86			maxLen:   4,
87			expected: "n...",
88		},
89		{
90			name:     "empty image",
91			image:    "",
92			maxLen:   10,
93			expected: "",
94		},
95	}
96
97	for _, tt := range tests {
98		t.Run(tt.name, func(t *testing.T) {
99			result := truncateImage(tt.image, tt.maxLen)
100			assert.Equal(t, tt.expected, result)
101		})
102	}
103}
104
105func TestTruncateNetwork(t *testing.T) {
106	tests := []struct {
107		name     string
108		network  string
109		maxLen   int
110		expected string
111	}{
112		// Basic cases
113		{
114			name:     "short network fits",
115			network:  "gordon-net",
116			maxLen:   20,
117			expected: "gordon-net",
118		},
119		{
120			name:     "exact fit",
121			network:  "gordon-net",
122			maxLen:   10,
123			expected: "gordon-net",
124		},
125
126		// Truncation
127		{
128			name:     "truncate long network with ellipsis",
129			network:  "gordon-my-very-long-network-name",
130			maxLen:   20,
131			expected: "gordon-my-very-lo...",
132		},
133
134		// Special values
135		{
136			name:     "empty returns dash",
137			network:  "",
138			maxLen:   10,
139			expected: "-",
140		},
141		{
142			name:     "dash returns dash",
143			network:  "-",
144			maxLen:   10,
145			expected: "-",
146		},
147
148		// Edge cases
149		{
150			name:     "maxLen zero returns empty",
151			network:  "gordon-net",
152			maxLen:   0,
153			expected: "",
154		},
155		{
156			name:     "maxLen negative returns empty",
157			network:  "gordon-net",
158			maxLen:   -1,
159			expected: "",
160		},
161		{
162			name:     "maxLen 3 or less - no ellipsis",
163			network:  "gordon-net",
164			maxLen:   3,
165			expected: "gor",
166		},
167		{
168			name:     "maxLen 4 - truncate with ellipsis",
169			network:  "gordon-net",
170			maxLen:   4,
171			expected: "g...",
172		},
173	}
174
175	for _, tt := range tests {
176		t.Run(tt.name, func(t *testing.T) {
177			result := truncateNetwork(tt.network, tt.maxLen)
178			assert.Equal(t, tt.expected, result)
179		})
180	}
181}

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 7

Tags 106

↑↓ moveenter openesc close