github.com/rliebz/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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 // Setup 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 // Setup test command and restore that 21 testCommandName := "unit-test-cli-args" 22 testCommand := &testCommandCLI{} 23 defer func() { delete(Commands, testCommandName) }() 24 Commands[testCommandName] = func() (cli.Command, error) { 25 return testCommand, nil 26 } 27 28 cases := []struct { 29 Name string 30 Args []string 31 Value string 32 Expected []string 33 Err bool 34 }{ 35 { 36 "no env", 37 []string{testCommandName, "foo", "bar"}, 38 "", 39 []string{"foo", "bar"}, 40 false, 41 }, 42 43 { 44 "both env var and CLI", 45 []string{testCommandName, "foo", "bar"}, 46 "-foo bar", 47 []string{"-foo", "bar", "foo", "bar"}, 48 false, 49 }, 50 51 { 52 "only env var", 53 []string{testCommandName}, 54 "-foo bar", 55 []string{"-foo", "bar"}, 56 false, 57 }, 58 59 { 60 "cli string has blank values", 61 []string{testCommandName, "bar", "", "baz"}, 62 "-foo bar", 63 []string{"-foo", "bar", "bar", "", "baz"}, 64 false, 65 }, 66 67 { 68 "cli string has blank values before the command", 69 []string{"", testCommandName, "bar"}, 70 "-foo bar", 71 []string{"-foo", "bar", "bar"}, 72 false, 73 }, 74 75 { 76 // this should fail gracefully, this is just testing 77 // that we don't panic with our slice arithmetic 78 "no command", 79 []string{}, 80 "-foo bar", 81 nil, 82 true, 83 }, 84 85 { 86 "single quoted strings", 87 []string{testCommandName, "foo"}, 88 "-foo 'bar baz'", 89 []string{"-foo", "bar baz", "foo"}, 90 false, 91 }, 92 93 { 94 "double quoted strings", 95 []string{testCommandName, "foo"}, 96 `-foo "bar baz"`, 97 []string{"-foo", "bar baz", "foo"}, 98 false, 99 }, 100 101 { 102 "double quoted single quoted strings", 103 []string{testCommandName, "foo"}, 104 `-foo "'bar baz'"`, 105 []string{"-foo", "'bar baz'", "foo"}, 106 false, 107 }, 108 } 109 110 for i, tc := range cases { 111 t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { 112 os.Unsetenv(EnvCLI) 113 defer os.Unsetenv(EnvCLI) 114 115 // Set the env var value 116 if tc.Value != "" { 117 if err := os.Setenv(EnvCLI, tc.Value); err != nil { 118 t.Fatalf("err: %s", err) 119 } 120 } 121 122 // Setup the args 123 args := make([]string, len(tc.Args)+1) 124 args[0] = oldArgs[0] // process name 125 copy(args[1:], tc.Args) 126 127 // Run it! 128 os.Args = args 129 testCommand.Args = nil 130 exit := wrappedMain() 131 if (exit != 0) != tc.Err { 132 t.Fatalf("bad: %d", exit) 133 } 134 if tc.Err { 135 return 136 } 137 138 // Verify 139 if !reflect.DeepEqual(testCommand.Args, tc.Expected) { 140 t.Fatalf("bad: %#v", testCommand.Args) 141 } 142 }) 143 } 144 } 145 146 // This test just has more options than the test above. Use this for 147 // more control over behavior at the expense of more complex test structures. 148 func TestMain_cliArgsFromEnvAdvanced(t *testing.T) { 149 // Restore original CLI args 150 oldArgs := os.Args 151 defer func() { os.Args = oldArgs }() 152 153 cases := []struct { 154 Name string 155 Command string 156 EnvVar string 157 Args []string 158 Value string 159 Expected []string 160 Err bool 161 }{ 162 { 163 "targeted to another command", 164 "command", 165 EnvCLI + "_foo", 166 []string{"command", "foo", "bar"}, 167 "-flag", 168 []string{"foo", "bar"}, 169 false, 170 }, 171 172 { 173 "targeted to this command", 174 "command", 175 EnvCLI + "_command", 176 []string{"command", "foo", "bar"}, 177 "-flag", 178 []string{"-flag", "foo", "bar"}, 179 false, 180 }, 181 182 { 183 "targeted to a command with a hyphen", 184 "command-name", 185 EnvCLI + "_command_name", 186 []string{"command-name", "foo", "bar"}, 187 "-flag", 188 []string{"-flag", "foo", "bar"}, 189 false, 190 }, 191 192 { 193 "targeted to a command with a space", 194 "command name", 195 EnvCLI + "_command_name", 196 []string{"command", "name", "foo", "bar"}, 197 "-flag", 198 []string{"-flag", "foo", "bar"}, 199 false, 200 }, 201 } 202 203 for i, tc := range cases { 204 t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { 205 // Setup test command and restore that 206 testCommandName := tc.Command 207 testCommand := &testCommandCLI{} 208 defer func() { delete(Commands, testCommandName) }() 209 Commands[testCommandName] = func() (cli.Command, error) { 210 return testCommand, nil 211 } 212 213 os.Unsetenv(tc.EnvVar) 214 defer os.Unsetenv(tc.EnvVar) 215 216 // Set the env var value 217 if tc.Value != "" { 218 if err := os.Setenv(tc.EnvVar, tc.Value); err != nil { 219 t.Fatalf("err: %s", err) 220 } 221 } 222 223 // Setup the args 224 args := make([]string, len(tc.Args)+1) 225 args[0] = oldArgs[0] // process name 226 copy(args[1:], tc.Args) 227 228 // Run it! 229 os.Args = args 230 testCommand.Args = nil 231 exit := wrappedMain() 232 if (exit != 0) != tc.Err { 233 t.Fatalf("bad: %d", exit) 234 } 235 if tc.Err { 236 return 237 } 238 239 // Verify 240 if !reflect.DeepEqual(testCommand.Args, tc.Expected) { 241 t.Fatalf("bad: %#v", testCommand.Args) 242 } 243 }) 244 } 245 } 246 247 type testCommandCLI struct { 248 Args []string 249 } 250 251 func (c *testCommandCLI) Run(args []string) int { 252 c.Args = args 253 return 0 254 } 255 256 func (c *testCommandCLI) Synopsis() string { return "" } 257 func (c *testCommandCLI) Help() string { return "" }