github.com/cycloidio/terraform@v1.1.10-0.20220513142504-76d5c768dc63/main_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "reflect" 7 "testing" 8 9 "github.com/mitchellh/cli" 10 ) 11 12 func TestMain_cliArgsFromEnv(t *testing.T) { 13 // Set up the state. This test really messes with the environment and 14 // global state so we set things up to be restored. 15 16 // Restore original CLI args 17 oldArgs := os.Args 18 defer func() { os.Args = oldArgs }() 19 20 // Set up test command and restore that 21 Commands = make(map[string]cli.CommandFactory) 22 defer func() { 23 Commands = nil 24 }() 25 testCommandName := "unit-test-cli-args" 26 testCommand := &testCommandCLI{} 27 Commands[testCommandName] = func() (cli.Command, error) { 28 return testCommand, nil 29 } 30 31 cases := []struct { 32 Name string 33 Args []string 34 Value string 35 Expected []string 36 Err bool 37 }{ 38 { 39 "no env", 40 []string{testCommandName, "foo", "bar"}, 41 "", 42 []string{"foo", "bar"}, 43 false, 44 }, 45 46 { 47 "both env var and CLI", 48 []string{testCommandName, "foo", "bar"}, 49 "-foo bar", 50 []string{"-foo", "bar", "foo", "bar"}, 51 false, 52 }, 53 54 { 55 "only env var", 56 []string{testCommandName}, 57 "-foo bar", 58 []string{"-foo", "bar"}, 59 false, 60 }, 61 62 { 63 "cli string has blank values", 64 []string{testCommandName, "bar", "", "baz"}, 65 "-foo bar", 66 []string{"-foo", "bar", "bar", "", "baz"}, 67 false, 68 }, 69 70 { 71 "cli string has blank values before the command", 72 []string{"", testCommandName, "bar"}, 73 "-foo bar", 74 []string{"-foo", "bar", "bar"}, 75 false, 76 }, 77 78 { 79 // this should fail gracefully, this is just testing 80 // that we don't panic with our slice arithmetic 81 "no command", 82 []string{}, 83 "-foo bar", 84 nil, 85 true, 86 }, 87 88 { 89 "single quoted strings", 90 []string{testCommandName, "foo"}, 91 "-foo 'bar baz'", 92 []string{"-foo", "bar baz", "foo"}, 93 false, 94 }, 95 96 { 97 "double quoted strings", 98 []string{testCommandName, "foo"}, 99 `-foo "bar baz"`, 100 []string{"-foo", "bar baz", "foo"}, 101 false, 102 }, 103 104 { 105 "double quoted single quoted strings", 106 []string{testCommandName, "foo"}, 107 `-foo "'bar baz'"`, 108 []string{"-foo", "'bar baz'", "foo"}, 109 false, 110 }, 111 } 112 113 for i, tc := range cases { 114 t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { 115 os.Unsetenv(EnvCLI) 116 defer os.Unsetenv(EnvCLI) 117 118 // Set the env var value 119 if tc.Value != "" { 120 if err := os.Setenv(EnvCLI, tc.Value); err != nil { 121 t.Fatalf("err: %s", err) 122 } 123 } 124 125 // Set up the args 126 args := make([]string, len(tc.Args)+1) 127 args[0] = oldArgs[0] // process name 128 copy(args[1:], tc.Args) 129 130 // Run it! 131 os.Args = args 132 testCommand.Args = nil 133 exit := realMain() 134 if (exit != 0) != tc.Err { 135 t.Fatalf("bad: %d", exit) 136 } 137 if tc.Err { 138 return 139 } 140 141 // Verify 142 if !reflect.DeepEqual(testCommand.Args, tc.Expected) { 143 t.Fatalf("bad: %#v", testCommand.Args) 144 } 145 }) 146 } 147 } 148 149 // This test just has more options than the test above. Use this for 150 // more control over behavior at the expense of more complex test structures. 151 func TestMain_cliArgsFromEnvAdvanced(t *testing.T) { 152 // Restore original CLI args 153 oldArgs := os.Args 154 defer func() { os.Args = oldArgs }() 155 156 // Set up test command and restore that 157 Commands = make(map[string]cli.CommandFactory) 158 defer func() { 159 Commands = nil 160 }() 161 162 cases := []struct { 163 Name string 164 Command string 165 EnvVar string 166 Args []string 167 Value string 168 Expected []string 169 Err bool 170 }{ 171 { 172 "targeted to another command", 173 "command", 174 EnvCLI + "_foo", 175 []string{"command", "foo", "bar"}, 176 "-flag", 177 []string{"foo", "bar"}, 178 false, 179 }, 180 181 { 182 "targeted to this command", 183 "command", 184 EnvCLI + "_command", 185 []string{"command", "foo", "bar"}, 186 "-flag", 187 []string{"-flag", "foo", "bar"}, 188 false, 189 }, 190 191 { 192 "targeted to a command with a hyphen", 193 "command-name", 194 EnvCLI + "_command_name", 195 []string{"command-name", "foo", "bar"}, 196 "-flag", 197 []string{"-flag", "foo", "bar"}, 198 false, 199 }, 200 201 { 202 "targeted to a command with a space", 203 "command name", 204 EnvCLI + "_command_name", 205 []string{"command", "name", "foo", "bar"}, 206 "-flag", 207 []string{"-flag", "foo", "bar"}, 208 false, 209 }, 210 } 211 212 for i, tc := range cases { 213 t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { 214 // Set up test command and restore that 215 testCommandName := tc.Command 216 testCommand := &testCommandCLI{} 217 defer func() { delete(Commands, testCommandName) }() 218 Commands[testCommandName] = func() (cli.Command, error) { 219 return testCommand, nil 220 } 221 222 os.Unsetenv(tc.EnvVar) 223 defer os.Unsetenv(tc.EnvVar) 224 225 // Set the env var value 226 if tc.Value != "" { 227 if err := os.Setenv(tc.EnvVar, tc.Value); err != nil { 228 t.Fatalf("err: %s", err) 229 } 230 } 231 232 // Set up the args 233 args := make([]string, len(tc.Args)+1) 234 args[0] = oldArgs[0] // process name 235 copy(args[1:], tc.Args) 236 237 // Run it! 238 os.Args = args 239 testCommand.Args = nil 240 exit := realMain() 241 if (exit != 0) != tc.Err { 242 t.Fatalf("unexpected exit status %d; want 0", exit) 243 } 244 if tc.Err { 245 return 246 } 247 248 // Verify 249 if !reflect.DeepEqual(testCommand.Args, tc.Expected) { 250 t.Fatalf("bad: %#v", testCommand.Args) 251 } 252 }) 253 } 254 } 255 256 // verify that we output valid autocomplete results 257 func TestMain_autoComplete(t *testing.T) { 258 // Restore original CLI args 259 oldArgs := os.Args 260 defer func() { os.Args = oldArgs }() 261 262 // Set up test command and restore that 263 Commands = make(map[string]cli.CommandFactory) 264 defer func() { 265 Commands = nil 266 }() 267 268 // Set up test command and restore that 269 Commands["foo"] = func() (cli.Command, error) { 270 return &testCommandCLI{}, nil 271 } 272 273 os.Setenv("COMP_LINE", "terraform versio") 274 defer os.Unsetenv("COMP_LINE") 275 276 // Run it! 277 os.Args = []string{"terraform", "terraform", "versio"} 278 exit := realMain() 279 if exit != 0 { 280 t.Fatalf("unexpected exit status %d; want 0", exit) 281 } 282 } 283 284 type testCommandCLI struct { 285 Args []string 286 } 287 288 func (c *testCommandCLI) Run(args []string) int { 289 c.Args = args 290 return 0 291 } 292 293 func (c *testCommandCLI) Synopsis() string { return "" } 294 func (c *testCommandCLI) Help() string { return "" } 295 296 func TestWarnOutput(t *testing.T) { 297 mock := cli.NewMockUi() 298 wrapped := &ui{mock} 299 wrapped.Warn("WARNING") 300 301 stderr := mock.ErrorWriter.String() 302 stdout := mock.OutputWriter.String() 303 304 if stderr != "" { 305 t.Fatalf("unexpected stderr: %q", stderr) 306 } 307 308 if stdout != "WARNING\n" { 309 t.Fatalf("unexpected stdout: %q\n", stdout) 310 } 311 }