1// Copyright 2023 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 version
6
7import (
8	"reflect"
9	"testing"
10)
11
12func TestCompare(t *testing.T) { test2(t, compareTests, "Compare", Compare) }
13
14var compareTests = []testCase2[string, string, int]{
15	{"", "", 0},
16	{"x", "x", 0},
17	{"", "x", 0},
18	{"1", "1.1", 0},
19	{"go1", "go1.1", -1},
20	{"go1.5", "go1.6", -1},
21	{"go1.5", "go1.10", -1},
22	{"go1.6", "go1.6.1", -1},
23	{"go1.19", "go1.19.0", 0},
24	{"go1.19rc1", "go1.19", -1},
25	{"go1.20", "go1.20.0", 0},
26	{"go1.20", "go1.20.0-bigcorp", 0},
27	{"go1.20rc1", "go1.20", -1},
28	{"go1.21", "go1.21.0", -1},
29	{"go1.21", "go1.21.0-bigcorp", -1},
30	{"go1.21", "go1.21rc1", -1},
31	{"go1.21rc1", "go1.21.0", -1},
32	{"go1.6", "go1.19", -1},
33	{"go1.19", "go1.19.1", -1},
34	{"go1.19rc1", "go1.19", -1},
35	{"go1.19rc1", "go1.19", -1},
36	{"go1.19rc1", "go1.19.1", -1},
37	{"go1.19rc1", "go1.19rc2", -1},
38	{"go1.19.0", "go1.19.1", -1},
39	{"go1.19rc1", "go1.19.0", -1},
40	{"go1.19alpha3", "go1.19beta2", -1},
41	{"go1.19beta2", "go1.19rc1", -1},
42	{"go1.1", "go1.99999999999999998", -1},
43	{"go1.99999999999999998", "go1.99999999999999999", -1},
44}
45
46func TestLang(t *testing.T) { test1(t, langTests, "Lang", Lang) }
47
48var langTests = []testCase1[string, string]{
49	{"bad", ""},
50	{"go1.2rc3", "go1.2"},
51	{"go1.2.3", "go1.2"},
52	{"go1.2", "go1.2"},
53	{"go1", "go1"},
54	{"go222", "go222.0"},
55	{"go1.999testmod", "go1.999"},
56}
57
58func TestIsValid(t *testing.T) { test1(t, isValidTests, "IsValid", IsValid) }
59
60var isValidTests = []testCase1[string, bool]{
61	{"", false},
62	{"1.2.3", false},
63	{"go1.2rc3", true},
64	{"go1.2.3", true},
65	{"go1.999testmod", true},
66	{"go1.600+auto", false},
67	{"go1.22", true},
68	{"go1.21.0", true},
69	{"go1.21rc2", true},
70	{"go1.21", true},
71	{"go1.20.0", true},
72	{"go1.20", true},
73	{"go1.19", true},
74	{"go1.3", true},
75	{"go1.2", true},
76	{"go1", true},
77}
78
79type testCase1[In, Out any] struct {
80	in  In
81	out Out
82}
83
84type testCase2[In1, In2, Out any] struct {
85	in1 In1
86	in2 In2
87	out Out
88}
89
90func test1[In, Out any](t *testing.T, tests []testCase1[In, Out], name string, f func(In) Out) {
91	t.Helper()
92	for _, tt := range tests {
93		if out := f(tt.in); !reflect.DeepEqual(out, tt.out) {
94			t.Errorf("%s(%v) = %v, want %v", name, tt.in, out, tt.out)
95		}
96	}
97}
98
99func test2[In1, In2, Out any](t *testing.T, tests []testCase2[In1, In2, Out], name string, f func(In1, In2) Out) {
100	t.Helper()
101	for _, tt := range tests {
102		if out := f(tt.in1, tt.in2); !reflect.DeepEqual(out, tt.out) {
103			t.Errorf("%s(%+v, %+v) = %+v, want %+v", name, tt.in1, tt.in2, out, tt.out)
104		}
105	}
106}
107