github.com/justincormack/cli@v0.0.0-20201215022714-831ebeae9675/e2e/cli-plugins/flags_test.go (about)

     1  package cliplugins
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  
     7  	"gotest.tools/v3/icmd"
     8  )
     9  
    10  // TestRunGoodArgument ensures correct behaviour when running a valid plugin with an `--argument`.
    11  func TestRunGoodArgument(t *testing.T) {
    12  	run, _, cleanup := prepare(t)
    13  	defer cleanup()
    14  
    15  	res := icmd.RunCmd(run("helloworld", "--who", "Cleveland"))
    16  	res.Assert(t, icmd.Expected{
    17  		ExitCode: 0,
    18  		Out:      "Hello Cleveland!",
    19  	})
    20  }
    21  
    22  // TestClashWithGlobalArgs ensures correct behaviour when a plugin
    23  // has an argument with the same name as one of the globals.
    24  func TestClashWithGlobalArgs(t *testing.T) {
    25  	run, _, cleanup := prepare(t)
    26  	defer cleanup()
    27  
    28  	for _, tc := range []struct {
    29  		name                     string
    30  		args                     []string
    31  		expectedOut, expectedErr string
    32  	}{
    33  		{
    34  			name:        "short-without-val",
    35  			args:        []string{"-D"},
    36  			expectedOut: "Hello World!",
    37  			expectedErr: "Plugin debug mode enabled",
    38  		},
    39  		{
    40  			name:        "long-without-val",
    41  			args:        []string{"--debug"},
    42  			expectedOut: "Hello World!",
    43  			expectedErr: "Plugin debug mode enabled",
    44  		},
    45  		{
    46  			name:        "short-with-val",
    47  			args:        []string{"-c", "Christmas"},
    48  			expectedOut: "Merry Christmas!",
    49  			expectedErr: icmd.None,
    50  		},
    51  		{
    52  			name:        "short-with-val",
    53  			args:        []string{"--context", "Christmas"},
    54  			expectedOut: "Merry Christmas!",
    55  			expectedErr: icmd.None,
    56  		},
    57  	} {
    58  		t.Run(tc.name, func(t *testing.T) {
    59  			args := append([]string{"helloworld"}, tc.args...)
    60  			res := icmd.RunCmd(run(args...))
    61  			res.Assert(t, icmd.Expected{
    62  				ExitCode: 0,
    63  				Out:      tc.expectedOut,
    64  				Err:      tc.expectedErr,
    65  			})
    66  		})
    67  	}
    68  }
    69  
    70  // TestGlobalArgsOnlyParsedOnce checks that global args are only parsed
    71  // once (cf https://github.com/docker/cli/issues/1801). These tests
    72  // rely on `-H` being a list type (i.e. NewNamedListOptsRef) which
    73  // reject multiple uses dynamically (see `getServerHost()` in
    74  // github.com/docker/cli/cli/command/cli.go) in order to detect this
    75  // scenario.
    76  func TestGlobalArgsOnlyParsedOnce(t *testing.T) {
    77  	run, _, cleanup := prepare(t)
    78  	defer cleanup()
    79  
    80  	// We can rely on `$DOCKER_HOST` being set due to the call to
    81  	// `environment.Setup` in our `TestMain`.
    82  	dh := os.Getenv("DOCKER_HOST")
    83  
    84  	for _, tc := range []struct {
    85  		name                     string
    86  		args                     []string
    87  		expectedExitCode         int
    88  		expectedOut, expectedErr string
    89  	}{
    90  		{
    91  			// This is checking the precondition wrt -H mentioned in the function comment
    92  			name:             "fails-if-H-used-twice",
    93  			args:             []string{"-H", dh, "-H", dh, "version", "-f", "{{.Client.Version}}"},
    94  			expectedExitCode: 1,
    95  			expectedOut:      icmd.None,
    96  			expectedErr:      "Please specify only one -H",
    97  		},
    98  		{
    99  			name:             "builtin",
   100  			args:             []string{"-H", dh, "version", "-f", "{{.Client.Version}}"},
   101  			expectedExitCode: 0,
   102  			expectedOut:      "", // Will be the client version, but the specifics aren't important so long as stderr is empty.
   103  			expectedErr:      icmd.None,
   104  		},
   105  		{
   106  			name:             "plugin",
   107  			args:             []string{"-H", dh, "helloworld", "apiversion"},
   108  			expectedExitCode: 0,
   109  			expectedOut:      "", // Will be the client version, but the specifics aren't important so long as stderr is empty.
   110  			expectedErr:      icmd.None,
   111  		},
   112  	} {
   113  		t.Run(tc.name, func(t *testing.T) {
   114  			res := icmd.RunCmd(run(tc.args...))
   115  			res.Assert(t, icmd.Expected{
   116  				ExitCode: tc.expectedExitCode,
   117  				Out:      tc.expectedOut,
   118  				Err:      tc.expectedErr,
   119  			})
   120  		})
   121  	}
   122  }
   123  
   124  // TestUnknownGlobal checks that unknown globals report errors
   125  func TestUnknownGlobal(t *testing.T) {
   126  	run, _, cleanup := prepare(t)
   127  	defer cleanup()
   128  
   129  	for name, args := range map[string][]string{
   130  		"no-val":       {"--unknown", "helloworld"},
   131  		"separate-val": {"--unknown", "foo", "helloworld"},
   132  		"joined-val":   {"--unknown=foo", "helloworld"},
   133  	} {
   134  		args := args
   135  		t.Run(name, func(t *testing.T) {
   136  			res := icmd.RunCmd(run(args...))
   137  			res.Assert(t, icmd.Expected{
   138  				ExitCode: 125,
   139  				Out:      icmd.None,
   140  				Err:      "unknown flag: --unknown",
   141  			})
   142  		})
   143  	}
   144  }
   145  
   146  // TestCliPluginsVersion checks that `-v` and friends DTRT
   147  func TestCliPluginsVersion(t *testing.T) {
   148  	run, _, cleanup := prepare(t)
   149  	defer cleanup()
   150  
   151  	for _, tc := range []struct {
   152  		name           string
   153  		args           []string
   154  		expCode        int
   155  		expOut, expErr string
   156  	}{
   157  		{
   158  			name:    "global-version",
   159  			args:    []string{"version"},
   160  			expCode: 0,
   161  			expOut:  "Client:\n Version:",
   162  			expErr:  icmd.None,
   163  		},
   164  		{
   165  			name:    "global-version-flag",
   166  			args:    []string{"--version"},
   167  			expCode: 0,
   168  			expOut:  "Docker version",
   169  			expErr:  icmd.None,
   170  		},
   171  		{
   172  			name:    "global-short-version-flag",
   173  			args:    []string{"-v"},
   174  			expCode: 0,
   175  			expOut:  "Docker version",
   176  			expErr:  icmd.None,
   177  		},
   178  		{
   179  			name:    "global-with-unknown-arg",
   180  			args:    []string{"version", "foo"},
   181  			expCode: 1,
   182  			expOut:  icmd.None,
   183  			expErr:  `"docker version" accepts no arguments.`,
   184  		},
   185  		{
   186  			name:    "global-with-plugin-arg",
   187  			args:    []string{"version", "helloworld"},
   188  			expCode: 1,
   189  			expOut:  icmd.None,
   190  			expErr:  `"docker version" accepts no arguments.`,
   191  		},
   192  		{
   193  			name:    "global-version-flag-with-unknown-arg",
   194  			args:    []string{"--version", "foo"},
   195  			expCode: 0,
   196  			expOut:  "Docker version",
   197  			expErr:  icmd.None,
   198  		},
   199  		{
   200  			name:    "global-short-version-flag-with-unknown-arg",
   201  			args:    []string{"-v", "foo"},
   202  			expCode: 0,
   203  			expOut:  "Docker version",
   204  			expErr:  icmd.None,
   205  		},
   206  		{
   207  			name:    "global-version-flag-with-plugin",
   208  			args:    []string{"--version", "helloworld"},
   209  			expCode: 125,
   210  			expOut:  icmd.None,
   211  			expErr:  "unknown flag: --version",
   212  		},
   213  		{
   214  			name:    "global-short-version-flag-with-plugin",
   215  			args:    []string{"-v", "helloworld"},
   216  			expCode: 125,
   217  			expOut:  icmd.None,
   218  			expErr:  "unknown shorthand flag: 'v' in -v",
   219  		},
   220  		{
   221  			name:    "plugin-with-version",
   222  			args:    []string{"helloworld", "version"},
   223  			expCode: 0,
   224  			expOut:  "Hello World!",
   225  			expErr:  icmd.None,
   226  		},
   227  		{
   228  			name:    "plugin-with-version-flag",
   229  			args:    []string{"helloworld", "--version"},
   230  			expCode: 125,
   231  			expOut:  icmd.None,
   232  			expErr:  "unknown flag: --version",
   233  		},
   234  		{
   235  			name:    "plugin-with-short-version-flag",
   236  			args:    []string{"helloworld", "-v"},
   237  			expCode: 125,
   238  			expOut:  icmd.None,
   239  			expErr:  "unknown shorthand flag: 'v' in -v",
   240  		},
   241  		{
   242  			name:    "",
   243  			args:    []string{},
   244  			expCode: 0,
   245  			expOut:  "",
   246  			expErr:  "",
   247  		},
   248  	} {
   249  		t.Run(tc.name, func(t *testing.T) {
   250  			res := icmd.RunCmd(run(tc.args...))
   251  			res.Assert(t, icmd.Expected{
   252  				ExitCode: tc.expCode,
   253  				Out:      tc.expOut,
   254  				Err:      tc.expErr,
   255  			})
   256  		})
   257  	}
   258  
   259  }