1
2
3
4
5 package module
6
7 import (
8 "testing"
9
10 "github.com/go-quicktest/qt"
11 )
12
13 var checkTests = []struct {
14 path string
15 version string
16 ok bool
17 }{
18 {"rsc.io/quote@v0", "0.1.0", false},
19 {"rsc io/quote", "v1.0.0", false},
20
21 {"github.com/go-yaml/yaml@v0", "v0.8.0", true},
22 {"github.com/go-yaml/yaml@v1", "v1.0.0", true},
23 {"github.com/go-yaml/yaml", "v2.0.0", false},
24 {"github.com/go-yaml/yaml@v1", "v2.1.5", false},
25 {"github.com/go-yaml/yaml@v3.0", "v3.0.0", false},
26
27 {"github.com/go-yaml/yaml@v2", "v1.0.0", false},
28 {"github.com/go-yaml/yaml@v2", "v2.0.0", true},
29 {"github.com/go-yaml/yaml@v2", "v2.1.5", true},
30 {"github.com/go-yaml/yaml@v2", "v3.0.0", false},
31
32 {"rsc.io/quote", "v17.0.0", false},
33 }
34
35 func TestCheck(t *testing.T) {
36 for _, tt := range checkTests {
37 err := Check(tt.path, tt.version)
38 if tt.ok && err != nil {
39 t.Errorf("Check(%q, %q) = %v, wanted nil error", tt.path, tt.version, err)
40 } else if !tt.ok && err == nil {
41 t.Errorf("Check(%q, %q) succeeded, wanted error", tt.path, tt.version)
42 }
43 }
44 }
45
46 var checkPathWithoutVersionTests = []struct {
47 path string
48 wantErr string
49 }{{
50 path: "rsc io/quote",
51 wantErr: `invalid char ' '`,
52 }, {
53 path: "foo.com@v0",
54 wantErr: `module path inappropriately contains major version`,
55 }, {
56 path: "foo.com/bar/baz",
57 }}
58
59 func TestCheckPathWithoutVersion(t *testing.T) {
60 for _, test := range checkPathWithoutVersionTests {
61 t.Run(test.path, func(t *testing.T) {
62 err := CheckPathWithoutVersion(test.path)
63 if test.wantErr != "" {
64 qt.Assert(t, qt.ErrorMatches(err, test.wantErr))
65 return
66 }
67 qt.Assert(t, qt.IsNil(err))
68 })
69 }
70 }
71
72 var newVersionTests = []struct {
73 path, vers string
74 wantError string
75 wantPath string
76 wantBasePath string
77 }{{
78 path: "github.com/foo/bar@v0",
79 vers: "v0.1.2",
80 wantPath: "github.com/foo/bar@v0",
81 wantBasePath: "github.com/foo/bar",
82 }, {
83 path: "github.com/foo/bar",
84 vers: "v3.1.2",
85 wantPath: "github.com/foo/bar@v3",
86 wantBasePath: "github.com/foo/bar",
87 }, {
88 path: "github.com/foo/bar@v1",
89 vers: "",
90 wantPath: "github.com/foo/bar@v1",
91 wantBasePath: "github.com/foo/bar",
92 }, {
93 path: "github.com/foo/bar@v1",
94 vers: "v3.1.2",
95 wantError: `mismatched major version suffix in "github.com/foo/bar@v1" \(version v3\.1\.2\)`,
96 }, {
97 path: "github.com/foo/bar@v1",
98 vers: "v3.1",
99 wantError: `version "v3.1" \(of module "github.com/foo/bar@v1"\) is not canonical`,
100 }, {
101 path: "github.com/foo/bar@v1",
102 vers: "v3.10.4+build",
103 wantError: `version "v3.10.4\+build" \(of module "github.com/foo/bar@v1"\) is not canonical`,
104 }, {
105 path: "something/bad@v1",
106 vers: "v1.2.3",
107 wantError: `malformed module path "something/bad@v1": missing dot in first path element`,
108 }, {
109 path: "foo.com/bar",
110 vers: "",
111 wantError: `path "foo.com/bar" has no major version`,
112 }, {
113 path: "x.com",
114 vers: "bad",
115 wantError: `version "bad" \(of module "x.com"\) is not well formed`,
116 }, {
117 path: "local",
118 vers: "",
119 wantPath: "local",
120 wantBasePath: "local",
121 }, {
122 path: "local",
123 vers: "v0.1.2",
124 wantError: `module 'local' cannot have version`,
125 }, {
126 path: "local@v1",
127 vers: "",
128 wantError: `module 'local' cannot have version`,
129 }}
130
131 func TestNewVersion(t *testing.T) {
132 for _, test := range newVersionTests {
133 t.Run(test.path+"@"+test.vers, func(t *testing.T) {
134 v, err := NewVersion(test.path, test.vers)
135 if test.wantError != "" {
136 qt.Assert(t, qt.ErrorMatches(err, test.wantError))
137 return
138 }
139 qt.Assert(t, qt.IsNil(err))
140 qt.Assert(t, qt.Equals(v.Path(), test.wantPath))
141 qt.Assert(t, qt.Equals(v.BasePath(), test.wantBasePath))
142 qt.Assert(t, qt.Equals(v.Version(), test.vers))
143 })
144 }
145 }
146
147 var parseVersionTests = []struct {
148 s string
149 wantError string
150 }{{
151 s: "github.com/foo/bar@v0.1.2",
152 }}
153
154 func TestParseVersion(t *testing.T) {
155 for _, test := range parseVersionTests {
156 t.Run(test.s, func(t *testing.T) {
157 v, err := ParseVersion(test.s)
158 if test.wantError != "" {
159 qt.Assert(t, qt.ErrorMatches(err, test.wantError))
160 return
161 }
162 qt.Assert(t, qt.IsNil(err))
163 qt.Assert(t, qt.Equals(v.String(), test.s))
164 })
165 }
166 }
167
168 var escapeVersionTests = []struct {
169 v string
170 esc string
171 }{
172 {v: "v1.2.3-alpha"},
173 {v: "v3"},
174 {v: "v2.3.1-ABcD", esc: "v2.3.1-!a!bc!d"},
175 }
176
177 func TestEscapeVersion(t *testing.T) {
178 for _, tt := range escapeVersionTests {
179 esc, err := EscapeVersion(tt.v)
180 if err != nil {
181 t.Errorf("EscapeVersion(%q): unexpected error: %v", tt.v, err)
182 continue
183 }
184 want := tt.esc
185 if want == "" {
186 want = tt.v
187 }
188 if esc != want {
189 t.Errorf("EscapeVersion(%q) = %q, want %q", tt.v, esc, want)
190 }
191 }
192 }
193
194 func TestEscapePath(t *testing.T) {
195
196 for _, tt := range checkPathWithoutVersionTests {
197 if tt.wantErr != "" {
198 _, err := EscapePath(tt.path)
199 if err == nil {
200 t.Errorf("EscapePath(%q): succeeded, want error (invalid path)", tt.path)
201 }
202 }
203 }
204 path := "foo.com/bar"
205 esc, err := EscapePath(path)
206 if err != nil {
207 t.Fatal(err)
208 }
209 if esc != path {
210 t.Fatalf("EscapePath(%q) = %q, want %q", path, esc, path)
211 }
212 }
213
214 var parseImportPathTests = []struct {
215 testName string
216 path string
217 want ImportPath
218 wantCanonical string
219 }{{
220 testName: "StdlibLikeWithSlash",
221 path: "stdlib/path",
222 want: ImportPath{
223 Path: "stdlib/path",
224 Qualifier: "path",
225 },
226 }, {
227 testName: "StdlibLikeNoSlash",
228 path: "math",
229 want: ImportPath{
230 Path: "math",
231 Qualifier: "math",
232 },
233 }, {
234 testName: "StdlibLikeExplicitQualifier",
235 path: "stdlib/path:other",
236 want: ImportPath{
237 Path: "stdlib/path",
238 ExplicitQualifier: true,
239 Qualifier: "other",
240 },
241 }, {
242 testName: "StdlibLikeExplicitQualifierNoSlash",
243 path: "math:other",
244 want: ImportPath{
245 Path: "math",
246 ExplicitQualifier: true,
247 Qualifier: "other",
248 },
249 }, {
250 testName: "WithMajorVersion",
251 path: "foo.com/bar@v0",
252 want: ImportPath{
253 Path: "foo.com/bar",
254 Version: "v0",
255 Qualifier: "bar",
256 },
257 }, {
258 testName: "WithMajorVersionNoSlash",
259 path: "main.test@v0",
260 want: ImportPath{
261 Path: "main.test",
262 Version: "v0",
263 Qualifier: "main.test",
264 },
265 }, {
266 testName: "WithMajorVersionAndExplicitQualifier",
267 path: "foo.com/bar@v0:other",
268 want: ImportPath{
269 Path: "foo.com/bar",
270 Version: "v0",
271 ExplicitQualifier: true,
272 Qualifier: "other",
273 },
274 }, {
275 testName: "WithMajorVersionAndNoQualifier",
276 path: "foo.com/bar@v0",
277 want: ImportPath{
278 Path: "foo.com/bar",
279 Version: "v0",
280 Qualifier: "bar",
281 },
282 }, {
283 testName: "WithRedundantQualifier",
284 path: "foo.com/bar@v0:bar",
285 want: ImportPath{
286 Path: "foo.com/bar",
287 Version: "v0",
288 ExplicitQualifier: true,
289 Qualifier: "bar",
290 },
291 wantCanonical: "foo.com/bar@v0",
292 }}
293
294 func TestParseImportPath(t *testing.T) {
295 for _, test := range parseImportPathTests {
296 t.Run(test.testName, func(t *testing.T) {
297 parts := ParseImportPath(test.path)
298 qt.Assert(t, qt.DeepEquals(parts, test.want))
299 qt.Assert(t, qt.Equals(parts.String(), test.path))
300 if test.wantCanonical == "" {
301 test.wantCanonical = test.path
302 }
303 qt.Assert(t, qt.Equals(parts.Canonical().String(), test.wantCanonical))
304 })
305 }
306 }
307
View as plain text