golang.org/x/build@v0.0.0-20240506185731-218518f32b70/maintner/maintnerd/maintapi/version/version_test.go (about) 1 // Copyright 2019 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 5 package version 6 7 import ( 8 "strconv" 9 "testing" 10 "testing/quick" 11 ) 12 13 func TestParseTag(t *testing.T) { 14 tests := []struct { 15 tagName string 16 wantMajor, wantMinor, wantPatch int 17 wantOK bool 18 }{ 19 {"go1", 1, 0, 0, true}, 20 {"go1.2", 1, 2, 0, true}, 21 {"go1.2.0", 1, 2, 0, true}, 22 {"go1.2.3", 1, 2, 3, true}, 23 {"go23.45.67", 23, 45, 67, true}, 24 {"not-go", 0, 0, 0, false}, 25 {"go", 0, 0, 0, false}, 26 {"go.", 0, 0, 0, false}, 27 {"go1.", 0, 0, 0, false}, 28 {"go1-bad", 0, 0, 0, false}, 29 {"go1.2.", 0, 0, 0, false}, 30 {"go1.2-bad", 0, 0, 0, false}, 31 {"go1.2.3.", 0, 0, 0, false}, 32 {"go1.2.3-bad", 0, 0, 0, false}, 33 {"go1.2.3.4", 0, 0, 0, false}, 34 {"go0.0.0", 0, 0, 0, false}, 35 {"go-1", 0, 0, 0, false}, 36 {"go1.-2", 0, 0, 0, false}, 37 {"go1.2.-3", 0, 0, 0, false}, 38 {"go+1", 0, 0, 0, false}, 39 {"go01", 0, 0, 0, false}, 40 {"go001", 0, 0, 0, false}, 41 {"go1000", 0, 0, 0, false}, 42 {"go00", 0, 0, 0, false}, 43 {"go00.2", 0, 0, 0, false}, 44 {"go00.2.3", 0, 0, 0, false}, 45 {"go1.00", 0, 0, 0, false}, 46 {"go1.00.0", 0, 0, 0, false}, 47 {"go1.00.3", 0, 0, 0, false}, 48 {"go1.2.00", 0, 0, 0, false}, 49 } 50 for i, tt := range tests { 51 major, minor, patch, ok := ParseTag(tt.tagName) 52 if got, want := ok, tt.wantOK; got != want { 53 t.Errorf("#%d %q: got ok = %v; want %v", i, tt.tagName, got, want) 54 continue 55 } 56 if !tt.wantOK { 57 continue 58 } 59 if got, want := major, tt.wantMajor; got != want { 60 t.Errorf("#%d %q: got major = %d; want %d", i, tt.tagName, got, want) 61 } 62 if got, want := minor, tt.wantMinor; got != want { 63 t.Errorf("#%d %q: got minor = %d; want %d", i, tt.tagName, got, want) 64 } 65 if got, want := patch, tt.wantPatch; got != want { 66 t.Errorf("#%d %q: got patch = %d; want %d", i, tt.tagName, got, want) 67 } 68 } 69 } 70 71 func TestParseReleaseBranch(t *testing.T) { 72 tests := []struct { 73 branchName string 74 wantMajor, wantMinor int 75 wantOK bool 76 }{ 77 {"release-branch.go1", 1, 0, true}, 78 {"release-branch.go1.2", 1, 2, true}, 79 {"release-branch.go23.45", 23, 45, true}, 80 {"not-release-branch", 0, 0, false}, 81 {"release-branch.go", 0, 0, false}, 82 {"release-branch.go.", 0, 0, false}, 83 {"release-branch.go1.", 0, 0, false}, 84 {"release-branch.go1-bad", 0, 0, false}, 85 {"release-branch.go1.2.", 0, 0, false}, 86 {"release-branch.go1.2-bad", 0, 0, false}, 87 {"release-branch.go1.2.3", 0, 0, false}, 88 {"release-branch.go0.0", 0, 0, false}, 89 {"release-branch.go-1", 0, 0, false}, 90 {"release-branch.go1.-2", 0, 0, false}, 91 {"release-branch.go+1", 0, 0, false}, 92 {"release-branch.go01", 0, 0, false}, 93 {"release-branch.go001", 0, 0, false}, 94 {"release-branch.go1000", 0, 0, false}, 95 {"release-branch.go1.0", 0, 0, false}, 96 {"release-branch.go00", 0, 0, false}, 97 {"release-branch.go00.2", 0, 0, false}, 98 {"release-branch.go1.00", 0, 0, false}, 99 } 100 for i, tt := range tests { 101 major, minor, ok := ParseReleaseBranch(tt.branchName) 102 if got, want := ok, tt.wantOK; got != want { 103 t.Errorf("#%d %q: got ok = %v; want %v", i, tt.branchName, got, want) 104 continue 105 } 106 if !tt.wantOK { 107 continue 108 } 109 if got, want := major, tt.wantMajor; got != want { 110 t.Errorf("#%d %q: got major = %d; want %d", i, tt.branchName, got, want) 111 } 112 if got, want := minor, tt.wantMinor; got != want { 113 t.Errorf("#%d %q: got minor = %d; want %d", i, tt.branchName, got, want) 114 } 115 } 116 } 117 118 func TestParse0To999(t *testing.T) { 119 // The only accepted inputs are numbers in [0, 999] range 120 // in canonical string form. All other input should be rejected. 121 // Build a complete map of inputs to answers. 122 var golden = make(map[string]int) // input -> output 123 for n := 0; n <= 999; n++ { 124 golden[strconv.Itoa(n)] = n 125 } 126 127 // Numbers in [0, 999] range should be accepted. 128 for in, want := range golden { 129 got, ok := parse0To999(in) 130 if !ok { 131 t.Errorf("parse0To999(%q): got ok = false; want true", in) 132 continue 133 } 134 if got != want { 135 t.Errorf("parse0To999(%q): got n = %d; want %d", in, got, want) 136 } 137 } 138 139 // All other numbers should be rejected. 140 ints := func(x int) bool { 141 gotN, gotOK := parse0To999(strconv.Itoa(x)) 142 wantN, wantOK := golden[strconv.Itoa(x)] 143 return gotOK == wantOK && gotN == wantN 144 } 145 if err := quick.Check(ints, nil); err != nil { 146 t.Error(err) 147 } 148 149 // All other strings should be rejected. 150 strings := func(x string) bool { 151 gotN, gotOK := parse0To999(x) 152 wantN, wantOK := golden[x] 153 return gotOK == wantOK && gotN == wantN 154 } 155 if err := quick.Check(strings, nil); err != nil { 156 t.Error(err) 157 } 158 } 159 160 func TestAllocs(t *testing.T) { 161 got := testing.AllocsPerRun(1000, func() { 162 ParseReleaseBranch("release-branch.go1.5") 163 }) 164 if got > 0 { 165 t.Fatalf("unexpected %v allocation(s)", got) 166 } 167 } 168 169 func TestGo1PointX(t *testing.T) { 170 tests := []struct { 171 goVer string 172 wantX int 173 }{ 174 {"go1.9", 9}, 175 {"go1.16beta1", 16}, 176 {"go1.16rc1", 16}, 177 {"go1.16", 16}, 178 {"go1.16.1", 16}, 179 } 180 for _, tt := range tests { 181 x, ok := Go1PointX(tt.goVer) 182 if !ok || x != tt.wantX { 183 t.Errorf("Go1PointX(%q) = %v, %v, want %v, true", tt.goVer, x, ok, tt.wantX) 184 } 185 } 186 }