Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / cmd / stringer / golden_test.go
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         "io/ioutil"
14         "os"
15         "path/filepath"
16         "strings"
17         "testing"
18
19         "golang.org/x/tools/internal/testenv"
20 )
21
22 // Golden represents a test case.
23 type Golden struct {
24         name        string
25         trimPrefix  string
26         lineComment bool
27         input       string // input; the package clause is provided when running the test.
28         output      string // expected output.
29 }
30
31 var golden = []Golden{
32         {"day", "", false, day_in, day_out},
33         {"offset", "", false, offset_in, offset_out},
34         {"gap", "", false, gap_in, gap_out},
35         {"num", "", false, num_in, num_out},
36         {"unum", "", false, unum_in, unum_out},
37         {"unumpos", "", false, unumpos_in, unumpos_out},
38         {"prime", "", false, prime_in, prime_out},
39         {"prefix", "Type", false, prefix_in, prefix_out},
40         {"tokens", "", true, tokens_in, tokens_out},
41 }
42
43 // Each example starts with "type XXX [u]int", with a single space separating them.
44
45 // Simple test: enumeration of type int starting at 0.
46 const day_in = `type Day int
47 const (
48         Monday Day = iota
49         Tuesday
50         Wednesday
51         Thursday
52         Friday
53         Saturday
54         Sunday
55 )
56 `
57
58 const day_out = `func _() {
59         // An "invalid array index" compiler error signifies that the constant values have changed.
60         // Re-run the stringer command to generate them again.
61         var x [1]struct{}
62         _ = x[Monday-0]
63         _ = x[Tuesday-1]
64         _ = x[Wednesday-2]
65         _ = x[Thursday-3]
66         _ = x[Friday-4]
67         _ = x[Saturday-5]
68         _ = x[Sunday-6]
69 }
70
71 const _Day_name = "MondayTuesdayWednesdayThursdayFridaySaturdaySunday"
72
73 var _Day_index = [...]uint8{0, 6, 13, 22, 30, 36, 44, 50}
74
75 func (i Day) String() string {
76         if i < 0 || i >= Day(len(_Day_index)-1) {
77                 return "Day(" + strconv.FormatInt(int64(i), 10) + ")"
78         }
79         return _Day_name[_Day_index[i]:_Day_index[i+1]]
80 }
81 `
82
83 // Enumeration with an offset.
84 // Also includes a duplicate.
85 const offset_in = `type Number int
86 const (
87         _ Number = iota
88         One
89         Two
90         Three
91         AnotherOne = One  // Duplicate; note that AnotherOne doesn't appear below.
92 )
93 `
94
95 const offset_out = `func _() {
96         // An "invalid array index" compiler error signifies that the constant values have changed.
97         // Re-run the stringer command to generate them again.
98         var x [1]struct{}
99         _ = x[One-1]
100         _ = x[Two-2]
101         _ = x[Three-3]
102 }
103
104 const _Number_name = "OneTwoThree"
105
106 var _Number_index = [...]uint8{0, 3, 6, 11}
107
108 func (i Number) String() string {
109         i -= 1
110         if i < 0 || i >= Number(len(_Number_index)-1) {
111                 return "Number(" + strconv.FormatInt(int64(i+1), 10) + ")"
112         }
113         return _Number_name[_Number_index[i]:_Number_index[i+1]]
114 }
115 `
116
117 // Gaps and an offset.
118 const gap_in = `type Gap int
119 const (
120         Two Gap = 2
121         Three Gap = 3
122         Five Gap = 5
123         Six Gap = 6
124         Seven Gap = 7
125         Eight Gap = 8
126         Nine Gap = 9
127         Eleven Gap = 11
128 )
129 `
130
131 const gap_out = `func _() {
132         // An "invalid array index" compiler error signifies that the constant values have changed.
133         // Re-run the stringer command to generate them again.
134         var x [1]struct{}
135         _ = x[Two-2]
136         _ = x[Three-3]
137         _ = x[Five-5]
138         _ = x[Six-6]
139         _ = x[Seven-7]
140         _ = x[Eight-8]
141         _ = x[Nine-9]
142         _ = x[Eleven-11]
143 }
144
145 const (
146         _Gap_name_0 = "TwoThree"
147         _Gap_name_1 = "FiveSixSevenEightNine"
148         _Gap_name_2 = "Eleven"
149 )
150
151 var (
152         _Gap_index_0 = [...]uint8{0, 3, 8}
153         _Gap_index_1 = [...]uint8{0, 4, 7, 12, 17, 21}
154 )
155
156 func (i Gap) String() string {
157         switch {
158         case 2 <= i && i <= 3:
159                 i -= 2
160                 return _Gap_name_0[_Gap_index_0[i]:_Gap_index_0[i+1]]
161         case 5 <= i && i <= 9:
162                 i -= 5
163                 return _Gap_name_1[_Gap_index_1[i]:_Gap_index_1[i+1]]
164         case i == 11:
165                 return _Gap_name_2
166         default:
167                 return "Gap(" + strconv.FormatInt(int64(i), 10) + ")"
168         }
169 }
170 `
171
172 // Signed integers spanning zero.
173 const num_in = `type Num int
174 const (
175         m_2 Num = -2 + iota
176         m_1
177         m0
178         m1
179         m2
180 )
181 `
182
183 const num_out = `func _() {
184         // An "invalid array index" compiler error signifies that the constant values have changed.
185         // Re-run the stringer command to generate them again.
186         var x [1]struct{}
187         _ = x[m_2 - -2]
188         _ = x[m_1 - -1]
189         _ = x[m0-0]
190         _ = x[m1-1]
191         _ = x[m2-2]
192 }
193
194 const _Num_name = "m_2m_1m0m1m2"
195
196 var _Num_index = [...]uint8{0, 3, 6, 8, 10, 12}
197
198 func (i Num) String() string {
199         i -= -2
200         if i < 0 || i >= Num(len(_Num_index)-1) {
201                 return "Num(" + strconv.FormatInt(int64(i+-2), 10) + ")"
202         }
203         return _Num_name[_Num_index[i]:_Num_index[i+1]]
204 }
205 `
206
207 // Unsigned integers spanning zero.
208 const unum_in = `type Unum uint
209 const (
210         m_2 Unum = iota + 253
211         m_1
212 )
213
214 const (
215         m0 Unum = iota
216         m1
217         m2
218 )
219 `
220
221 const unum_out = `func _() {
222         // An "invalid array index" compiler error signifies that the constant values have changed.
223         // Re-run the stringer command to generate them again.
224         var x [1]struct{}
225         _ = x[m_2-253]
226         _ = x[m_1-254]
227         _ = x[m0-0]
228         _ = x[m1-1]
229         _ = x[m2-2]
230 }
231
232 const (
233         _Unum_name_0 = "m0m1m2"
234         _Unum_name_1 = "m_2m_1"
235 )
236
237 var (
238         _Unum_index_0 = [...]uint8{0, 2, 4, 6}
239         _Unum_index_1 = [...]uint8{0, 3, 6}
240 )
241
242 func (i Unum) String() string {
243         switch {
244         case i <= 2:
245                 return _Unum_name_0[_Unum_index_0[i]:_Unum_index_0[i+1]]
246         case 253 <= i && i <= 254:
247                 i -= 253
248                 return _Unum_name_1[_Unum_index_1[i]:_Unum_index_1[i+1]]
249         default:
250                 return "Unum(" + strconv.FormatInt(int64(i), 10) + ")"
251         }
252 }
253 `
254
255 // Unsigned positive integers.
256 const unumpos_in = `type Unumpos uint
257 const (
258         m253 Unumpos = iota + 253
259         m254
260 )
261
262 const (
263         m1 Unumpos = iota + 1
264         m2
265         m3
266 )
267 `
268
269 const unumpos_out = `func _() {
270         // An "invalid array index" compiler error signifies that the constant values have changed.
271         // Re-run the stringer command to generate them again.
272         var x [1]struct{}
273         _ = x[m253-253]
274         _ = x[m254-254]
275         _ = x[m1-1]
276         _ = x[m2-2]
277         _ = x[m3-3]
278 }
279
280 const (
281         _Unumpos_name_0 = "m1m2m3"
282         _Unumpos_name_1 = "m253m254"
283 )
284
285 var (
286         _Unumpos_index_0 = [...]uint8{0, 2, 4, 6}
287         _Unumpos_index_1 = [...]uint8{0, 4, 8}
288 )
289
290 func (i Unumpos) String() string {
291         switch {
292         case 1 <= i && i <= 3:
293                 i -= 1
294                 return _Unumpos_name_0[_Unumpos_index_0[i]:_Unumpos_index_0[i+1]]
295         case 253 <= i && i <= 254:
296                 i -= 253
297                 return _Unumpos_name_1[_Unumpos_index_1[i]:_Unumpos_index_1[i+1]]
298         default:
299                 return "Unumpos(" + strconv.FormatInt(int64(i), 10) + ")"
300         }
301 }
302 `
303
304 // Enough gaps to trigger a map implementation of the method.
305 // Also includes a duplicate to test that it doesn't cause problems
306 const prime_in = `type Prime int
307 const (
308         p2 Prime = 2
309         p3 Prime = 3
310         p5 Prime = 5
311         p7 Prime = 7
312         p77 Prime = 7 // Duplicate; note that p77 doesn't appear below.
313         p11 Prime = 11
314         p13 Prime = 13
315         p17 Prime = 17
316         p19 Prime = 19
317         p23 Prime = 23
318         p29 Prime = 29
319         p37 Prime = 31
320         p41 Prime = 41
321         p43 Prime = 43
322 )
323 `
324
325 const prime_out = `func _() {
326         // An "invalid array index" compiler error signifies that the constant values have changed.
327         // Re-run the stringer command to generate them again.
328         var x [1]struct{}
329         _ = x[p2-2]
330         _ = x[p3-3]
331         _ = x[p5-5]
332         _ = x[p7-7]
333         _ = x[p77-7]
334         _ = x[p11-11]
335         _ = x[p13-13]
336         _ = x[p17-17]
337         _ = x[p19-19]
338         _ = x[p23-23]
339         _ = x[p29-29]
340         _ = x[p37-31]
341         _ = x[p41-41]
342         _ = x[p43-43]
343 }
344
345 const _Prime_name = "p2p3p5p7p11p13p17p19p23p29p37p41p43"
346
347 var _Prime_map = map[Prime]string{
348         2:  _Prime_name[0:2],
349         3:  _Prime_name[2:4],
350         5:  _Prime_name[4:6],
351         7:  _Prime_name[6:8],
352         11: _Prime_name[8:11],
353         13: _Prime_name[11:14],
354         17: _Prime_name[14:17],
355         19: _Prime_name[17:20],
356         23: _Prime_name[20:23],
357         29: _Prime_name[23:26],
358         31: _Prime_name[26:29],
359         41: _Prime_name[29:32],
360         43: _Prime_name[32:35],
361 }
362
363 func (i Prime) String() string {
364         if str, ok := _Prime_map[i]; ok {
365                 return str
366         }
367         return "Prime(" + strconv.FormatInt(int64(i), 10) + ")"
368 }
369 `
370
371 const prefix_in = `type Type int
372 const (
373         TypeInt Type = iota
374         TypeString
375         TypeFloat
376         TypeRune
377         TypeByte
378         TypeStruct
379         TypeSlice
380 )
381 `
382
383 const prefix_out = `func _() {
384         // An "invalid array index" compiler error signifies that the constant values have changed.
385         // Re-run the stringer command to generate them again.
386         var x [1]struct{}
387         _ = x[TypeInt-0]
388         _ = x[TypeString-1]
389         _ = x[TypeFloat-2]
390         _ = x[TypeRune-3]
391         _ = x[TypeByte-4]
392         _ = x[TypeStruct-5]
393         _ = x[TypeSlice-6]
394 }
395
396 const _Type_name = "IntStringFloatRuneByteStructSlice"
397
398 var _Type_index = [...]uint8{0, 3, 9, 14, 18, 22, 28, 33}
399
400 func (i Type) String() string {
401         if i < 0 || i >= Type(len(_Type_index)-1) {
402                 return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
403         }
404         return _Type_name[_Type_index[i]:_Type_index[i+1]]
405 }
406 `
407
408 const tokens_in = `type Token int
409 const (
410         And Token = iota // &
411         Or               // |
412         Add              // +
413         Sub              // -
414         Ident
415         Period // .
416
417         // not to be used
418         SingleBefore
419         // not to be used
420         BeforeAndInline // inline
421         InlineGeneral /* inline general */
422 )
423 `
424
425 const tokens_out = `func _() {
426         // An "invalid array index" compiler error signifies that the constant values have changed.
427         // Re-run the stringer command to generate them again.
428         var x [1]struct{}
429         _ = x[And-0]
430         _ = x[Or-1]
431         _ = x[Add-2]
432         _ = x[Sub-3]
433         _ = x[Ident-4]
434         _ = x[Period-5]
435         _ = x[SingleBefore-6]
436         _ = x[BeforeAndInline-7]
437         _ = x[InlineGeneral-8]
438 }
439
440 const _Token_name = "&|+-Ident.SingleBeforeinlineinline general"
441
442 var _Token_index = [...]uint8{0, 1, 2, 3, 4, 9, 10, 22, 28, 42}
443
444 func (i Token) String() string {
445         if i < 0 || i >= Token(len(_Token_index)-1) {
446                 return "Token(" + strconv.FormatInt(int64(i), 10) + ")"
447         }
448         return _Token_name[_Token_index[i]:_Token_index[i+1]]
449 }
450 `
451
452 func TestGolden(t *testing.T) {
453         testenv.NeedsTool(t, "go")
454
455         dir, err := ioutil.TempDir("", "stringer")
456         if err != nil {
457                 t.Error(err)
458         }
459         defer os.RemoveAll(dir)
460
461         for _, test := range golden {
462                 g := Generator{
463                         trimPrefix:  test.trimPrefix,
464                         lineComment: test.lineComment,
465                 }
466                 input := "package test\n" + test.input
467                 file := test.name + ".go"
468                 absFile := filepath.Join(dir, file)
469                 err := ioutil.WriteFile(absFile, []byte(input), 0644)
470                 if err != nil {
471                         t.Error(err)
472                 }
473
474                 g.parsePackage([]string{absFile}, nil)
475                 // Extract the name and type of the constant from the first line.
476                 tokens := strings.SplitN(test.input, " ", 3)
477                 if len(tokens) != 3 {
478                         t.Fatalf("%s: need type declaration on first line", test.name)
479                 }
480                 g.generate(tokens[1])
481                 got := string(g.format())
482                 if got != test.output {
483                         t.Errorf("%s: got(%d)\n====\n%q====\nexpected(%d)\n====%q", test.name, len(got), got, len(test.output), test.output)
484                 }
485         }
486 }