github.com/prysmaticlabs/prysm@v1.4.4/shared/cmd/flags_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"flag"
     5  	"io/ioutil"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    10  	"github.com/urfave/cli/v2"
    11  )
    12  
    13  func TestLoadFlagsFromConfig(t *testing.T) {
    14  	app := cli.App{}
    15  	set := flag.NewFlagSet("test", 0)
    16  	context := cli.NewContext(&app, set, nil)
    17  
    18  	require.NoError(t, ioutil.WriteFile("flags_test.yaml", []byte("testflag: 100"), 0666))
    19  
    20  	require.NoError(t, set.Parse([]string{"test-command", "--" + ConfigFileFlag.Name, "flags_test.yaml"}))
    21  	command := &cli.Command{
    22  		Name: "test-command",
    23  		Flags: WrapFlags([]cli.Flag{
    24  			&cli.StringFlag{
    25  				Name: ConfigFileFlag.Name,
    26  			},
    27  			&cli.IntFlag{
    28  				Name:  "testflag",
    29  				Value: 0,
    30  			},
    31  		}),
    32  		Before: func(cliCtx *cli.Context) error {
    33  			return LoadFlagsFromConfig(cliCtx, cliCtx.Command.Flags)
    34  		},
    35  		Action: func(cliCtx *cli.Context) error {
    36  			require.Equal(t, 100, cliCtx.Int("testflag"))
    37  			return nil
    38  		},
    39  	}
    40  	require.NoError(t, command.Run(context))
    41  	require.NoError(t, os.Remove("flags_test.yaml"))
    42  }
    43  
    44  func TestValidateNoArgs(t *testing.T) {
    45  	app := &cli.App{
    46  		Before: ValidateNoArgs,
    47  		Action: func(c *cli.Context) error {
    48  			return nil
    49  		},
    50  		Flags: []cli.Flag{
    51  			&cli.StringFlag{
    52  				Name: "foo",
    53  			},
    54  		},
    55  		Commands: []*cli.Command{
    56  			{
    57  				Name: "bar",
    58  				Subcommands: []*cli.Command{
    59  					{
    60  						Name: "subComm1",
    61  						Subcommands: []*cli.Command{
    62  							{
    63  								Name: "subComm3",
    64  							},
    65  						},
    66  					},
    67  					{
    68  						Name: "subComm2",
    69  						Subcommands: []*cli.Command{
    70  							{
    71  								Name: "subComm4",
    72  							},
    73  						},
    74  					},
    75  				},
    76  			},
    77  		},
    78  	}
    79  
    80  	// It should not work with a bogus argument
    81  	err := app.Run([]string{"command", "foo"})
    82  	require.ErrorContains(t, "unrecognized argument: foo", err)
    83  	// It should work with registered flags
    84  	err = app.Run([]string{"command", "--foo=bar"})
    85  	require.NoError(t, err)
    86  	// It should work with subcommands.
    87  	err = app.Run([]string{"command", "bar"})
    88  	require.NoError(t, err)
    89  	// It should fail on unregistered flag (default logic in urfave/cli).
    90  	err = app.Run([]string{"command", "bar", "--baz"})
    91  	require.ErrorContains(t, "flag provided but not defined", err)
    92  
    93  	// Handle Nested Subcommands
    94  
    95  	err = app.Run([]string{"command", "bar", "subComm1"})
    96  	require.NoError(t, err)
    97  
    98  	err = app.Run([]string{"command", "bar", "subComm2"})
    99  	require.NoError(t, err)
   100  
   101  	// Should fail from unknown subcommands.
   102  	err = app.Run([]string{"command", "bar", "subComm3"})
   103  	require.ErrorContains(t, "unrecognized argument: subComm3", err)
   104  
   105  	err = app.Run([]string{"command", "bar", "subComm4"})
   106  	require.ErrorContains(t, "unrecognized argument: subComm4", err)
   107  
   108  	// Should fail with invalid double nested subcommands.
   109  	err = app.Run([]string{"command", "bar", "subComm1", "subComm2"})
   110  	require.ErrorContains(t, "unrecognized argument: subComm2", err)
   111  
   112  	err = app.Run([]string{"command", "bar", "subComm1", "subComm4"})
   113  	require.ErrorContains(t, "unrecognized argument: subComm4", err)
   114  
   115  	err = app.Run([]string{"command", "bar", "subComm2", "subComm1"})
   116  	require.ErrorContains(t, "unrecognized argument: subComm1", err)
   117  
   118  	err = app.Run([]string{"command", "bar", "subComm2", "subComm3"})
   119  	require.ErrorContains(t, "unrecognized argument: subComm3", err)
   120  
   121  	// Should pass with correct nested double subcommands.
   122  	err = app.Run([]string{"command", "bar", "subComm1", "subComm3"})
   123  	require.NoError(t, err)
   124  
   125  	err = app.Run([]string{"command", "bar", "subComm2", "subComm4"})
   126  	require.NoError(t, err)
   127  }
   128  
   129  func TestValidateNoArgs_SubcommandFlags(t *testing.T) {
   130  	app := &cli.App{
   131  		Before: ValidateNoArgs,
   132  		Action: func(c *cli.Context) error {
   133  			return nil
   134  		},
   135  		Flags: []cli.Flag{
   136  			&cli.StringFlag{
   137  				Name: "foo",
   138  			},
   139  		},
   140  		Commands: []*cli.Command{
   141  			{
   142  				Name: "bar",
   143  				Subcommands: []*cli.Command{
   144  					{
   145  						Name: "subComm1",
   146  						Subcommands: []*cli.Command{
   147  							{
   148  								Name: "subComm3",
   149  							},
   150  						},
   151  						Flags: []cli.Flag{
   152  							&cli.StringFlag{
   153  								Name: "barfoo2",
   154  							},
   155  							&cli.BoolFlag{
   156  								Name: "barfoo99",
   157  							},
   158  						},
   159  					},
   160  					{
   161  						Name: "subComm2",
   162  						Subcommands: []*cli.Command{
   163  							{
   164  								Name: "subComm4",
   165  							},
   166  						},
   167  						Flags: []cli.Flag{
   168  							&cli.StringFlag{
   169  								Name: "barfoo3",
   170  							},
   171  							&cli.BoolFlag{
   172  								Name: "barfoo100",
   173  							},
   174  						},
   175  					},
   176  				},
   177  				Flags: []cli.Flag{
   178  					&cli.StringFlag{
   179  						Name: "barfoo1",
   180  					},
   181  				},
   182  			},
   183  		},
   184  	}
   185  
   186  	// It should not work with a bogus argument
   187  	err := app.Run([]string{"command", "foo"})
   188  	require.ErrorContains(t, "unrecognized argument: foo", err)
   189  	// It should work with registered flags
   190  	err = app.Run([]string{"command", "--foo=bar"})
   191  	require.NoError(t, err)
   192  
   193  	// It should work with registered flags with spaces.
   194  	err = app.Run([]string{"command", "--foo", "bar"})
   195  	require.NoError(t, err)
   196  
   197  	// Handle Nested Subcommands and its flags
   198  
   199  	err = app.Run([]string{"command", "bar", "--barfoo1=xyz"})
   200  	require.NoError(t, err)
   201  
   202  	err = app.Run([]string{"command", "bar", "--barfoo1", "xyz"})
   203  	require.NoError(t, err)
   204  
   205  	// Should pass with correct nested double subcommands.
   206  	err = app.Run([]string{"command", "bar", "subComm1", "--barfoo2=xyz"})
   207  	require.NoError(t, err)
   208  
   209  	err = app.Run([]string{"command", "bar", "subComm1", "--barfoo2", "xyz"})
   210  	require.NoError(t, err)
   211  
   212  	err = app.Run([]string{"command", "bar", "subComm2", "--barfoo3=xyz"})
   213  	require.NoError(t, err)
   214  
   215  	err = app.Run([]string{"command", "bar", "subComm2", "--barfoo3", "xyz"})
   216  	require.NoError(t, err)
   217  
   218  	err = app.Run([]string{"command", "bar", "subComm2", "--barfoo3"})
   219  	require.ErrorContains(t, "flag needs an argument", err)
   220  
   221  	err = app.Run([]string{"command", "bar", "subComm1", "--barfoo99"})
   222  	require.NoError(t, err)
   223  
   224  	// Test edge case with boolean flags, as they do not require spaced arguments.
   225  	app.CommandNotFound = func(context *cli.Context, s string) {
   226  		require.Equal(t, "garbage", s)
   227  	}
   228  	err = app.Run([]string{"command", "bar", "subComm1", "--barfoo99", "garbage"})
   229  	require.ErrorContains(t, "unrecognized argument: garbage", err)
   230  
   231  	err = app.Run([]string{"command", "bar", "subComm1", "--barfoo99", "garbage", "subComm3"})
   232  	require.ErrorContains(t, "unrecognized argument: garbage", err)
   233  
   234  	err = app.Run([]string{"command", "bar", "subComm2", "--barfoo100", "garbage"})
   235  	require.ErrorContains(t, "unrecognized argument: garbage", err)
   236  
   237  	err = app.Run([]string{"command", "bar", "subComm2", "--barfoo100", "garbage", "subComm4"})
   238  	require.ErrorContains(t, "unrecognized argument: garbage", err)
   239  }