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