package commandkit import ( "bytes" "context" "errors" "io" "strings" "testing" ) func builtinReportingTestApp(t *testing.T) *App { t.Helper() command := NewCommand(CommandSpec[struct{}]{ Name: "run", Run: func(Invocation, struct{}) Outcome { return Success() }, }) app, err := New(Identity{Name: "Example", Version: "1.2.3"}, command, Group("promptkit", "PromptKit", Group("list", "List", simpleRunnable("collections"))), Alias("r", "run"), Alias("list collections", "promptkit list collections"), ) if err != nil { t.Fatal(err) } return app } func TestHelpAndVersionUseManagedOutput(t *testing.T) { app := builtinReportingTestApp(t) for _, args := range [][]string{{"help", "--quiet"}, {"version", "--quiet"}, {"list", "--help", "--quiet"}} { var output, diagnostics bytes.Buffer outcome := app.Execute(context.Background(), args, Streams{Out: &output, Err: &diagnostics}) if outcome.Kind != OutcomeSuccess || outcome.Status != 0 { t.Errorf("Execute(%q) = %#v", args, outcome) } if output.Len() != 0 || diagnostics.Len() != 0 { t.Errorf("Execute(%q) wrote output %q or diagnostics %q", args, output.String(), diagnostics.String()) } if outcome.Presentation.Output.State != DeliverySuppressed { t.Errorf("Execute(%q) output presentation = %#v", args, outcome.Presentation.Output) } } for _, test := range []struct { args []string want string }{ {args: []string{"help", "run"}, want: "run"}, {args: []string{"help", "r"}, want: "Alias for: Example run"}, {args: []string{"list", "--help"}, want: "Reporting Flags"}, {args: []string{"version"}, want: "Example 1.2.3"}, {args: []string{"version", "--format=yaml"}, want: "version: 1.2.3"}, } { var output, diagnostics bytes.Buffer outcome := app.Execute(context.Background(), test.args, Streams{Out: &output, Err: &diagnostics}) if outcome.Kind != OutcomeSuccess || !strings.Contains(output.String(), test.want) { t.Errorf("Execute(%q) = %#v, output %q", test.args, outcome, output.String()) } } } func TestHelpAndVersionDestinationFailuresUseReporterObservations(t *testing.T) { app := builtinReportingTestApp(t) writeErr := errors.New("help/version destination failed") for _, args := range [][]string{{"help", "run"}, {"version"}} { var diagnostics bytes.Buffer outcome := app.Execute(context.Background(), args, Streams{ Out: executeReportingFailureWriter{err: writeErr}, Err: &diagnostics, }) if outcome.Kind != OutcomeOperational || outcome.Status != 1 { t.Errorf("Execute(%q) = %#v", args, outcome) } if !errors.Is(outcome.Presentation.Output.WriteError, writeErr) || outcome.Presentation.Output.State != DeliveryIncomplete { t.Errorf("Execute(%q) presentation = %#v", args, outcome.Presentation) } if !strings.Contains(diagnostics.String(), "deliver") || !strings.Contains(diagnostics.String(), "output") { t.Errorf("Execute(%q) diagnostics = %q", args, diagnostics.String()) } } } func TestInvalidHelpAndVersionRequestsRemainUsageOutcomes(t *testing.T) { app := builtinReportingTestApp(t) for _, args := range [][]string{{"help", "unknown"}, {"version", "--scope=unknown"}, {"version", "--format=unknown"}} { var output, diagnostics bytes.Buffer outcome := app.Execute(context.Background(), args, Streams{Out: &output, Err: &diagnostics}) if outcome.Kind != OutcomeUsage || outcome.Status != 2 { t.Errorf("Execute(%q) = %#v", args, outcome) } if !strings.Contains(diagnostics.String(), "Usage: Example") { t.Errorf("Execute(%q) diagnostics = %q", args, diagnostics.String()) } } } func TestQuietBuiltinRenderingSuppressesDestinationWrites(t *testing.T) { app := builtinReportingTestApp(t) // A quiet successful run must not touch its supplied result destination. var diagnostics bytes.Buffer outcome := app.Execute(context.Background(), []string{"version", "--quiet"}, Streams{ Out: executeReportingFailureWriter{err: io.ErrClosedPipe}, Err: &diagnostics, }) if outcome.Kind != OutcomeSuccess || outcome.Presentation.Output.State != DeliverySuppressed { t.Fatalf("quiet version outcome = %#v", outcome) } if diagnostics.Len() != 0 { t.Fatalf("quiet version diagnostics = %q", diagnostics.String()) } }