1// Copyright 2018 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package semver 6 7import ( 8 "strings" 9 "testing" 10) 11 12var tests = []struct { 13 in string 14 out string 15}{ 16 {"bad", ""}, 17 {"v1-alpha.beta.gamma", ""}, 18 {"v1-pre", ""}, 19 {"v1+meta", ""}, 20 {"v1-pre+meta", ""}, 21 {"v1.2-pre", ""}, 22 {"v1.2+meta", ""}, 23 {"v1.2-pre+meta", ""}, 24 {"v1.0.0-alpha", "v1.0.0-alpha"}, 25 {"v1.0.0-alpha.1", "v1.0.0-alpha.1"}, 26 {"v1.0.0-alpha.beta", "v1.0.0-alpha.beta"}, 27 {"v1.0.0-beta", "v1.0.0-beta"}, 28 {"v1.0.0-beta.2", "v1.0.0-beta.2"}, 29 {"v1.0.0-beta.11", "v1.0.0-beta.11"}, 30 {"v1.0.0-rc.1", "v1.0.0-rc.1"}, 31 {"v1", "v1.0.0"}, 32 {"v1.0", "v1.0.0"}, 33 {"v1.0.0", "v1.0.0"}, 34 {"v1.2", "v1.2.0"}, 35 {"v1.2.0", "v1.2.0"}, 36 {"v1.2.3-456", "v1.2.3-456"}, 37 {"v1.2.3-456.789", "v1.2.3-456.789"}, 38 {"v1.2.3-456-789", "v1.2.3-456-789"}, 39 {"v1.2.3-456a", "v1.2.3-456a"}, 40 {"v1.2.3-pre", "v1.2.3-pre"}, 41 {"v1.2.3-pre+meta", "v1.2.3-pre"}, 42 {"v1.2.3-pre.1", "v1.2.3-pre.1"}, 43 {"v1.2.3-zzz", "v1.2.3-zzz"}, 44 {"v1.2.3", "v1.2.3"}, 45 {"v1.2.3+meta", "v1.2.3"}, 46 {"v1.2.3+meta-pre", "v1.2.3"}, 47 {"v1.2.3+meta-pre.sha.256a", "v1.2.3"}, 48} 49 50func TestIsValid(t *testing.T) { 51 for _, tt := range tests { 52 ok := IsValid(tt.in) 53 if ok != (tt.out != "") { 54 t.Errorf("IsValid(%q) = %v, want %v", tt.in, ok, !ok) 55 } 56 } 57} 58 59func TestCanonical(t *testing.T) { 60 for _, tt := range tests { 61 out := Canonical(tt.in) 62 if out != tt.out { 63 t.Errorf("Canonical(%q) = %q, want %q", tt.in, out, tt.out) 64 } 65 } 66} 67 68func TestMajor(t *testing.T) { 69 for _, tt := range tests { 70 out := Major(tt.in) 71 want := "" 72 if i := strings.Index(tt.out, "."); i >= 0 { 73 want = tt.out[:i] 74 } 75 if out != want { 76 t.Errorf("Major(%q) = %q, want %q", tt.in, out, want) 77 } 78 } 79} 80 81func TestMajorMinor(t *testing.T) { 82 for _, tt := range tests { 83 out := MajorMinor(tt.in) 84 var want string 85 if tt.out != "" { 86 want = tt.in 87 if i := strings.Index(want, "+"); i >= 0 { 88 want = want[:i] 89 } 90 if i := strings.Index(want, "-"); i >= 0 { 91 want = want[:i] 92 } 93 switch strings.Count(want, ".") { 94 case 0: 95 want += ".0" 96 case 1: 97 // ok 98 case 2: 99 want = want[:strings.LastIndex(want, ".")] 100 } 101 } 102 if out != want { 103 t.Errorf("MajorMinor(%q) = %q, want %q", tt.in, out, want) 104 } 105 } 106} 107 108func TestPrerelease(t *testing.T) { 109 for _, tt := range tests { 110 pre := Prerelease(tt.in) 111 var want string 112 if tt.out != "" { 113 if i := strings.Index(tt.out, "-"); i >= 0 { 114 want = tt.out[i:] 115 } 116 } 117 if pre != want { 118 t.Errorf("Prerelease(%q) = %q, want %q", tt.in, pre, want) 119 } 120 } 121} 122 123func TestBuild(t *testing.T) { 124 for _, tt := range tests { 125 build := Build(tt.in) 126 var want string 127 if tt.out != "" { 128 if i := strings.Index(tt.in, "+"); i >= 0 { 129 want = tt.in[i:] 130 } 131 } 132 if build != want { 133 t.Errorf("Build(%q) = %q, want %q", tt.in, build, want) 134 } 135 } 136} 137 138func TestCompare(t *testing.T) { 139 for i, ti := range tests { 140 for j, tj := range tests { 141 cmp := Compare(ti.in, tj.in) 142 var want int 143 if ti.out == tj.out { 144 want = 0 145 } else if i < j { 146 want = -1 147 } else { 148 want = +1 149 } 150 if cmp != want { 151 t.Errorf("Compare(%q, %q) = %d, want %d", ti.in, tj.in, cmp, want) 152 } 153 } 154 } 155} 156 157func TestMax(t *testing.T) { 158 for i, ti := range tests { 159 for j, tj := range tests { 160 max := Max(ti.in, tj.in) 161 want := Canonical(ti.in) 162 if i < j { 163 want = Canonical(tj.in) 164 } 165 if max != want { 166 t.Errorf("Max(%q, %q) = %q, want %q", ti.in, tj.in, max, want) 167 } 168 } 169 } 170} 171 172var ( 173 v1 = "v1.0.0+metadata-dash" 174 v2 = "v1.0.0+metadata-dash1" 175) 176 177func BenchmarkCompare(b *testing.B) { 178 for i := 0; i < b.N; i++ { 179 if Compare(v1, v2) != 0 { 180 b.Fatalf("bad compare") 181 } 182 } 183} 184