package commandkit import ( "reflect" "testing" commandmeta "gitea.maximumdirect.net/eric/CommandKit/internal/commandmeta" ) func newReportingParseApp(t *testing.T) *App { t.Helper() app, err := New(Identity{Name: "Example"}, flagAliasCommand("run", stringFlag("message", "")), FlagAlias("-q", "--quiet"), FlagAlias("-v", "--verbose"), FlagAlias("-d", "--debug"), ) if err != nil { t.Fatal(err) } return app } func TestReportingModeReductionFollowsFlagOccurrenceOrder(t *testing.T) { for _, test := range []struct { name string args []string mode commandmeta.ReportingMode }{ {"quiet then verbose", []string{"run", "--quiet", "--verbose"}, commandmeta.ReportingModeVerbose}, {"debug then quiet", []string{"run", "--debug", "--quiet"}, commandmeta.ReportingModeQuiet}, {"repeated verbose", []string{"run", "--verbose", "--verbose"}, commandmeta.ReportingModeVerbose}, {"clear selected repeated mode", []string{"run", "--verbose", "--verbose=false"}, commandmeta.ReportingModeNormal}, {"clear other mode has no effect", []string{"run", "--quiet", "--verbose=false"}, commandmeta.ReportingModeQuiet}, {"clear current after switch", []string{"run", "--verbose", "--quiet", "--quiet=false"}, commandmeta.ReportingModeNormal}, {"disabled quiet then debug", []string{"run", "--quiet=false", "--debug"}, commandmeta.ReportingModeDebug}, {"disabled quiet leaves verbose", []string{"run", "--verbose", "--quiet=false"}, commandmeta.ReportingModeVerbose}, } { t.Run(test.name, func(t *testing.T) { result := newReportingParseApp(t).parse(test.args, commandmeta.ParseOptions{}) if result.Failure != nil || result.Reporting.Mode != test.mode { t.Fatalf("parse result = %#v, want mode %d", result, test.mode) } }) } } func TestProgressSelectionIsIndependentAndUsesLastOccurrence(t *testing.T) { for _, test := range []struct { name string args []string mode commandmeta.ReportingMode progress bool progressSet bool }{ {"explicit false before debug", []string{"run", "--progress=false", "--debug"}, commandmeta.ReportingModeDebug, false, true}, {"explicit false after debug", []string{"run", "--debug", "--progress=false"}, commandmeta.ReportingModeDebug, false, true}, {"explicit true in verbose", []string{"run", "--verbose", "--progress"}, commandmeta.ReportingModeVerbose, true, true}, {"quiet keeps independent setting", []string{"run", "--progress", "--quiet"}, commandmeta.ReportingModeQuiet, true, true}, {"unset by default", []string{"run", "--verbose"}, commandmeta.ReportingModeVerbose, false, false}, } { t.Run(test.name, func(t *testing.T) { result := newReportingParseApp(t).parse(test.args, commandmeta.ParseOptions{}) selection := result.Reporting if result.Failure != nil || selection.Mode != test.mode || selection.Progress != test.progress || selection.ProgressSet != test.progressSet { t.Fatalf("parse selection = %#v, failure = %v", selection, result.Failure) } }) } } func TestReportingParseRetainsAliasesAndConsumedPrefix(t *testing.T) { app := newReportingParseApp(t) result := app.parse([]string{"run", "--verbose", "-q"}, commandmeta.ParseOptions{}) if result.Failure != nil || result.Reporting.Mode != commandmeta.ReportingModeQuiet { t.Fatalf("aliased selection = %#v", result) } want := []commandmeta.FlagOccurrence{ {Name: "verbose", Spelling: "--verbose", RawValue: "true"}, {Name: "quiet", Spelling: "-q", RawValue: "true"}, } if !reflect.DeepEqual(result.FlagOccurrences, want) { t.Fatalf("occurrences = %#v, want %#v", result.FlagOccurrences, want) } result = app.parse([]string{"run", "--verbose", "--unknown", "--quiet"}, commandmeta.ParseOptions{}) if result.Failure == nil || result.Reporting.Mode != commandmeta.ReportingModeVerbose || len(result.FlagOccurrences) != 1 { t.Fatalf("unknown flag partial selection = %#v", result) } result = app.parse([]string{"run", "--verbose", "--quiet=invalid", "--debug"}, commandmeta.ParseOptions{}) if result.Failure == nil || !result.Failure.Usage || result.Reporting.Mode != commandmeta.ReportingModeVerbose || len(result.FlagOccurrences) != 2 { t.Fatalf("invalid boolean partial selection = %#v", result) } } func TestReportingParsePreservesValuesHelpAndTerminator(t *testing.T) { app := newReportingParseApp(t) result := app.parse([]string{"run", "--message=--quiet", "--verbose", "--", "--debug"}, commandmeta.ParseOptions{}) if result.Failure != nil || result.Reporting.Mode != commandmeta.ReportingModeVerbose || !reflect.DeepEqual(result.Operands, []string{"--debug"}) { t.Fatalf("option-looking value or terminator = %#v", result) } if len(result.FlagOccurrences) != 2 || result.FlagOccurrences[0].Name != "message" || result.FlagOccurrences[0].RawValue != "--quiet" { t.Fatalf("reporting-like value became a flag occurrence: %#v", result.FlagOccurrences) } result = app.parse([]string{"run", "--help=bad", "--quiet"}, commandmeta.ParseOptions{}) if result.Failure == nil || result.Reporting.Mode != commandmeta.ReportingModeNormal || len(result.FlagOccurrences) != 1 || result.FlagOccurrences[0].Name != "help" { t.Fatalf("invalid help boolean consumed later flags: %#v", result) } result = app.parse([]string{"run", "--help=false", "--quiet"}, commandmeta.ParseOptions{}) if result.Failure != nil || result.HelpRequested || result.Reporting.Mode != commandmeta.ReportingModeQuiet { t.Fatalf("valid false help boolean changed handling: %#v", result) } result = app.parse([]string{"missing", "--quiet"}, commandmeta.ParseOptions{}) if result.Failure == nil || len(result.FlagOccurrences) != 0 { t.Fatalf("malformed path produced flag occurrences: %#v", result) } }