A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
1package readme
2
3import (
4 "testing"
5)
6
7func TestParseSourceURL(t *testing.T) {
8 tests := []struct {
9 name string
10 sourceURL string
11 wantPlatform Platform
12 wantUser string
13 wantRepo string
14 wantOK bool
15 }{
16 // GitHub
17 {
18 name: "github standard",
19 sourceURL: "https://github.com/bigmoves/quickslice",
20 wantPlatform: PlatformGitHub,
21 wantUser: "bigmoves",
22 wantRepo: "quickslice",
23 wantOK: true,
24 },
25 {
26 name: "github with .git suffix",
27 sourceURL: "https://github.com/user/repo.git",
28 wantPlatform: PlatformGitHub,
29 wantUser: "user",
30 wantRepo: "repo",
31 wantOK: true,
32 },
33 {
34 name: "github with trailing slash",
35 sourceURL: "https://github.com/user/repo/",
36 wantPlatform: PlatformGitHub,
37 wantUser: "user",
38 wantRepo: "repo",
39 wantOK: true,
40 },
41 {
42 name: "github with subpath (ignored)",
43 sourceURL: "https://github.com/user/repo/tree/main",
44 wantPlatform: PlatformGitHub,
45 wantUser: "user",
46 wantRepo: "repo",
47 wantOK: true,
48 },
49 {
50 name: "github user only",
51 sourceURL: "https://github.com/user",
52 wantOK: false,
53 },
54
55 // GitLab
56 {
57 name: "gitlab standard",
58 sourceURL: "https://gitlab.com/user/repo",
59 wantPlatform: PlatformGitLab,
60 wantUser: "user",
61 wantRepo: "repo",
62 wantOK: true,
63 },
64 {
65 name: "gitlab nested groups",
66 sourceURL: "https://gitlab.com/group/subgroup/repo",
67 wantPlatform: PlatformGitLab,
68 wantUser: "group/subgroup",
69 wantRepo: "repo",
70 wantOK: true,
71 },
72 {
73 name: "gitlab deep nested groups",
74 sourceURL: "https://gitlab.com/a/b/c/d/repo",
75 wantPlatform: PlatformGitLab,
76 wantUser: "a/b/c/d",
77 wantRepo: "repo",
78 wantOK: true,
79 },
80 {
81 name: "gitlab with .git suffix",
82 sourceURL: "https://gitlab.com/user/repo.git",
83 wantPlatform: PlatformGitLab,
84 wantUser: "user",
85 wantRepo: "repo",
86 wantOK: true,
87 },
88
89 // Tangled
90 {
91 name: "tangled standard",
92 sourceURL: "https://tangled.org/evan.jarrett.net/at-container-registry",
93 wantPlatform: PlatformTangled,
94 wantUser: "evan.jarrett.net",
95 wantRepo: "at-container-registry",
96 wantOK: true,
97 },
98 {
99 name: "tangled with legacy @ prefix",
100 sourceURL: "https://tangled.org/@evan.jarrett.net/at-container-registry",
101 wantPlatform: PlatformTangled,
102 wantUser: "evan.jarrett.net",
103 wantRepo: "at-container-registry",
104 wantOK: true,
105 },
106 {
107 name: "tangled.sh domain",
108 sourceURL: "https://tangled.sh/user/repo",
109 wantPlatform: PlatformTangled,
110 wantUser: "user",
111 wantRepo: "repo",
112 wantOK: true,
113 },
114 {
115 name: "tangled with trailing slash",
116 sourceURL: "https://tangled.org/user/repo/",
117 wantPlatform: PlatformTangled,
118 wantUser: "user",
119 wantRepo: "repo",
120 wantOK: true,
121 },
122
123 // Codeberg
124 {
125 name: "codeberg standard",
126 sourceURL: "https://codeberg.org/user/repo",
127 wantPlatform: PlatformCodeberg,
128 wantUser: "user",
129 wantRepo: "repo",
130 wantOK: true,
131 },
132
133 // Unsupported / Invalid
134 {
135 name: "unsupported platform",
136 sourceURL: "https://bitbucket.org/user/repo",
137 wantOK: false,
138 },
139 {
140 name: "empty url",
141 sourceURL: "",
142 wantOK: false,
143 },
144 {
145 name: "invalid url",
146 sourceURL: "not-a-url",
147 wantOK: false,
148 },
149 {
150 name: "just host",
151 sourceURL: "https://github.com",
152 wantOK: false,
153 },
154 }
155
156 for _, tt := range tests {
157 t.Run(tt.name, func(t *testing.T) {
158 platform, user, repo, ok := ParseSourceURL(tt.sourceURL)
159 if ok != tt.wantOK {
160 t.Errorf("ParseSourceURL(%q) ok = %v, want %v", tt.sourceURL, ok, tt.wantOK)
161 return
162 }
163 if !tt.wantOK {
164 return
165 }
166 if platform != tt.wantPlatform {
167 t.Errorf("ParseSourceURL(%q) platform = %v, want %v", tt.sourceURL, platform, tt.wantPlatform)
168 }
169 if user != tt.wantUser {
170 t.Errorf("ParseSourceURL(%q) user = %q, want %q", tt.sourceURL, user, tt.wantUser)
171 }
172 if repo != tt.wantRepo {
173 t.Errorf("ParseSourceURL(%q) repo = %q, want %q", tt.sourceURL, repo, tt.wantRepo)
174 }
175 })
176 }
177}
178
179func TestDeriveReadmeURL(t *testing.T) {
180 tests := []struct {
181 name string
182 sourceURL string
183 branch string
184 want string
185 }{
186 // GitHub
187 {
188 name: "github main",
189 sourceURL: "https://github.com/bigmoves/quickslice",
190 branch: "main",
191 want: "https://raw.githubusercontent.com/bigmoves/quickslice/refs/heads/main/README.md",
192 },
193 {
194 name: "github master",
195 sourceURL: "https://github.com/user/repo",
196 branch: "master",
197 want: "https://raw.githubusercontent.com/user/repo/refs/heads/master/README.md",
198 },
199
200 // GitLab
201 {
202 name: "gitlab main",
203 sourceURL: "https://gitlab.com/user/repo",
204 branch: "main",
205 want: "https://gitlab.com/user/repo/-/raw/main/README.md",
206 },
207 {
208 name: "gitlab nested groups",
209 sourceURL: "https://gitlab.com/group/subgroup/repo",
210 branch: "main",
211 want: "https://gitlab.com/group/subgroup/repo/-/raw/main/README.md",
212 },
213
214 // Tangled
215 {
216 name: "tangled main",
217 sourceURL: "https://tangled.org/evan.jarrett.net/at-container-registry",
218 branch: "main",
219 want: "https://tangled.org/evan.jarrett.net/at-container-registry/raw/main/README.md",
220 },
221 {
222 name: "tangled legacy @ prefix",
223 sourceURL: "https://tangled.org/@user/repo",
224 branch: "main",
225 want: "https://tangled.org/user/repo/raw/main/README.md",
226 },
227
228 // Codeberg
229 {
230 name: "codeberg main",
231 sourceURL: "https://codeberg.org/user/repo",
232 branch: "main",
233 want: "https://codeberg.org/user/repo/raw/branch/main/README.md",
234 },
235
236 // Unsupported
237 {
238 name: "unsupported platform",
239 sourceURL: "https://bitbucket.org/user/repo",
240 branch: "main",
241 want: "",
242 },
243 {
244 name: "empty url",
245 sourceURL: "",
246 branch: "main",
247 want: "",
248 },
249 }
250
251 for _, tt := range tests {
252 t.Run(tt.name, func(t *testing.T) {
253 got := DeriveReadmeURL(tt.sourceURL, tt.branch)
254 if got != tt.want {
255 t.Errorf("DeriveReadmeURL(%q, %q) = %q, want %q", tt.sourceURL, tt.branch, got, tt.want)
256 }
257 })
258 }
259}