semver_test.gno
3.01 Kb · 106 lines
1package semver
2
3import (
4 "testing"
5
6 "gno.land/p/nt/uassert/v0"
7)
8
9func TestParse(t *testing.T) {
10 cases := []struct {
11 in string
12 ok bool
13 major int
14 minor int
15 patch int
16 npre int
17 build string
18 }{
19 {"1.2.3", true, 1, 2, 3, 0, ""},
20 {"v1.2.3", true, 1, 2, 3, 0, ""},
21 {"1.0.0-alpha", true, 1, 0, 0, 1, ""},
22 {"1.0.0-alpha.1", true, 1, 0, 0, 2, ""},
23 {"2.0.0+build.5", true, 2, 0, 0, 0, "build.5"},
24 {"1.0.0-rc.1+ci.7", true, 1, 0, 0, 2, "ci.7"},
25 {"1.2", false, 0, 0, 0, 0, ""},
26 {"1.2.3.4", false, 0, 0, 0, 0, ""},
27 {"1.2.x", false, 0, 0, 0, 0, ""},
28 {"01.2.3", false, 0, 0, 0, 0, ""},
29 {"1.0.0-", false, 0, 0, 0, 0, ""},
30 {"", false, 0, 0, 0, 0, ""},
31 }
32 for _, c := range cases {
33 v, err := Parse(c.in)
34 if !c.ok {
35 uassert.Error(t, err, "expected error for "+c.in)
36 continue
37 }
38 uassert.NoError(t, err, "unexpected error for "+c.in)
39 uassert.Equal(t, c.major, v.Major, "major "+c.in)
40 uassert.Equal(t, c.minor, v.Minor, "minor "+c.in)
41 uassert.Equal(t, c.patch, v.Patch, "patch "+c.in)
42 uassert.Equal(t, c.npre, len(v.Pre), "pre count "+c.in)
43 uassert.Equal(t, c.build, v.Build, "build "+c.in)
44 }
45}
46
47func TestCompare(t *testing.T) {
48 cases := []struct {
49 a, b string
50 want int
51 }{
52 // numeric fields compare numerically, not lexically
53 {"1.2.3", "1.2.10", -1},
54 {"1.2.10", "1.2.3", 1},
55 {"1.0.0", "1.0.0", 0},
56 {"2.0.0", "1.9.9", 1},
57 {"1.1.0", "1.0.9", 1},
58 // pre-release < release
59 {"1.0.0-alpha", "1.0.0", -1},
60 {"1.0.0", "1.0.0-alpha", 1},
61 {"1.0.0-rc.1", "1.0.0", -1},
62 // pre-release ordering per SemVer §11 spec example
63 {"1.0.0-alpha", "1.0.0-alpha.1", -1},
64 {"1.0.0-alpha.1", "1.0.0-alpha.beta", -1},
65 {"1.0.0-alpha.beta", "1.0.0-beta", -1},
66 {"1.0.0-beta", "1.0.0-beta.2", -1},
67 {"1.0.0-beta.2", "1.0.0-beta.11", -1},
68 {"1.0.0-beta.11", "1.0.0-rc.1", -1},
69 // build metadata does not affect precedence
70 {"1.0.0", "1.0.0+build.99", 0},
71 {"1.0.0+a", "1.0.0+b", 0},
72 // invalid inputs sort last, equal to each other
73 {"nope", "1.0.0", 1},
74 {"1.0.0", "nope", -1},
75 {"nope", "still-bad", 0},
76 }
77 for _, c := range cases {
78 got := Compare(c.a, c.b)
79 uassert.Equal(t, c.want, got, c.a+" vs "+c.b)
80 }
81}
82
83func TestComparePreHelper(t *testing.T) {
84 uassert.Equal(t, 0, comparePre(nil, nil), "both empty")
85 uassert.Equal(t, 1, comparePre(nil, []string{"alpha"}), "release > prerelease")
86 uassert.Equal(t, -1, comparePre([]string{"alpha"}, nil), "prerelease < release")
87 uassert.Equal(t, -1, comparePre([]string{"1"}, []string{"alpha"}), "numeric id < alnum id")
88 uassert.Equal(t, -1, comparePre([]string{"alpha"}, []string{"alpha", "1"}), "shorter < longer prefix")
89}
90
91func TestParseNumHelper(t *testing.T) {
92 n, ok := parseNum("0")
93 uassert.True(t, ok, "0 is valid")
94 uassert.Equal(t, 0, n, "0 value")
95
96 n, ok = parseNum("123")
97 uassert.True(t, ok, "123 valid")
98 uassert.Equal(t, 123, n, "123 value")
99
100 _, ok = parseNum("00")
101 uassert.False(t, ok, "leading zero invalid")
102 _, ok = parseNum("12a")
103 uassert.False(t, ok, "non-digit invalid")
104 _, ok = parseNum("")
105 uassert.False(t, ok, "empty invalid")
106}