1 package semver
2
3 import (
4 "testing"
5 )
6
7 func prstr(s string) PRVersion {
8 return PRVersion{s, 0, false}
9 }
10
11 func prnum(i uint64) PRVersion {
12 return PRVersion{"", i, true}
13 }
14
15 type formatTest struct {
16 v Version
17 result string
18 }
19
20 var formatTests = []formatTest{
21 {Version{1, 2, 3, nil, nil}, "1.2.3"},
22 {Version{0, 0, 1, nil, nil}, "0.0.1"},
23 {Version{0, 0, 1, []PRVersion{prstr("alpha"), prstr("preview")}, []string{"123", "456"}}, "0.0.1-alpha.preview+123.456"},
24 {Version{1, 2, 3, []PRVersion{prstr("alpha"), prnum(1)}, []string{"123", "456"}}, "1.2.3-alpha.1+123.456"},
25 {Version{1, 2, 3, []PRVersion{prstr("alpha"), prnum(1)}, nil}, "1.2.3-alpha.1"},
26 {Version{1, 2, 3, nil, []string{"123", "456"}}, "1.2.3+123.456"},
27
28 {Version{1, 2, 3, []PRVersion{prstr("alpha"), prstr("b-eta")}, []string{"123", "b-uild"}}, "1.2.3-alpha.b-eta+123.b-uild"},
29 {Version{1, 2, 3, nil, []string{"123", "b-uild"}}, "1.2.3+123.b-uild"},
30 {Version{1, 2, 3, []PRVersion{prstr("alpha"), prstr("b-eta")}, nil}, "1.2.3-alpha.b-eta"},
31 }
32
33 var tolerantFormatTests = []formatTest{
34 {Version{1, 2, 3, nil, nil}, "v1.2.3"},
35 {Version{1, 2, 3, nil, nil}, " 1.2.3 "},
36 {Version{1, 2, 0, nil, nil}, "1.2"},
37 {Version{1, 0, 0, nil, nil}, "1"},
38 }
39
40 func TestStringer(t *testing.T) {
41 for _, test := range formatTests {
42 if res := test.v.String(); res != test.result {
43 t.Errorf("Stringer, expected %q but got %q", test.result, res)
44 }
45 }
46 }
47
48 func TestParse(t *testing.T) {
49 for _, test := range formatTests {
50 if v, err := Parse(test.result); err != nil {
51 t.Errorf("Error parsing %q: %q", test.result, err)
52 } else if comp := v.Compare(test.v); comp != 0 {
53 t.Errorf("Parsing, expected %q but got %q, comp: %d ", test.v, v, comp)
54 } else if err := v.Validate(); err != nil {
55 t.Errorf("Error validating parsed version %q: %q", test.v, err)
56 }
57 }
58 }
59
60 func TestParseTolerant(t *testing.T) {
61 for _, test := range tolerantFormatTests {
62 if v, err := ParseTolerant(test.result); err != nil {
63 t.Errorf("Error parsing %q: %q", test.result, err)
64 } else if comp := v.Compare(test.v); comp != 0 {
65 t.Errorf("Parsing, expected %q but got %q, comp: %d ", test.v, v, comp)
66 } else if err := v.Validate(); err != nil {
67 t.Errorf("Error validating parsed version %q: %q", test.v, err)
68 }
69 }
70 }
71
72 func TestMustParse(t *testing.T) {
73 _ = MustParse("32.2.1-alpha")
74 }
75
76 func TestMustParse_panic(t *testing.T) {
77 defer func() {
78 if recover() == nil {
79 t.Errorf("Should have panicked")
80 }
81 }()
82 _ = MustParse("invalid version")
83 }
84
85 func TestValidate(t *testing.T) {
86 for _, test := range formatTests {
87 if err := test.v.Validate(); err != nil {
88 t.Errorf("Error validating %q: %q", test.v, err)
89 }
90 }
91 }
92
93 type compareTest struct {
94 v1 Version
95 v2 Version
96 result int
97 }
98
99 var compareTests = []compareTest{
100 {Version{1, 0, 0, nil, nil}, Version{1, 0, 0, nil, nil}, 0},
101 {Version{2, 0, 0, nil, nil}, Version{1, 0, 0, nil, nil}, 1},
102 {Version{0, 1, 0, nil, nil}, Version{0, 1, 0, nil, nil}, 0},
103 {Version{0, 2, 0, nil, nil}, Version{0, 1, 0, nil, nil}, 1},
104 {Version{0, 0, 1, nil, nil}, Version{0, 0, 1, nil, nil}, 0},
105 {Version{0, 0, 2, nil, nil}, Version{0, 0, 1, nil, nil}, 1},
106 {Version{1, 2, 3, nil, nil}, Version{1, 2, 3, nil, nil}, 0},
107 {Version{2, 2, 4, nil, nil}, Version{1, 2, 4, nil, nil}, 1},
108 {Version{1, 3, 3, nil, nil}, Version{1, 2, 3, nil, nil}, 1},
109 {Version{1, 2, 4, nil, nil}, Version{1, 2, 3, nil, nil}, 1},
110
111
112 {Version{1, 0, 0, nil, nil}, Version{2, 0, 0, nil, nil}, -1},
113 {Version{2, 0, 0, nil, nil}, Version{2, 1, 0, nil, nil}, -1},
114 {Version{2, 1, 0, nil, nil}, Version{2, 1, 1, nil, nil}, -1},
115
116
117 {Version{1, 0, 0, nil, nil}, Version{1, 0, 0, []PRVersion{prstr("alpha")}, nil}, 1},
118 {Version{1, 0, 0, []PRVersion{prstr("alpha")}, nil}, Version{1, 0, 0, []PRVersion{prstr("alpha"), prnum(1)}, nil}, -1},
119 {Version{1, 0, 0, []PRVersion{prstr("alpha"), prnum(1)}, nil}, Version{1, 0, 0, []PRVersion{prstr("alpha"), prstr("beta")}, nil}, -1},
120 {Version{1, 0, 0, []PRVersion{prstr("alpha"), prstr("beta")}, nil}, Version{1, 0, 0, []PRVersion{prstr("beta")}, nil}, -1},
121 {Version{1, 0, 0, []PRVersion{prstr("beta")}, nil}, Version{1, 0, 0, []PRVersion{prstr("beta"), prnum(2)}, nil}, -1},
122 {Version{1, 0, 0, []PRVersion{prstr("beta"), prnum(2)}, nil}, Version{1, 0, 0, []PRVersion{prstr("beta"), prnum(11)}, nil}, -1},
123 {Version{1, 0, 0, []PRVersion{prstr("beta"), prnum(11)}, nil}, Version{1, 0, 0, []PRVersion{prstr("rc"), prnum(1)}, nil}, -1},
124 {Version{1, 0, 0, []PRVersion{prstr("rc"), prnum(1)}, nil}, Version{1, 0, 0, nil, nil}, -1},
125
126
127 {Version{1, 0, 0, nil, []string{"1", "2", "3"}}, Version{1, 0, 0, nil, nil}, 0},
128 }
129
130 func TestCompare(t *testing.T) {
131 for _, test := range compareTests {
132 if res := test.v1.Compare(test.v2); res != test.result {
133 t.Errorf("Comparing %q : %q, expected %d but got %d", test.v1, test.v2, test.result, res)
134 }
135
136 if res := test.v2.Compare(test.v1); res != -test.result {
137 t.Errorf("Comparing %q : %q, expected %d but got %d", test.v2, test.v1, -test.result, res)
138 }
139 }
140 }
141
142 type wrongformatTest struct {
143 v *Version
144 str string
145 }
146
147 var wrongformatTests = []wrongformatTest{
148 {nil, ""},
149 {nil, "."},
150 {nil, "1."},
151 {nil, ".1"},
152 {nil, "a.b.c"},
153 {nil, "1.a.b"},
154 {nil, "1.1.a"},
155 {nil, "1.a.1"},
156 {nil, "a.1.1"},
157 {nil, ".."},
158 {nil, "1.."},
159 {nil, "1.1."},
160 {nil, "1..1"},
161 {nil, "1.1.+123"},
162 {nil, "1.1.-beta"},
163 {nil, "-1.1.1"},
164 {nil, "1.-1.1"},
165 {nil, "1.1.-1"},
166
167 {nil, "20000000000000000000.1.1"},
168 {nil, "1.20000000000000000000.1"},
169 {nil, "1.1.20000000000000000000"},
170 {nil, "1.1.1-20000000000000000000"},
171
172 {nil, "01.1.1"},
173 {nil, "001.1.1"},
174 {nil, "1.01.1"},
175 {nil, "1.001.1"},
176 {nil, "1.1.01"},
177 {nil, "1.1.001"},
178 {nil, "1.1.1-01"},
179 {nil, "1.1.1-001"},
180 {nil, "1.1.1-beta.01"},
181 {nil, "1.1.1-beta.001"},
182 {&Version{0, 0, 0, []PRVersion{prstr("!")}, nil}, "0.0.0-!"},
183 {&Version{0, 0, 0, nil, []string{"!"}}, "0.0.0+!"},
184
185 {&Version{0, 0, 0, []PRVersion{prstr(""), prstr("alpha")}, nil}, "0.0.0-.alpha"},
186
187 {&Version{0, 0, 0, []PRVersion{prstr("alpha")}, []string{""}}, "0.0.0-alpha+"},
188 {&Version{0, 0, 0, []PRVersion{prstr("alpha")}, []string{"test", ""}}, "0.0.0-alpha+test."},
189 }
190
191 func TestWrongFormat(t *testing.T) {
192 for _, test := range wrongformatTests {
193
194 if res, err := Parse(test.str); err == nil {
195 t.Errorf("Parsing wrong format version %q, expected error but got %q", test.str, res)
196 }
197
198 if test.v != nil {
199 if err := test.v.Validate(); err == nil {
200 t.Errorf("Validating wrong format version %q (%q), expected error", test.v, test.str)
201 }
202 }
203 }
204 }
205
206 var wrongTolerantFormatTests = []wrongformatTest{
207 {nil, "1.0+abc"},
208 {nil, "1.0-rc.1"},
209 }
210
211 func TestWrongTolerantFormat(t *testing.T) {
212 for _, test := range wrongTolerantFormatTests {
213 if res, err := ParseTolerant(test.str); err == nil {
214 t.Errorf("Parsing wrong format version %q, expected error but got %q", test.str, res)
215 }
216 }
217 }
218
219 func TestCompareHelper(t *testing.T) {
220 v := Version{1, 0, 0, []PRVersion{prstr("alpha")}, nil}
221 v1 := Version{1, 0, 0, nil, nil}
222 if !v.EQ(v) {
223 t.Errorf("%q should be equal to %q", v, v)
224 }
225 if !v.Equals(v) {
226 t.Errorf("%q should be equal to %q", v, v)
227 }
228 if !v1.NE(v) {
229 t.Errorf("%q should not be equal to %q", v1, v)
230 }
231 if !v.GTE(v) {
232 t.Errorf("%q should be greater than or equal to %q", v, v)
233 }
234 if !v.LTE(v) {
235 t.Errorf("%q should be less than or equal to %q", v, v)
236 }
237 if !v.LT(v1) {
238 t.Errorf("%q should be less than %q", v, v1)
239 }
240 if !v.LTE(v1) {
241 t.Errorf("%q should be less than or equal %q", v, v1)
242 }
243 if !v.LE(v1) {
244 t.Errorf("%q should be less than or equal %q", v, v1)
245 }
246 if !v1.GT(v) {
247 t.Errorf("%q should be greater than %q", v1, v)
248 }
249 if !v1.GTE(v) {
250 t.Errorf("%q should be greater than or equal %q", v1, v)
251 }
252 if !v1.GE(v) {
253 t.Errorf("%q should be greater than or equal %q", v1, v)
254 }
255 }
256
257 func TestPreReleaseVersions(t *testing.T) {
258 p1, err := NewPRVersion("123")
259 if !p1.IsNumeric() {
260 t.Errorf("Expected numeric prversion, got %q", p1)
261 }
262 if p1.VersionNum != 123 {
263 t.Error("Wrong prversion number")
264 }
265 if err != nil {
266 t.Errorf("Not expected error %q", err)
267 }
268 p2, err := NewPRVersion("alpha")
269 if p2.IsNumeric() {
270 t.Errorf("Expected non-numeric prversion, got %q", p2)
271 }
272 if p2.VersionStr != "alpha" {
273 t.Error("Wrong prversion string")
274 }
275 if err != nil {
276 t.Errorf("Not expected error %q", err)
277 }
278 }
279
280 func TestBuildMetaDataVersions(t *testing.T) {
281 _, err := NewBuildVersion("123")
282 if err != nil {
283 t.Errorf("Unexpected error %q", err)
284 }
285
286 _, err = NewBuildVersion("build")
287 if err != nil {
288 t.Errorf("Unexpected error %q", err)
289 }
290
291 _, err = NewBuildVersion("test?")
292 if err == nil {
293 t.Error("Expected error, got none")
294 }
295
296 _, err = NewBuildVersion("")
297 if err == nil {
298 t.Error("Expected error, got none")
299 }
300 }
301
302 func TestNewHelper(t *testing.T) {
303 v, err := New("1.2.3")
304 if err != nil {
305 t.Fatalf("Unexpected error %q", err)
306 }
307
308
309 if v == nil {
310 t.Fatal("Version is nil")
311 }
312 if v.Compare(Version{1, 2, 3, nil, nil}) != 0 {
313 t.Fatal("Unexpected comparison problem")
314 }
315 }
316
317 func TestMakeHelper(t *testing.T) {
318 v, err := Make("1.2.3")
319 if err != nil {
320 t.Fatalf("Unexpected error %q", err)
321 }
322 if v.Compare(Version{1, 2, 3, nil, nil}) != 0 {
323 t.Fatal("Unexpected comparison problem")
324 }
325 }
326
327 func BenchmarkParseSimple(b *testing.B) {
328 const VERSION = "0.0.1"
329 b.ReportAllocs()
330 b.ResetTimer()
331 for n := 0; n < b.N; n++ {
332 Parse(VERSION)
333 }
334 }
335
336 func BenchmarkParseComplex(b *testing.B) {
337 const VERSION = "0.0.1-alpha.preview+123.456"
338 b.ReportAllocs()
339 b.ResetTimer()
340 for n := 0; n < b.N; n++ {
341 Parse(VERSION)
342 }
343 }
344
345 func BenchmarkParseAverage(b *testing.B) {
346 l := len(formatTests)
347 b.ReportAllocs()
348 b.ResetTimer()
349 for n := 0; n < b.N; n++ {
350 Parse(formatTests[n%l].result)
351 }
352 }
353
354 func BenchmarkParseTolerantAverage(b *testing.B) {
355 l := len(tolerantFormatTests)
356 b.ReportAllocs()
357 b.ResetTimer()
358 for n := 0; n < b.N; n++ {
359 ParseTolerant(tolerantFormatTests[n%l].result)
360 }
361 }
362
363 func BenchmarkStringSimple(b *testing.B) {
364 const VERSION = "0.0.1"
365 v, _ := Parse(VERSION)
366 b.ReportAllocs()
367 b.ResetTimer()
368 for n := 0; n < b.N; n++ {
369 v.String()
370 }
371 }
372
373 func BenchmarkStringLarger(b *testing.B) {
374 const VERSION = "11.15.2012"
375 v, _ := Parse(VERSION)
376 b.ReportAllocs()
377 b.ResetTimer()
378 for n := 0; n < b.N; n++ {
379 v.String()
380 }
381 }
382
383 func BenchmarkStringComplex(b *testing.B) {
384 const VERSION = "0.0.1-alpha.preview+123.456"
385 v, _ := Parse(VERSION)
386 b.ReportAllocs()
387 b.ResetTimer()
388 for n := 0; n < b.N; n++ {
389 v.String()
390 }
391 }
392
393 func BenchmarkStringAverage(b *testing.B) {
394 l := len(formatTests)
395 b.ReportAllocs()
396 b.ResetTimer()
397 for n := 0; n < b.N; n++ {
398 formatTests[n%l].v.String()
399 }
400 }
401
402 func BenchmarkValidateSimple(b *testing.B) {
403 const VERSION = "0.0.1"
404 v, _ := Parse(VERSION)
405 b.ReportAllocs()
406 b.ResetTimer()
407 for n := 0; n < b.N; n++ {
408 v.Validate()
409 }
410 }
411
412 func BenchmarkValidateComplex(b *testing.B) {
413 const VERSION = "0.0.1-alpha.preview+123.456"
414 v, _ := Parse(VERSION)
415 b.ReportAllocs()
416 b.ResetTimer()
417 for n := 0; n < b.N; n++ {
418 v.Validate()
419 }
420 }
421
422 func BenchmarkValidateAverage(b *testing.B) {
423 l := len(formatTests)
424 b.ReportAllocs()
425 b.ResetTimer()
426 for n := 0; n < b.N; n++ {
427 formatTests[n%l].v.Validate()
428 }
429 }
430
431 func BenchmarkCompareSimple(b *testing.B) {
432 const VERSION = "0.0.1"
433 v, _ := Parse(VERSION)
434 b.ReportAllocs()
435 b.ResetTimer()
436 for n := 0; n < b.N; n++ {
437 v.Compare(v)
438 }
439 }
440
441 func BenchmarkCompareComplex(b *testing.B) {
442 const VERSION = "0.0.1-alpha.preview+123.456"
443 v, _ := Parse(VERSION)
444 b.ReportAllocs()
445 b.ResetTimer()
446 for n := 0; n < b.N; n++ {
447 v.Compare(v)
448 }
449 }
450
451 func BenchmarkCompareAverage(b *testing.B) {
452 l := len(compareTests)
453 b.ReportAllocs()
454 b.ResetTimer()
455 for n := 0; n < b.N; n++ {
456 compareTests[n%l].v1.Compare((compareTests[n%l].v2))
457 }
458 }
459
View as plain text