github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/elvish/getopt/getopt_test.go (about)

     1  package getopt
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  )
     7  
     8  var options = []*Option{
     9  	{'a', "all", NoArgument},
    10  	{'o', "option", RequiredArgument},
    11  	{'n', "number", OptionalArgument},
    12  }
    13  
    14  var cases = []struct {
    15  	config   Config
    16  	elems    []string
    17  	wantOpts []*ParsedOption
    18  	wantArgs []string
    19  	wantCtx  *Context
    20  }{
    21  	// NoArgument, short option.
    22  	{0, []string{"-a", ""},
    23  		[]*ParsedOption{{options[0], false, ""}},
    24  		nil, &Context{Type: NewOptionOrArgument}},
    25  	// NoArgument, long option.
    26  	{0, []string{"--all", ""},
    27  		[]*ParsedOption{{options[0], true, ""}},
    28  		nil, &Context{Type: NewOptionOrArgument}},
    29  
    30  	// RequiredArgument, argument following the option directly
    31  	{0, []string{"-oname=elvish", ""},
    32  		[]*ParsedOption{{options[1], false, "name=elvish"}},
    33  		nil, &Context{Type: NewOptionOrArgument}},
    34  	// RequiredArgument, argument in next element
    35  	{0, []string{"-o", "name=elvish", ""},
    36  		[]*ParsedOption{{options[1], false, "name=elvish"}},
    37  		nil, &Context{Type: NewOptionOrArgument}},
    38  	// RequiredArgument, long option, argument following the option directly
    39  	{0, []string{"--option=name=elvish", ""},
    40  		[]*ParsedOption{{options[1], true, "name=elvish"}},
    41  		nil, &Context{Type: NewOptionOrArgument}},
    42  	// RequiredArgument, long option, argument in next element
    43  	{0, []string{"--option", "name=elvish", ""},
    44  		[]*ParsedOption{{options[1], true, "name=elvish"}},
    45  		nil, &Context{Type: NewOptionOrArgument}},
    46  
    47  	// OptionalArgument, with argument
    48  	{0, []string{"-n1", ""},
    49  		[]*ParsedOption{{options[2], false, "1"}},
    50  		nil, &Context{Type: NewOptionOrArgument}},
    51  	// OptionalArgument, without argument
    52  	{0, []string{"-n", ""},
    53  		[]*ParsedOption{{options[2], false, ""}},
    54  		nil, &Context{Type: NewOptionOrArgument}},
    55  
    56  	// DoubleDashTerminatesOptions
    57  	{DoubleDashTerminatesOptions, []string{"-a", "--", "-o", ""},
    58  		[]*ParsedOption{{options[0], false, ""}},
    59  		[]string{"-o"}, &Context{Type: Argument}},
    60  	// FirstArgTerminatesOptions
    61  	{FirstArgTerminatesOptions, []string{"-a", "x", "-o", ""},
    62  		[]*ParsedOption{{options[0], false, ""}},
    63  		[]string{"x", "-o"}, &Context{Type: Argument}},
    64  	// LongOnly
    65  	{LongOnly, []string{"-all", ""},
    66  		[]*ParsedOption{{options[0], true, ""}},
    67  		nil, &Context{Type: NewOptionOrArgument}},
    68  
    69  	// NewOption
    70  	{0, []string{"-"}, nil, nil, &Context{Type: NewOption}},
    71  	// NewLongOption
    72  	{0, []string{"--"}, nil, nil, &Context{Type: NewLongOption}},
    73  	// LongOption
    74  	{0, []string{"--all"}, nil, nil,
    75  		&Context{Type: LongOption, Text: "all"}},
    76  	// LongOption, LongOnly
    77  	{LongOnly, []string{"-all"}, nil, nil,
    78  		&Context{Type: LongOption, Text: "all"}},
    79  	// ChainShortOption
    80  	{0, []string{"-a"},
    81  		[]*ParsedOption{{options[0], false, ""}}, nil,
    82  		&Context{Type: ChainShortOption}},
    83  	// OptionArgument, short option, same element
    84  	{0, []string{"-o"}, nil, nil,
    85  		&Context{Type: OptionArgument,
    86  			Option: &ParsedOption{options[1], false, ""}}},
    87  	// OptionArgument, short option, separate element
    88  	{0, []string{"-o", ""}, nil, nil,
    89  		&Context{Type: OptionArgument,
    90  			Option: &ParsedOption{options[1], false, ""}}},
    91  	// OptionArgument, long option, same element
    92  	{0, []string{"--option="}, nil, nil,
    93  		&Context{Type: OptionArgument,
    94  			Option: &ParsedOption{options[1], true, ""}}},
    95  	// OptionArgument, long option, separate element
    96  	{0, []string{"--option", ""}, nil, nil,
    97  		&Context{Type: OptionArgument,
    98  			Option: &ParsedOption{options[1], true, ""}}},
    99  	// OptionArgument, long only, same element
   100  	{LongOnly, []string{"-option="}, nil, nil,
   101  		&Context{Type: OptionArgument,
   102  			Option: &ParsedOption{options[1], true, ""}}},
   103  	// OptionArgument, long only, separate element
   104  	{LongOnly, []string{"-option", ""}, nil, nil,
   105  		&Context{Type: OptionArgument,
   106  			Option: &ParsedOption{options[1], true, ""}}},
   107  	// Argument
   108  	{0, []string{"x"}, nil, nil,
   109  		&Context{Type: Argument, Text: "x"}},
   110  
   111  	// Unknown short option, same element
   112  	{0, []string{"-x"}, nil, nil,
   113  		&Context{
   114  			Type: OptionArgument,
   115  			Option: &ParsedOption{
   116  				&Option{'x', "", OptionalArgument}, false, ""}}},
   117  	// Unknown short option, separate element
   118  	{0, []string{"-x", ""},
   119  		[]*ParsedOption{{
   120  			&Option{'x', "", OptionalArgument}, false, ""}},
   121  		nil,
   122  		&Context{Type: NewOptionOrArgument}},
   123  
   124  	// Unknown long option
   125  	{0, []string{"--unknown", ""},
   126  		[]*ParsedOption{{
   127  			&Option{0, "unknown", OptionalArgument}, true, ""}},
   128  		nil,
   129  		&Context{Type: NewOptionOrArgument}},
   130  	// Unknown long option, with argument
   131  	{0, []string{"--unknown=value", ""},
   132  		[]*ParsedOption{{
   133  			&Option{0, "unknown", OptionalArgument}, true, "value"}},
   134  		nil,
   135  		&Context{Type: NewOptionOrArgument}},
   136  
   137  	// Unknown long option, LongOnly
   138  	{LongOnly, []string{"-unknown", ""},
   139  		[]*ParsedOption{{
   140  			&Option{0, "unknown", OptionalArgument}, true, ""}},
   141  		nil,
   142  		&Context{Type: NewOptionOrArgument}},
   143  	// Unknown long option, with argument
   144  	{LongOnly, []string{"-unknown=value", ""},
   145  		[]*ParsedOption{{
   146  			&Option{0, "unknown", OptionalArgument}, true, "value"}},
   147  		nil,
   148  		&Context{Type: NewOptionOrArgument}},
   149  }
   150  
   151  func TestGetopt(t *testing.T) {
   152  	for _, tc := range cases {
   153  		g := &Getopt{options, tc.config}
   154  		opts, args, ctx := g.Parse(tc.elems)
   155  		shouldEqual := func(name string, got, want interface{}) {
   156  			if !reflect.DeepEqual(got, want) {
   157  				t.Errorf("Parse(%#v) (config = %v)\ngot %s = %v, want %v",
   158  					tc.elems, tc.config, name, got, want)
   159  			}
   160  		}
   161  		shouldEqual("opts", opts, tc.wantOpts)
   162  		shouldEqual("args", args, tc.wantArgs)
   163  		shouldEqual("ctx", ctx, tc.wantCtx)
   164  	}
   165  }