github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/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 "" }