Files
commandkit/internal/cobra/flags_test.go

138 lines
7.1 KiB
Go

package cobra
import (
"reflect"
"testing"
commandmeta "gitea.maximumdirect.net/eric/CommandKit/internal/commandmeta"
)
func flagGrammarTree() *commandmeta.Command {
return &commandmeta.Command{Name: "app", Children: []*commandmeta.Command{{
Name: "run", Runnable: true,
Flags: []commandmeta.Flag{
{Name: "color", Short: "c"},
{Name: "verbose", Short: "v", Boolean: true},
{Name: "quiet", Short: "q", Boolean: true},
{Name: "message", Short: "m"},
{Name: "tag", Short: "t", Repeated: true},
},
}}}
}
func flagGrammarOptions() ParseOptions {
return ParseOptions{FlagAliases: []commandmeta.FlagAlias{
{Source: "--colour", Target: "--color"},
{Source: "-C", Target: "--color"},
{Source: "-w", Target: "--verbose"},
{Source: "-z", Target: "--quiet"},
{Source: "--taggy", Target: "-t"},
{Source: "--hlep", Target: "--help"},
}}
}
func TestParseCanonicalAndAliasShortGrammar(t *testing.T) {
for _, test := range []struct {
name string
args []string
values [][]string
spellings [][]string
}{
{"boolean cluster", []string{"run", "-vq"}, [][]string{nil, {"true"}, {"true"}, nil, nil}, [][]string{nil, {"-v"}, {"-q"}, nil, nil}},
{"aliased boolean cluster", []string{"run", "-wz"}, [][]string{nil, {"true"}, {"true"}, nil, nil}, [][]string{nil, {"-w"}, {"-z"}, nil, nil}},
{"value short separated", []string{"run", "-c", "blue"}, [][]string{{"blue"}, nil, nil, nil, nil}, [][]string{{"-c"}, nil, nil, nil, nil}},
{"value short equals", []string{"run", "-c=blue"}, [][]string{{"blue"}, nil, nil, nil, nil}, [][]string{{"-c"}, nil, nil, nil, nil}},
{"value short attached", []string{"run", "-cblue"}, [][]string{{"blue"}, nil, nil, nil, nil}, [][]string{{"-c"}, nil, nil, nil, nil}},
{"long alias", []string{"run", "--colour=blue"}, [][]string{{"blue"}, nil, nil, nil, nil}, [][]string{{"--colour"}, nil, nil, nil, nil}},
{"short alias", []string{"run", "-Cblue"}, [][]string{{"blue"}, nil, nil, nil, nil}, [][]string{{"-C"}, nil, nil, nil, nil}},
{"cluster value consumes suffix", []string{"run", "-vqcblue"}, [][]string{{"blue"}, {"true"}, {"true"}, nil, nil}, [][]string{{"-c"}, {"-v"}, {"-q"}, nil, nil}},
{"cluster value consumes next", []string{"run", "-vqc", "blue"}, [][]string{{"blue"}, {"true"}, {"true"}, nil, nil}, [][]string{{"-c"}, {"-v"}, {"-q"}, nil, nil}},
{"mixed canonical and alias cluster", []string{"run", "-wqcblue"}, [][]string{{"blue"}, {"true"}, {"true"}, nil, nil}, [][]string{{"-c"}, {"-w"}, {"-q"}, nil, nil}},
{"value takes remaining suffix", []string{"run", "-cvq"}, [][]string{{"vq"}, nil, nil, nil, nil}, [][]string{{"-c"}, nil, nil, nil, nil}},
{"boolean explicit false", []string{"run", "-v=false"}, [][]string{nil, {"false"}, nil, nil, nil}, [][]string{nil, {"-v"}, nil, nil, nil}},
{"boolean explicit false in cluster", []string{"run", "-qv=false"}, [][]string{nil, {"false"}, {"true"}, nil, nil}, [][]string{nil, {"-v"}, {"-q"}, nil, nil}},
{"empty canonical short", []string{"run", "-c="}, [][]string{{""}, nil, nil, nil, nil}, [][]string{{"-c"}, nil, nil, nil, nil}},
{"empty canonical long", []string{"run", "--color="}, [][]string{{""}, nil, nil, nil, nil}, [][]string{{"--color"}, nil, nil, nil, nil}},
{"empty separated short", []string{"run", "-c", ""}, [][]string{{""}, nil, nil, nil, nil}, [][]string{{"-c"}, nil, nil, nil, nil}},
{"empty aliased long", []string{"run", "--colour="}, [][]string{{""}, nil, nil, nil, nil}, [][]string{{"--colour"}, nil, nil, nil, nil}},
{"empty aliased short", []string{"run", "-C="}, [][]string{{""}, nil, nil, nil, nil}, [][]string{{"-C"}, nil, nil, nil, nil}},
{"empty boolean short", []string{"run", "-v="}, [][]string{nil, {""}, nil, nil, nil}, [][]string{nil, {"-v"}, nil, nil, nil}},
} {
t.Run(test.name, func(t *testing.T) {
result := Parse(flagGrammarTree(), test.args, flagGrammarOptions())
if result.Failure != nil {
t.Fatalf("parse failed: %s", result.Failure.Message)
}
if !reflect.DeepEqual(result.FlagValues, test.values) {
t.Errorf("values = %#v, want %#v", result.FlagValues, test.values)
}
if !reflect.DeepEqual(result.FlagSpellings, test.spellings) {
t.Errorf("spellings = %#v, want %#v", result.FlagSpellings, test.spellings)
}
})
}
}
func TestParseFlagAliasesPreserveValuesAndTerminators(t *testing.T) {
result := Parse(flagGrammarTree(), []string{"run", "--message", "--hlep", "--message=--hlep", "--taggy", "one", "--", "--taggy"}, flagGrammarOptions())
if result.Failure != nil {
t.Fatalf("parse failed: %s", result.Failure.Message)
}
if got, want := result.FlagValues[3], []string{"--hlep", "--hlep"}; !reflect.DeepEqual(got, want) {
t.Fatalf("message values = %#v, want %#v", got, want)
}
if got, want := result.FlagSpellings[3], []string{"--message", "--message"}; !reflect.DeepEqual(got, want) {
t.Fatalf("message spellings = %#v, want %#v", got, want)
}
if got, want := result.FlagValues[4], []string{"one"}; !reflect.DeepEqual(got, want) {
t.Fatalf("tag values = %#v, want %#v", got, want)
}
if got, want := result.Operands, []string{"--taggy"}; !reflect.DeepEqual(got, want) {
t.Fatalf("operands = %#v, want %#v", got, want)
}
}
func TestParseHelpAliasAndUnknownShortMembers(t *testing.T) {
result := Parse(flagGrammarTree(), []string{"run", "--hlep"}, flagGrammarOptions())
if result.Failure != nil || !result.HelpRequested {
t.Fatalf("help alias result = %#v", result)
}
result = Parse(flagGrammarTree(), []string{"run", "-vx"}, flagGrammarOptions())
if result.Failure == nil || result.Failure.Message == "" {
t.Fatalf("unknown short cluster member result = %#v", result)
}
result = Parse(flagGrammarTree(), []string{"run", "--color"}, flagGrammarOptions())
if result.Failure == nil || result.Failure.Message == "" {
t.Fatalf("missing value result = %#v", result)
}
result = Parse(flagGrammarTree(), []string{"run", "--colour"}, flagGrammarOptions())
if result.Failure == nil || result.Failure.Message == "" {
t.Fatalf("missing aliased value result = %#v", result)
}
result = Parse(flagGrammarTree(), []string{"run", "-c"}, flagGrammarOptions())
if result.Failure == nil || result.Failure.Message == "" {
t.Fatalf("missing short value result = %#v", result)
}
result = Parse(flagGrammarTree(), []string{"run", "-C"}, flagGrammarOptions())
if result.Failure == nil || result.Failure.Message == "" {
t.Fatalf("missing aliased short value result = %#v", result)
}
result = Parse(flagGrammarTree(), []string{"run", "-vfalse"}, flagGrammarOptions())
if result.Failure == nil || result.Failure.Message == "" {
t.Fatalf("boolean suffix without equals result = %#v", result)
}
}
func TestParseFlagAliasOccurrenceOrderAndSpellings(t *testing.T) {
result := Parse(flagGrammarTree(), []string{"run", "--taggy=first", "-t", "second", "--taggy", "third"}, flagGrammarOptions())
if result.Failure != nil {
t.Fatalf("parse failed: %s", result.Failure.Message)
}
if got, want := result.FlagValues[4], []string{"first", "second", "third"}; !reflect.DeepEqual(got, want) {
t.Fatalf("tag values = %#v, want %#v", got, want)
}
if got, want := result.FlagSpellings[4], []string{"--taggy", "-t", "--taggy"}; !reflect.DeepEqual(got, want) {
t.Fatalf("tag spellings = %#v, want %#v", got, want)
}
}