package commandkit import ( "bytes" "context" "encoding/json" "reflect" "strings" "testing" commandmeta "go.maximumdirect.net/commandkit/internal/commandmeta" ) func TestSharedFormatFlag(t *testing.T) { factories, runs := 0, 0 command := NewCommand(CommandSpec[struct{}]{Name: "run", NewInput: func() struct{} { factories++; return struct{}{} }, Run: func(inv Invocation, _ struct{}) Outcome { runs++ _ = inv.Reporter().Report(Report{Value: map[string]any{"answer": 42}}) return Success() }}) app, err := New(Identity{Name: "Example", Version: "1"}, command, FlagAlias("--fmt", "--format")) if err != nil { t.Fatal(err) } for _, tc := range []struct { args []string expected string }{ {[]string{"run", "--format", "text"}, "yaml"}, {[]string{"run", "--format=yaml"}, "yaml"}, {[]string{"run", "--fmt=json"}, "json"}, {[]string{"run", "--format=yaml", "--fmt", "json"}, "json"}, {[]string{"run"}, "yaml"}, } { var out bytes.Buffer got := app.Execute(context.Background(), tc.args, Streams{Out: &out}) if got.Status != 0 { t.Fatalf("%v: %#v", tc.args, got) } var value any if tc.expected == "json" { dec := json.NewDecoder(&out) dec.UseNumber() err = dec.Decode(&value) } else { value, err = DecodeYAMLReport(&out) } if err != nil || !reflect.DeepEqual(value, map[string]any{"answer": json.Number("42")}) { t.Fatalf("%v: %#v %v", tc.args, value, err) } } beforeFactories, beforeRuns := factories, runs for _, args := range [][]string{{"run", "--format="}, {"run", "--fmt=xml"}, {"run", "--format=bad", "--format=json"}, {"run", "--format", "--quiet"}} { var diagnostics bytes.Buffer got := app.Execute(context.Background(), args, Streams{Err: &diagnostics}) if got.Kind != OutcomeUsage || !strings.Contains(diagnostics.String(), "format") { t.Fatalf("%v: %#v %q", args, got, &diagnostics) } } if factories != beforeFactories || runs != beforeRuns { t.Fatalf("invalid formats ran domain code: factories %d, runs %d", factories, runs) } var help bytes.Buffer got := app.Execute(context.Background(), []string{"run", "--help"}, Streams{Out: &help}) if got.Status != 0 || !strings.Contains(help.String(), "--format") || factories != beforeFactories || runs != beforeRuns { t.Fatalf("help: %#v, %q", got, &help) } } func TestSharedFormatParseOrderAndTerminator(t *testing.T) { app, err := New(Identity{Name: "Example"}, flagAliasCommand("run", stringFlag("message", "")), FlagAlias("--fmt", "--format")) if err != nil { t.Fatal(err) } result := parseReportingArgs(app, []string{"run", "--verbose", "--fmt", "json", "--quiet", "--message=--format", "--", "--format=yaml"}) if result.Failure != nil || result.Reporting.Format != "json" || result.Reporting.Mode != commandmeta.ReportingModeQuiet || !reflect.DeepEqual(result.Operands, []string{"--format=yaml"}) { t.Fatalf("%#v", result) } if result.FlagOccurrences[1].Spelling != "--fmt" || result.FlagOccurrences[1].RawValue != "json" { t.Fatalf("%#v", result.FlagOccurrences) } }