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  }