github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/go/not-internal/generate/generate_test.go (about) 1 // Copyright 2011 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 generate 6 7 import ( 8 "os" 9 "reflect" 10 "runtime" 11 "testing" 12 ) 13 14 type splitTest struct { 15 in string 16 out []string 17 } 18 19 // Same as above, except including source line number to set 20 type splitTestWithLine struct { 21 in string 22 out []string 23 lineNumber int 24 } 25 26 const anyLineNo = 0 27 28 var splitTests = []splitTest{ 29 {"", nil}, 30 {"x", []string{"x"}}, 31 {" a b\tc ", []string{"a", "b", "c"}}, 32 {` " a " `, []string{" a "}}, 33 {"$GOARCH", []string{runtime.GOARCH}}, 34 {"$GOOS", []string{runtime.GOOS}}, 35 {"$GOFILE", []string{"proc.go"}}, 36 {"$GOPACKAGE", []string{"sys"}}, 37 {"a $XXNOTDEFINEDXX b", []string{"a", "", "b"}}, 38 {"/$XXNOTDEFINED/", []string{"//"}}, 39 {"/$DOLLAR/", []string{"/$/"}}, 40 {"yacc -o $GOARCH/yacc_$GOFILE", []string{"go", "tool", "yacc", "-o", runtime.GOARCH + "/yacc_proc.go"}}, 41 } 42 43 func TestGenerateCommandParse(t *testing.T) { 44 g := &Generator{ 45 r: nil, // Unused here. 46 path: "/usr/ken/sys/proc.go", 47 dir: "/usr/ken/sys", 48 file: "proc.go", 49 pkg: "sys", 50 commands: make(map[string][]string), 51 } 52 g.setEnv() 53 g.setShorthand([]string{"-command", "yacc", "go", "tool", "yacc"}) 54 for _, test := range splitTests { 55 // First with newlines. 56 got := g.split("//go:generate " + test.in + "\n") 57 if !reflect.DeepEqual(got, test.out) { 58 t.Errorf("split(%q): got %q expected %q", test.in, got, test.out) 59 } 60 // Then with CRLFs, thank you Windows. 61 got = g.split("//go:generate " + test.in + "\r\n") 62 if !reflect.DeepEqual(got, test.out) { 63 t.Errorf("split(%q): got %q expected %q", test.in, got, test.out) 64 } 65 } 66 } 67 68 // These environment variables will be undefined before the splitTestWithLine tests 69 var undefEnvList = []string{ 70 "_XYZZY_", 71 } 72 73 // These environment variables will be defined before the splitTestWithLine tests 74 var defEnvMap = map[string]string{ 75 "_PLUGH_": "SomeVal", 76 "_X": "Y", 77 } 78 79 // TestGenerateCommandShortHand - similar to TestGenerateCommandParse, 80 // except: 81 // 1. if the result starts with -command, record that shorthand 82 // before moving on to the next test. 83 // 2. If a source line number is specified, set that in the parser 84 // before executing the test. i.e., execute the split as if it 85 // processing that source line. 86 func TestGenerateCommandShorthand(t *testing.T) { 87 g := &Generator{ 88 r: nil, // Unused here. 89 path: "/usr/ken/sys/proc.go", 90 dir: "/usr/ken/sys", 91 file: "proc.go", 92 pkg: "sys", 93 commands: make(map[string][]string), 94 } 95 96 var inLine string 97 var expected, got []string 98 99 g.setEnv() 100 101 // Set up the system environment variables 102 for i := range undefEnvList { 103 os.Unsetenv(undefEnvList[i]) 104 } 105 for k := range defEnvMap { 106 os.Setenv(k, defEnvMap[k]) 107 } 108 109 // simple command from environment variable 110 inLine = "//go:generate -command CMD0 \"ab${_X}cd\"" 111 expected = []string{"-command", "CMD0", "abYcd"} 112 got = g.split(inLine + "\n") 113 114 if !reflect.DeepEqual(got, expected) { 115 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 116 } 117 118 // try again, with an extra level of indirection (should leave variable in command) 119 inLine = "//go:generate -command CMD0 \"ab${DOLLAR}{_X}cd\"" 120 expected = []string{"-command", "CMD0", "ab${_X}cd"} 121 got = g.split(inLine + "\n") 122 123 if !reflect.DeepEqual(got, expected) { 124 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 125 } 126 127 // Now the interesting part, record that output as a command 128 g.setShorthand(got) 129 130 // see that the command still substitutes correctly from env. variable 131 inLine = "//go:generate CMD0" 132 expected = []string{"abYcd"} 133 got = g.split(inLine + "\n") 134 135 if !reflect.DeepEqual(got, expected) { 136 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 137 } 138 139 // Now change the value of $X and see if the recorded definition is 140 // still intact (vs. having the $_X already substituted out) 141 142 os.Setenv("_X", "Z") 143 inLine = "//go:generate CMD0" 144 expected = []string{"abZcd"} 145 got = g.split(inLine + "\n") 146 147 if !reflect.DeepEqual(got, expected) { 148 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 149 } 150 151 // What if the variable is now undefined? Should be empty substitution. 152 153 os.Unsetenv("_X") 154 inLine = "//go:generate CMD0" 155 expected = []string{"abcd"} 156 got = g.split(inLine + "\n") 157 158 if !reflect.DeepEqual(got, expected) { 159 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 160 } 161 162 // Try another undefined variable as an extra check 163 os.Unsetenv("_Z") 164 inLine = "//go:generate -command CMD1 \"ab${_Z}cd\"" 165 expected = []string{"-command", "CMD1", "abcd"} 166 got = g.split(inLine + "\n") 167 168 if !reflect.DeepEqual(got, expected) { 169 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 170 } 171 172 g.setShorthand(got) 173 174 inLine = "//go:generate CMD1" 175 expected = []string{"abcd"} 176 got = g.split(inLine + "\n") 177 178 if !reflect.DeepEqual(got, expected) { 179 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 180 } 181 182 const val = "someNewValue" 183 os.Setenv("_Z", val) 184 185 // try again with the properly-escaped variable. 186 187 inLine = "//go:generate -command CMD2 \"ab${DOLLAR}{_Z}cd\"" 188 expected = []string{"-command", "CMD2", "ab${_Z}cd"} 189 got = g.split(inLine + "\n") 190 191 if !reflect.DeepEqual(got, expected) { 192 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 193 } 194 195 g.setShorthand(got) 196 197 inLine = "//go:generate CMD2" 198 expected = []string{"ab" + val + "cd"} 199 got = g.split(inLine + "\n") 200 201 if !reflect.DeepEqual(got, expected) { 202 t.Errorf("split(%q): got %q expected %q", inLine, got, expected) 203 } 204 } 205 206 // Command-related tests for TestGenerateCommandShortHand2 207 // -- Note line numbers included to check substitutions from "build-in" variable - $GOLINE 208 var splitTestsLines = []splitTestWithLine{ 209 {"-command TEST1 $GOLINE", []string{"-command", "TEST1", "22"}, 22}, 210 {"-command TEST2 ${DOLLAR}GOLINE", []string{"-command", "TEST2", "$GOLINE"}, 26}, 211 {"TEST1", []string{"22"}, 33}, 212 {"TEST2", []string{"66"}, 66}, 213 {"TEST1 ''", []string{"22", "''"}, 99}, 214 {"TEST2 ''", []string{"44", "''"}, 44}, 215 } 216 217 // TestGenerateCommandShortHand - similar to TestGenerateCommandParse, 218 // except: 219 // 1. if the result starts with -command, record that shorthand 220 // before moving on to the next test. 221 // 2. If a source line number is specified, set that in the parser 222 // before executing the test. i.e., execute the split as if it 223 // processing that source line. 224 func TestGenerateCommandShortHand2(t *testing.T) { 225 g := &Generator{ 226 r: nil, // Unused here. 227 path: "/usr/ken/sys/proc.go", 228 dir: "/usr/ken/sys", 229 file: "proc.go", 230 pkg: "sys", 231 commands: make(map[string][]string), 232 } 233 g.setEnv() 234 for _, test := range splitTestsLines { 235 // if the test specified a line number, reflect that 236 if test.lineNumber != anyLineNo { 237 g.lineNum = test.lineNumber 238 g.setEnv() 239 } 240 // First with newlines. 241 got := g.split("//go:generate " + test.in + "\n") 242 if !reflect.DeepEqual(got, test.out) { 243 t.Errorf("split(%q): got %q expected %q", test.in, got, test.out) 244 } 245 // Then with CRLFs, thank you Windows. 246 got = g.split("//go:generate " + test.in + "\r\n") 247 if !reflect.DeepEqual(got, test.out) { 248 t.Errorf("split(%q): got %q expected %q", test.in, got, test.out) 249 } 250 if got[0] == "-command" { // record commands 251 g.setShorthand(got) 252 } 253 } 254 }