...

Source file src/edge-infra.dev/pkg/lib/cli/command/command_test.go

Documentation: edge-infra.dev/pkg/lib/cli/command

     1  package command
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  
    10  	"edge-infra.dev/pkg/lib/cli/rags"
    11  )
    12  
    13  var testCases = []struct {
    14  	cmd              *Command
    15  	expectedLongName string
    16  	expectedName     string
    17  	expectedErr      error
    18  }{
    19  	{
    20  		// root command, no extensions, 3 subcommands
    21  		cmd: &Command{
    22  			ShortUsage: "lift",
    23  			Commands: []*Command{
    24  				{ShortUsage: "subcmd1"},
    25  				{ShortUsage: "subcmd2"},
    26  				{ShortUsage: "subcmd3"},
    27  			},
    28  		},
    29  		expectedLongName: "",
    30  		expectedName:     "",
    31  	},
    32  	{
    33  		// 1 subcommand, 1 extension
    34  		cmd: &Command{
    35  			ShortUsage: "lift pack [flags] <package paths...>",
    36  			ShortHelp:  "packs stuff up",
    37  			LongHelp:   "packs stuff up --but longer",
    38  			Extensions: []Extension{&testExtension{name: "ext1"}},
    39  			Exec: func(_ context.Context, _ []string) error {
    40  				return nil
    41  			},
    42  		},
    43  		expectedLongName: "pack",
    44  		expectedName:     "pack",
    45  	},
    46  	{
    47  		// 2 subcommand, 2 extensions
    48  		cmd: &Command{
    49  			ShortUsage: "edge clustersecret view [flags] <args>",
    50  			ShortHelp:  "clustersecret view sees all",
    51  			LongHelp:   "it really does see everything",
    52  			Extensions: []Extension{&testExtension{name: "ext1"}, &testExtension{name: "ext2"}},
    53  		},
    54  		expectedLongName: "clustersecret view",
    55  		expectedName:     "view",
    56  	},
    57  	{
    58  		// 3 subcommand, 2 valid extensions, 1 faulty extension in the middle
    59  		cmd: &Command{
    60  			ShortUsage: "root subcmd1 subcmd2 subcmd3 [flags] <args>",
    61  			ShortHelp:  "definitely does something",
    62  			LongHelp:   "does something described in more detail",
    63  			Extensions: []Extension{&testExtension{name: "ext1"}, &faultyExtension{},
    64  				&testExtension{name: "ext2"}},
    65  			Exec: func(_ context.Context, _ []string) error {
    66  				return nil
    67  			},
    68  		},
    69  		expectedLongName: "subcmd1 subcmd2 subcmd3",
    70  		expectedName:     "subcmd3",
    71  		expectedErr:      fmt.Errorf("Faulty extension AfterParse"),
    72  	},
    73  }
    74  
    75  type testExtension struct {
    76  	name               string
    77  	finishedAfterParse bool
    78  	stringFlag         string
    79  	boolFlag           bool
    80  }
    81  
    82  type faultyExtension struct{}
    83  
    84  func (ext *testExtension) RegisterFlags(rs *rags.RagSet) {
    85  	rs.StringVar(&ext.stringFlag, ext.name+"-string-flag", "default string value", "string usage message")
    86  	rs.BoolVar(&ext.boolFlag, ext.name+"-bool-flag", false, "bool usage message")
    87  }
    88  
    89  func (ext *testExtension) AfterParse() error {
    90  	ext.finishedAfterParse = true
    91  	return nil
    92  }
    93  
    94  func (ext *faultyExtension) RegisterFlags(_ *rags.RagSet) {}
    95  
    96  func (ext *faultyExtension) AfterParse() error {
    97  	return fmt.Errorf("Faulty extension AfterParse")
    98  }
    99  
   100  // test name related functionality
   101  
   102  func TestLongName(t *testing.T) {
   103  	for _, tc := range testCases {
   104  		assert.Equal(t, tc.expectedLongName, tc.cmd.LongName())
   105  	}
   106  }
   107  
   108  func TestName(t *testing.T) {
   109  	for _, tc := range testCases {
   110  		assert.Equal(t, tc.expectedName, tc.cmd.Name())
   111  	}
   112  }
   113  
   114  // testing afterParse() and wExec()
   115  func TestAfterParse(t *testing.T) {
   116  	for _, tc := range testCases {
   117  		_, err := tc.cmd.afterParse(context.TODO())
   118  		for _, e := range tc.cmd.Extensions {
   119  			// checks to see that every extension either successfully finished AfterParse
   120  			// or if an error was encountered, that execution of afterParse immediately halts
   121  			seenFaultyExt := false
   122  			if ext, ok := e.(*testExtension); ok {
   123  				assert.Equal(t, !seenFaultyExt, ext.finishedAfterParse)
   124  			} else if _, ok := e.(*faultyExtension); ok {
   125  				assert.Equal(t, err, fmt.Errorf("Faulty extension AfterParse"))
   126  				break
   127  			}
   128  		}
   129  	}
   130  }
   131  
   132  func TestWExec(t *testing.T) {
   133  	for _, tc := range testCases {
   134  		// only test commands with execs since nil values aren't
   135  		// filled in until Command() is called
   136  		if tc.cmd.Exec != nil {
   137  			wrappedExec := tc.cmd.wExec()
   138  			assert.Equal(t, tc.expectedErr, wrappedExec(nil, nil))
   139  		}
   140  	}
   141  }
   142  
   143  // testing Command()
   144  func TestCommand(t *testing.T) {
   145  	for _, tc := range testCases {
   146  		cmd := tc.cmd.Command()
   147  		assert.NotNil(t, cmd)
   148  
   149  		// checking flagset was properly initialized
   150  		assert.Equal(t, tc.cmd.ShortUsage, cmd.FlagSet.Name())
   151  		fs := tc.cmd.Rags.FlagSet()
   152  		for _, e := range tc.cmd.Extensions {
   153  			if ext, ok := e.(*testExtension); ok {
   154  				assert.NotNil(t, fs.Lookup(ext.name+"-string-flag"))
   155  				assert.NotNil(t, fs.Lookup(ext.name+"-bool-flag"))
   156  			}
   157  		}
   158  
   159  		// checking basic command fields are populated
   160  		assert.Equal(t, tc.cmd.Name(), cmd.Name)
   161  		assert.Equal(t, tc.cmd.ShortUsage, cmd.ShortUsage)
   162  		assert.Equal(t, tc.cmd.ShortHelp, cmd.ShortHelp)
   163  		assert.Equal(t, tc.cmd.LongHelp, cmd.LongHelp)
   164  		assert.NotNil(t, cmd.Options)
   165  		assert.NotNil(t, cmd.UsageFunc)
   166  		assert.NotNil(t, cmd.Exec)
   167  
   168  		// checking all subcommands were added
   169  		assert.Equal(t, len(tc.cmd.Commands), len(cmd.Subcommands))
   170  	}
   171  }
   172  

View as plain text