github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/cmd/stringer/golden_test.go (about) 1 // Copyright 2014 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 // This file contains simple golden tests for various examples. 6 // Besides validating the results when the implementation changes, 7 // it provides a way to look at the generated code without having 8 // to execute the print statements in one's head. 9 10 package main 11 12 import ( 13 "strings" 14 "testing" 15 ) 16 17 // Golden represents a test case. 18 type Golden struct { 19 name string 20 input string // input; the package clause is provided when running the test. 21 output string // exected output. 22 } 23 24 var golden = []Golden{ 25 {"day", day_in, day_out}, 26 {"offset", offset_in, offset_out}, 27 {"gap", gap_in, gap_out}, 28 {"num", num_in, num_out}, 29 {"unum", unum_in, unum_out}, 30 {"prime", prime_in, prime_out}, 31 } 32 33 // Each example starts with "type XXX [u]int", with a single space separating them. 34 35 // Simple test: enumeration of type int starting at 0. 36 const day_in = `type Day int 37 const ( 38 Monday Day = iota 39 Tuesday 40 Wednesday 41 Thursday 42 Friday 43 Saturday 44 Sunday 45 ) 46 ` 47 48 const day_out = ` 49 const _Day_name = "MondayTuesdayWednesdayThursdayFridaySaturdaySunday" 50 51 var _Day_index = [...]uint8{0, 6, 13, 22, 30, 36, 44, 50} 52 53 func (i Day) String() string { 54 if i < 0 || i >= Day(len(_Day_index)-1) { 55 return fmt.Sprintf("Day(%d)", i) 56 } 57 return _Day_name[_Day_index[i]:_Day_index[i+1]] 58 } 59 ` 60 61 // Enumeration with an offset. 62 // Also includes a duplicate. 63 const offset_in = `type Number int 64 const ( 65 _ Number = iota 66 One 67 Two 68 Three 69 AnotherOne = One // Duplicate; note that AnotherOne doesn't appear below. 70 ) 71 ` 72 73 const offset_out = ` 74 const _Number_name = "OneTwoThree" 75 76 var _Number_index = [...]uint8{0, 3, 6, 11} 77 78 func (i Number) String() string { 79 i -= 1 80 if i < 0 || i >= Number(len(_Number_index)-1) { 81 return fmt.Sprintf("Number(%d)", i+1) 82 } 83 return _Number_name[_Number_index[i]:_Number_index[i+1]] 84 } 85 ` 86 87 // Gaps and an offset. 88 const gap_in = `type Gap int 89 const ( 90 Two Gap = 2 91 Three Gap = 3 92 Five Gap = 5 93 Six Gap = 6 94 Seven Gap = 7 95 Eight Gap = 8 96 Nine Gap = 9 97 Eleven Gap = 11 98 ) 99 ` 100 101 const gap_out = ` 102 const ( 103 _Gap_name_0 = "TwoThree" 104 _Gap_name_1 = "FiveSixSevenEightNine" 105 _Gap_name_2 = "Eleven" 106 ) 107 108 var ( 109 _Gap_index_0 = [...]uint8{0, 3, 8} 110 _Gap_index_1 = [...]uint8{0, 4, 7, 12, 17, 21} 111 _Gap_index_2 = [...]uint8{0, 6} 112 ) 113 114 func (i Gap) String() string { 115 switch { 116 case 2 <= i && i <= 3: 117 i -= 2 118 return _Gap_name_0[_Gap_index_0[i]:_Gap_index_0[i+1]] 119 case 5 <= i && i <= 9: 120 i -= 5 121 return _Gap_name_1[_Gap_index_1[i]:_Gap_index_1[i+1]] 122 case i == 11: 123 return _Gap_name_2 124 default: 125 return fmt.Sprintf("Gap(%d)", i) 126 } 127 } 128 ` 129 130 // Signed integers spanning zero. 131 const num_in = `type Num int 132 const ( 133 m_2 Num = -2 + iota 134 m_1 135 m0 136 m1 137 m2 138 ) 139 ` 140 141 const num_out = ` 142 const _Num_name = "m_2m_1m0m1m2" 143 144 var _Num_index = [...]uint8{0, 3, 6, 8, 10, 12} 145 146 func (i Num) String() string { 147 i -= -2 148 if i < 0 || i >= Num(len(_Num_index)-1) { 149 return fmt.Sprintf("Num(%d)", i+-2) 150 } 151 return _Num_name[_Num_index[i]:_Num_index[i+1]] 152 } 153 ` 154 155 // Unsigned integers spanning zero. 156 const unum_in = `type Unum uint 157 const ( 158 m_2 Unum = iota + 253 159 m_1 160 ) 161 162 const ( 163 m0 Unum = iota 164 m1 165 m2 166 ) 167 ` 168 169 const unum_out = ` 170 const ( 171 _Unum_name_0 = "m0m1m2" 172 _Unum_name_1 = "m_2m_1" 173 ) 174 175 var ( 176 _Unum_index_0 = [...]uint8{0, 2, 4, 6} 177 _Unum_index_1 = [...]uint8{0, 3, 6} 178 ) 179 180 func (i Unum) String() string { 181 switch { 182 case 0 <= i && i <= 2: 183 return _Unum_name_0[_Unum_index_0[i]:_Unum_index_0[i+1]] 184 case 253 <= i && i <= 254: 185 i -= 253 186 return _Unum_name_1[_Unum_index_1[i]:_Unum_index_1[i+1]] 187 default: 188 return fmt.Sprintf("Unum(%d)", i) 189 } 190 } 191 ` 192 193 // Enough gaps to trigger a map implementation of the method. 194 // Also includes a duplicate to test that it doesn't cause problems 195 const prime_in = `type Prime int 196 const ( 197 p2 Prime = 2 198 p3 Prime = 3 199 p5 Prime = 5 200 p7 Prime = 7 201 p77 Prime = 7 // Duplicate; note that p77 doesn't appear below. 202 p11 Prime = 11 203 p13 Prime = 13 204 p17 Prime = 17 205 p19 Prime = 19 206 p23 Prime = 23 207 p29 Prime = 29 208 p37 Prime = 31 209 p41 Prime = 41 210 p43 Prime = 43 211 ) 212 ` 213 214 const prime_out = ` 215 const _Prime_name = "p2p3p5p7p11p13p17p19p23p29p37p41p43" 216 217 var _Prime_map = map[Prime]string{ 218 2: _Prime_name[0:2], 219 3: _Prime_name[2:4], 220 5: _Prime_name[4:6], 221 7: _Prime_name[6:8], 222 11: _Prime_name[8:11], 223 13: _Prime_name[11:14], 224 17: _Prime_name[14:17], 225 19: _Prime_name[17:20], 226 23: _Prime_name[20:23], 227 29: _Prime_name[23:26], 228 31: _Prime_name[26:29], 229 41: _Prime_name[29:32], 230 43: _Prime_name[32:35], 231 } 232 233 func (i Prime) String() string { 234 if str, ok := _Prime_map[i]; ok { 235 return str 236 } 237 return fmt.Sprintf("Prime(%d)", i) 238 } 239 ` 240 241 func TestGolden(t *testing.T) { 242 for _, test := range golden { 243 var g Generator 244 input := "package test\n" + test.input 245 file := test.name + ".go" 246 g.parsePackage(".", []string{file}, input) 247 // Extract the name and type of the constant from the first line. 248 tokens := strings.SplitN(test.input, " ", 3) 249 if len(tokens) != 3 { 250 t.Fatalf("%s: need type declaration on first line", test.name) 251 } 252 g.generate(tokens[1]) 253 got := string(g.format()) 254 if got != test.output { 255 t.Errorf("%s: got\n====\n%s====\nexpected\n====%s", test.name, got, test.output) 256 } 257 } 258 }