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 gover 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", -1}, 19 {"1.5", "1.6", -1}, 20 {"1.5", "1.10", -1}, 21 {"1.6", "1.6.1", -1}, 22 {"1.19", "1.19.0", 0}, 23 {"1.19rc1", "1.19", -1}, 24 {"1.20", "1.20.0", 0}, 25 {"1.20rc1", "1.20", -1}, 26 {"1.21", "1.21.0", -1}, 27 {"1.21", "1.21rc1", -1}, 28 {"1.21rc1", "1.21.0", -1}, 29 {"1.6", "1.19", -1}, 30 {"1.19", "1.19.1", -1}, 31 {"1.19rc1", "1.19", -1}, 32 {"1.19rc1", "1.19.1", -1}, 33 {"1.19rc1", "1.19rc2", -1}, 34 {"1.19.0", "1.19.1", -1}, 35 {"1.19rc1", "1.19.0", -1}, 36 {"1.19alpha3", "1.19beta2", -1}, 37 {"1.19beta2", "1.19rc1", -1}, 38 {"1.1", "1.99999999999999998", -1}, 39 {"1.99999999999999998", "1.99999999999999999", -1}, 40} 41 42func TestParse(t *testing.T) { test1(t, parseTests, "Parse", Parse) } 43 44var parseTests = []testCase1[string, Version]{ 45 {"1", Version{"1", "0", "0", "", ""}}, 46 {"1.2", Version{"1", "2", "0", "", ""}}, 47 {"1.2.3", Version{"1", "2", "3", "", ""}}, 48 {"1.2rc3", Version{"1", "2", "", "rc", "3"}}, 49 {"1.20", Version{"1", "20", "0", "", ""}}, 50 {"1.21", Version{"1", "21", "", "", ""}}, 51 {"1.21rc3", Version{"1", "21", "", "rc", "3"}}, 52 {"1.21.0", Version{"1", "21", "0", "", ""}}, 53 {"1.24", Version{"1", "24", "", "", ""}}, 54 {"1.24rc3", Version{"1", "24", "", "rc", "3"}}, 55 {"1.24.0", Version{"1", "24", "0", "", ""}}, 56 {"1.999testmod", Version{"1", "999", "", "testmod", ""}}, 57 {"1.99999999999999999", Version{"1", "99999999999999999", "", "", ""}}, 58} 59 60func TestLang(t *testing.T) { test1(t, langTests, "Lang", Lang) } 61 62var langTests = []testCase1[string, string]{ 63 {"1.2rc3", "1.2"}, 64 {"1.2.3", "1.2"}, 65 {"1.2", "1.2"}, 66 {"1", "1"}, 67 {"1.999testmod", "1.999"}, 68} 69 70func TestIsLang(t *testing.T) { test1(t, isLangTests, "IsLang", IsLang) } 71 72var isLangTests = []testCase1[string, bool]{ 73 {"1.2rc3", false}, 74 {"1.2.3", false}, 75 {"1.999testmod", false}, 76 {"1.22", true}, 77 {"1.21", true}, 78 {"1.20", false}, // == 1.20.0 79 {"1.19", false}, // == 1.20.0 80 {"1.3", false}, // == 1.3.0 81 {"1.2", false}, // == 1.2.0 82 {"1", false}, // == 1.0.0 83} 84 85func TestIsValid(t *testing.T) { test1(t, isValidTests, "IsValid", IsValid) } 86 87var isValidTests = []testCase1[string, bool]{ 88 {"1.2rc3", true}, 89 {"1.2.3", true}, 90 {"1.999testmod", true}, 91 {"1.600+auto", false}, 92 {"1.22", true}, 93 {"1.21.0", true}, 94 {"1.21rc2", true}, 95 {"1.21", true}, 96 {"1.20.0", true}, 97 {"1.20", true}, 98 {"1.19", true}, 99 {"1.3", true}, 100 {"1.2", true}, 101 {"1", true}, 102} 103 104type testCase1[In, Out any] struct { 105 in In 106 out Out 107} 108 109type testCase2[In1, In2, Out any] struct { 110 in1 In1 111 in2 In2 112 out Out 113} 114 115type testCase3[In1, In2, In3, Out any] struct { 116 in1 In1 117 in2 In2 118 in3 In3 119 out Out 120} 121 122func test1[In, Out any](t *testing.T, tests []testCase1[In, Out], name string, f func(In) Out) { 123 t.Helper() 124 for _, tt := range tests { 125 if out := f(tt.in); !reflect.DeepEqual(out, tt.out) { 126 t.Errorf("%s(%v) = %v, want %v", name, tt.in, out, tt.out) 127 } 128 } 129} 130 131func test2[In1, In2, Out any](t *testing.T, tests []testCase2[In1, In2, Out], name string, f func(In1, In2) Out) { 132 t.Helper() 133 for _, tt := range tests { 134 if out := f(tt.in1, tt.in2); !reflect.DeepEqual(out, tt.out) { 135 t.Errorf("%s(%+v, %+v) = %+v, want %+v", name, tt.in1, tt.in2, out, tt.out) 136 } 137 } 138} 139