|
|
|
|
@@ -19,7 +19,7 @@ func TestExecuteRunsTypedCommandsWithFreshInvocationState(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
var inputs []input
|
|
|
|
|
var contexts []context.Context
|
|
|
|
|
var streams []commandkit.Streams
|
|
|
|
|
var reporters []*commandkit.Reporter
|
|
|
|
|
firstContext := context.WithValue(context.Background(), struct{}{}, "first")
|
|
|
|
|
secondContext := context.WithValue(context.Background(), struct{}{}, "second")
|
|
|
|
|
var firstOut, secondOut, firstDiagnostic, secondDiagnostic bytes.Buffer
|
|
|
|
|
@@ -32,7 +32,12 @@ func TestExecuteRunsTypedCommandsWithFreshInvocationState(t *testing.T) {
|
|
|
|
|
Run: func(invocation commandkit.Invocation, value input) commandkit.Outcome {
|
|
|
|
|
inputs = append(inputs, value)
|
|
|
|
|
contexts = append(contexts, invocation.Context)
|
|
|
|
|
streams = append(streams, invocation.Streams)
|
|
|
|
|
reporter := invocation.Reporter()
|
|
|
|
|
reporters = append(reporters, reporter)
|
|
|
|
|
_ = reporter.RenderOutput(func(writer io.Writer) error {
|
|
|
|
|
_, err := io.WriteString(writer, value.name.Value+"\n")
|
|
|
|
|
return err
|
|
|
|
|
})
|
|
|
|
|
return commandkit.Success()
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
@@ -52,11 +57,11 @@ func TestExecuteRunsTypedCommandsWithFreshInvocationState(t *testing.T) {
|
|
|
|
|
if inputs[1].name.Set || inputs[1].name.Value != "" || inputs[1].ids.Set {
|
|
|
|
|
t.Fatalf("second invocation inherited state: %#v", inputs[1])
|
|
|
|
|
}
|
|
|
|
|
if streams[2].Out != io.Discard || streams[2].Err != io.Discard {
|
|
|
|
|
t.Fatalf("nil streams were not replaced with io.Discard: %#v", streams[2])
|
|
|
|
|
if reporters[0] == nil || reporters[1] == nil || reporters[2] == nil || reporters[0] == reporters[1] || reporters[0] == reporters[2] || reporters[1] == reporters[2] {
|
|
|
|
|
t.Fatalf("invocations did not receive fresh reporters: %#v", reporters)
|
|
|
|
|
}
|
|
|
|
|
if contexts[0] != firstContext || contexts[1] != secondContext || streams[0].Out != &firstOut || streams[0].Err != &firstDiagnostic || streams[1].Out != &secondOut || streams[1].Err != &secondDiagnostic {
|
|
|
|
|
t.Fatalf("handler invocation contexts or streams were not forwarded independently")
|
|
|
|
|
if firstOut.String() != "first\n" || secondOut.String() != "\n" || contexts[0] != firstContext || contexts[1] != secondContext {
|
|
|
|
|
t.Fatalf("handler invocation contexts or reporter destinations were not independent: out=%q/%q contexts=%v/%v", firstOut.String(), secondOut.String(), contexts[0], contexts[1])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -65,7 +70,7 @@ func TestOmittedInputFactoryUsesExactPointerZeroValue(t *testing.T) {
|
|
|
|
|
Name: "run",
|
|
|
|
|
Run: func(_ commandkit.Invocation, value *int) commandkit.Outcome {
|
|
|
|
|
if value != nil {
|
|
|
|
|
return commandkit.Failure(errors.New("omitted input factory allocated a pointer"))
|
|
|
|
|
return commandkit.Failure("omitted input factory allocated a pointer")
|
|
|
|
|
}
|
|
|
|
|
return commandkit.Success()
|
|
|
|
|
},
|
|
|
|
|
@@ -136,9 +141,9 @@ func TestExecutePresentsHandlerUsageAfterRegisteringCommand(t *testing.T) {
|
|
|
|
|
Run: func(commandkit.Invocation, struct{}) commandkit.Outcome {
|
|
|
|
|
calls++
|
|
|
|
|
if err := app.Register(late); err != nil {
|
|
|
|
|
return commandkit.Failure(err)
|
|
|
|
|
return commandkit.Failure(err.Error()).WithCause(err)
|
|
|
|
|
}
|
|
|
|
|
return commandkit.Usage(usageCause)
|
|
|
|
|
return commandkit.Usage("The handler requests usage.").WithCause(usageCause)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
app, err := commandkit.New(commandkit.Identity{Name: "example"}, command)
|
|
|
|
|
@@ -195,12 +200,11 @@ func TestExecuteReturnsUsageForParsingRequirementsAndInputChecks(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
func TestExecutePreservesDomainOutcomesAndWarningDiagnostics(t *testing.T) {
|
|
|
|
|
domainCause := errors.New("domain rejected the request")
|
|
|
|
|
warning := commandkit.MessageDiagnostic(commandkit.SeverityWarning, "review needed")
|
|
|
|
|
command := commandkit.NewCommand(commandkit.CommandSpec[struct{}]{
|
|
|
|
|
Name: "run",
|
|
|
|
|
Run: func(commandkit.Invocation, struct{}) commandkit.Outcome {
|
|
|
|
|
outcome := commandkit.Domain("sample", 2, domainCause)
|
|
|
|
|
outcome.Diagnostics = []commandkit.Diagnostic{warning}
|
|
|
|
|
Run: func(invocation commandkit.Invocation, _ struct{}) commandkit.Outcome {
|
|
|
|
|
_ = invocation.Reporter().Warn("review needed")
|
|
|
|
|
outcome := commandkit.Domain("sample", 2).WithExplanation("The request was rejected.").WithCause(domainCause)
|
|
|
|
|
return outcome
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
@@ -209,19 +213,18 @@ func TestExecutePreservesDomainOutcomesAndWarningDiagnostics(t *testing.T) {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
var diagnostic bytes.Buffer
|
|
|
|
|
outcome := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{Err: &diagnostic})
|
|
|
|
|
outcome := app.Execute(context.Background(), []string{"run", "--verbose"}, commandkit.Streams{Err: &diagnostic})
|
|
|
|
|
if outcome.Kind != commandkit.OutcomeDomain || outcome.Domain != "sample" || outcome.Status != 2 || !errors.Is(outcome.Cause, domainCause) {
|
|
|
|
|
t.Fatalf("domain outcome changed: %#v", outcome)
|
|
|
|
|
}
|
|
|
|
|
if diagnostic.String() != "review needed\ndomain rejected the request\n" || outcome.DiagnosticDelivery != commandkit.DeliveryComplete {
|
|
|
|
|
if diagnostic.String() != "WARN: review needed\nERROR: The request was rejected.\n" || outcome.Presentation.Diagnostics.State != commandkit.DeliveryComplete {
|
|
|
|
|
t.Fatalf("warning delivery = %q, %#v", diagnostic.String(), outcome)
|
|
|
|
|
}
|
|
|
|
|
warningOnly := commandkit.NewCommand(commandkit.CommandSpec[struct{}]{
|
|
|
|
|
Name: "warn",
|
|
|
|
|
Run: func(commandkit.Invocation, struct{}) commandkit.Outcome {
|
|
|
|
|
result := commandkit.Success()
|
|
|
|
|
result.Diagnostics = []commandkit.Diagnostic{warning}
|
|
|
|
|
return result
|
|
|
|
|
Run: func(invocation commandkit.Invocation, _ struct{}) commandkit.Outcome {
|
|
|
|
|
_ = invocation.Reporter().Warn("review needed")
|
|
|
|
|
return commandkit.Success()
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
app, err = commandkit.New(commandkit.Identity{Name: "example"}, warningOnly)
|
|
|
|
|
@@ -229,23 +232,18 @@ func TestExecutePreservesDomainOutcomesAndWarningDiagnostics(t *testing.T) {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
diagnostic.Reset()
|
|
|
|
|
outcome = app.Execute(context.Background(), []string{"warn"}, commandkit.Streams{Err: &diagnostic})
|
|
|
|
|
if outcome.Kind != commandkit.OutcomeSuccess || diagnostic.String() != "review needed\n" {
|
|
|
|
|
outcome = app.Execute(context.Background(), []string{"warn", "--verbose"}, commandkit.Streams{Err: &diagnostic})
|
|
|
|
|
if outcome.Kind != commandkit.OutcomeSuccess || diagnostic.String() != "WARN: review needed\n" {
|
|
|
|
|
t.Fatalf("warning-only outcome = %#v, diagnostics %q", outcome, diagnostic.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestExecuteDoesNotRepeatCompletedDiagnosticsOrPresentedCauses(t *testing.T) {
|
|
|
|
|
cause := errors.New("already shown")
|
|
|
|
|
func TestExecuteDoesNotPresentOperationCauseWithoutExplanation(t *testing.T) {
|
|
|
|
|
cause := errors.New("private operation detail")
|
|
|
|
|
command := commandkit.NewCommand(commandkit.CommandSpec[struct{}]{
|
|
|
|
|
Name: "run",
|
|
|
|
|
Run: func(commandkit.Invocation, struct{}) commandkit.Outcome {
|
|
|
|
|
outcome := commandkit.Domain("sample", 2, cause)
|
|
|
|
|
outcome.Diagnostics = []commandkit.Diagnostic{{Severity: commandkit.SeverityError, Write: func(writer io.Writer) error {
|
|
|
|
|
_, err := io.WriteString(writer, "presented\n")
|
|
|
|
|
return err
|
|
|
|
|
}}}
|
|
|
|
|
return outcome
|
|
|
|
|
return commandkit.Domain("sample", 2).WithCause(cause)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
app, err := commandkit.New(commandkit.Identity{Name: "example"}, command)
|
|
|
|
|
@@ -254,21 +252,11 @@ func TestExecuteDoesNotRepeatCompletedDiagnosticsOrPresentedCauses(t *testing.T)
|
|
|
|
|
}
|
|
|
|
|
var diagnostic bytes.Buffer
|
|
|
|
|
outcome := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{Err: &diagnostic})
|
|
|
|
|
if outcome.Kind != commandkit.OutcomeDomain || diagnostic.String() != "presented\n" {
|
|
|
|
|
t.Fatalf("presented cause was duplicated: %#v, %q", outcome, diagnostic.String())
|
|
|
|
|
if outcome.Kind != commandkit.OutcomeDomain || !errors.Is(outcome.Cause, cause) {
|
|
|
|
|
t.Fatalf("domain outcome changed: %#v", outcome)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
diagnostic.Reset()
|
|
|
|
|
completed := commandkit.Domain("sample", 2, cause)
|
|
|
|
|
completed.DiagnosticDelivery = commandkit.DeliveryComplete
|
|
|
|
|
command = commandkit.NewCommand(commandkit.CommandSpec[struct{}]{Name: "done", Run: func(commandkit.Invocation, struct{}) commandkit.Outcome { return completed }})
|
|
|
|
|
app, err = commandkit.New(commandkit.Identity{Name: "example"}, command)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
outcome = app.Execute(context.Background(), []string{"done"}, commandkit.Streams{Err: &diagnostic})
|
|
|
|
|
if diagnostic.Len() != 0 || outcome.DiagnosticDelivery != commandkit.DeliveryComplete {
|
|
|
|
|
t.Fatalf("completed diagnostics were repeated: %#v, %q", outcome, diagnostic.String())
|
|
|
|
|
if strings.Contains(diagnostic.String(), cause.Error()) || !strings.Contains(diagnostic.String(), "ERROR: Command failed.") {
|
|
|
|
|
t.Fatalf("cause was presented instead of the fallback explanation: %#v, %q", outcome, diagnostic.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -278,9 +266,7 @@ func TestExecuteRetainsOperationAndDiagnosticDeliveryFailures(t *testing.T) {
|
|
|
|
|
command := commandkit.NewCommand(commandkit.CommandSpec[struct{}]{
|
|
|
|
|
Name: "run",
|
|
|
|
|
Run: func(commandkit.Invocation, struct{}) commandkit.Outcome {
|
|
|
|
|
outcome := commandkit.Failure(operationFailure)
|
|
|
|
|
outcome.ReportIncomplete = true
|
|
|
|
|
return outcome
|
|
|
|
|
return commandkit.Failure("The operation was canceled.").WithCause(operationFailure)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
app, err := commandkit.New(commandkit.Identity{Name: "example"}, command)
|
|
|
|
|
@@ -288,12 +274,12 @@ func TestExecuteRetainsOperationAndDiagnosticDeliveryFailures(t *testing.T) {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
outcome := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{Err: failingWriter{err: writeFailure}})
|
|
|
|
|
if outcome.Kind != commandkit.OutcomeOperational || outcome.Status != 1 || outcome.DiagnosticDelivery != commandkit.DeliveryIncomplete || !outcome.ReportIncomplete || !errors.Is(outcome.Cause, operationFailure) || !errors.Is(outcome.DeliveryError, writeFailure) {
|
|
|
|
|
if outcome.Kind != commandkit.OutcomeOperational || outcome.Status != 1 || outcome.Presentation.Diagnostics.State != commandkit.DeliveryIncomplete || !errors.Is(outcome.Cause, operationFailure) || !errors.Is(outcome.Presentation.Diagnostics.WriteError, writeFailure) {
|
|
|
|
|
t.Fatalf("combined operation and delivery failure = %#v", outcome)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{Err: shortWriter{}})
|
|
|
|
|
if !errors.Is(short.DeliveryError, io.ErrShortWrite) || short.DiagnosticDelivery != commandkit.DeliveryIncomplete {
|
|
|
|
|
if !errors.Is(short.Presentation.Diagnostics.WriteError, io.ErrShortWrite) || short.Presentation.Diagnostics.State != commandkit.DeliveryIncomplete {
|
|
|
|
|
t.Fatalf("short write was not detected: %#v", short)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -339,7 +325,7 @@ func TestExecuteRunsApplicationOwnedNestedHelp(t *testing.T) {
|
|
|
|
|
)},
|
|
|
|
|
Run: func(_ commandkit.Invocation, value input) commandkit.Outcome {
|
|
|
|
|
received = append(received, value)
|
|
|
|
|
return commandkit.Domain("session-help", 7, domainCause)
|
|
|
|
|
return commandkit.Domain("session-help", 7).WithExplanation("Session help is unavailable.").WithCause(domainCause)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
session := commandkit.Group("session", "Session commands.", help)
|
|
|
|
|
@@ -463,7 +449,7 @@ func TestHelpRendersRegisteredMetadataAndResolvesExactPaths(t *testing.T) {
|
|
|
|
|
t.Fatalf("version invoked an application command: %#v calls=%d/%d", versionOutcome, factoryCalls, runCalls)
|
|
|
|
|
}
|
|
|
|
|
failed := app.Execute(context.Background(), []string{"config", "show", "--help"}, commandkit.Streams{Out: shortWriter{}, Err: &diagnostic})
|
|
|
|
|
if failed.Kind != commandkit.OutcomeOperational || !failed.ReportIncomplete || !errors.Is(failed.DeliveryError, io.ErrShortWrite) {
|
|
|
|
|
if failed.Kind != commandkit.OutcomeOperational || failed.Presentation.Output.State != commandkit.DeliveryIncomplete || !errors.Is(failed.Presentation.Output.WriteError, io.ErrShortWrite) {
|
|
|
|
|
t.Fatalf("failed help delivery = %#v", failed)
|
|
|
|
|
}
|
|
|
|
|
out.Reset()
|
|
|
|
|
@@ -503,7 +489,7 @@ func TestVersionCommandFormatsApplicationAndCommandKitIdentity(t *testing.T) {
|
|
|
|
|
t.Fatalf("invalid version scope = %#v, output %q", invalid, out.String())
|
|
|
|
|
}
|
|
|
|
|
failed := app.Execute(context.Background(), []string{"version"}, commandkit.Streams{Out: shortWriter{}, Err: &diagnostic})
|
|
|
|
|
if failed.Kind != commandkit.OutcomeOperational || !failed.ReportIncomplete || !errors.Is(failed.DeliveryError, io.ErrShortWrite) {
|
|
|
|
|
if failed.Kind != commandkit.OutcomeOperational || failed.Presentation.Output.State != commandkit.DeliveryIncomplete || !errors.Is(failed.Presentation.Output.WriteError, io.ErrShortWrite) {
|
|
|
|
|
t.Fatalf("failed version delivery = %#v", failed)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -532,11 +518,11 @@ func TestHelpEntryFormsPresentReportAndDiagnosticFailures(t *testing.T) {
|
|
|
|
|
for _, args := range [][]string{nil, {"notes"}, {"--help"}, {"-h"}, {"notes", "--help"}, {"help"}, {"help", "notes"}} {
|
|
|
|
|
var diagnostics bytes.Buffer
|
|
|
|
|
result := app.Execute(context.Background(), args, commandkit.Streams{Out: failingWriter{reportErr}, Err: &diagnostics})
|
|
|
|
|
if result.Kind != commandkit.OutcomeOperational || !result.ReportIncomplete || !errors.Is(result.Cause, reportErr) || !errors.Is(result.DeliveryError, reportErr) || result.DiagnosticDelivery != commandkit.DeliveryComplete || strings.Count(diagnostics.String(), reportErr.Error()) != 1 {
|
|
|
|
|
if result.Kind != commandkit.OutcomeOperational || result.Presentation.Output.State != commandkit.DeliveryIncomplete || !errors.Is(result.Presentation.Output.WriteError, reportErr) || result.Presentation.Diagnostics.State != commandkit.DeliveryComplete || !strings.Contains(diagnostics.String(), "ERROR: Command failed.") {
|
|
|
|
|
t.Fatalf("%v: result=%#v diagnostics=%q", args, result, diagnostics.String())
|
|
|
|
|
}
|
|
|
|
|
result = app.Execute(context.Background(), args, commandkit.Streams{Out: failingWriter{reportErr}, Err: failingWriter{diagnosticErr}})
|
|
|
|
|
if result.DiagnosticDelivery != commandkit.DeliveryIncomplete || !errors.Is(result.Cause, reportErr) || !errors.Is(result.DeliveryError, reportErr) || !errors.Is(result.DeliveryError, diagnosticErr) {
|
|
|
|
|
if result.Presentation.Output.State != commandkit.DeliveryIncomplete || !errors.Is(result.Presentation.Output.WriteError, reportErr) || result.Presentation.Diagnostics.State != commandkit.DeliveryIncomplete || !errors.Is(result.Presentation.Diagnostics.WriteError, diagnosticErr) {
|
|
|
|
|
t.Fatalf("%v: result=%#v", args, result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -560,46 +546,34 @@ func TestExecuteNormalizesOutcomeDefaultsAndPreservesDomainValues(t *testing.T)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
result := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{})
|
|
|
|
|
wantDelivery := commandkit.DeliveryNone
|
|
|
|
|
if tc.cause != nil {
|
|
|
|
|
wantDelivery = commandkit.DeliveryComplete
|
|
|
|
|
}
|
|
|
|
|
if result.Kind != tc.kind || result.Status != tc.status || result.Domain != tc.domain || result.Cause != tc.cause || result.DiagnosticDelivery != wantDelivery {
|
|
|
|
|
var diagnostic bytes.Buffer
|
|
|
|
|
result := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{Err: &diagnostic})
|
|
|
|
|
if result.Kind != tc.kind || result.Status != tc.status || result.Domain != tc.domain || result.Cause != tc.cause {
|
|
|
|
|
t.Fatalf("result=%#v expected=%#v", result, tc)
|
|
|
|
|
}
|
|
|
|
|
if tc.status != 0 && !strings.Contains(diagnostic.String(), "ERROR: Command failed.") {
|
|
|
|
|
t.Fatalf("failed outcome omitted its fallback explanation: %q", diagnostic.String())
|
|
|
|
|
}
|
|
|
|
|
if tc.cause != nil && strings.Contains(diagnostic.String(), tc.cause.Error()) {
|
|
|
|
|
t.Fatalf("operation cause was presented automatically: %q", diagnostic.String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestNilDiagnosticWritersHaveNoOutputAndDoNotHideCauses(t *testing.T) {
|
|
|
|
|
func TestNilDiagnosticWriterDoesNotHideOperationCause(t *testing.T) {
|
|
|
|
|
cause := errors.New("operation failed")
|
|
|
|
|
for _, base := range []commandkit.Outcome{commandkit.Success(), commandkit.Domain("needs action", 2, nil), commandkit.Failure(cause)} {
|
|
|
|
|
base.Diagnostics = []commandkit.Diagnostic{{}, {Severity: commandkit.SeverityWarning}, {Severity: commandkit.SeverityError}}
|
|
|
|
|
command := commandkit.NewCommand(commandkit.CommandSpec[struct{}]{Name: "run", Run: func(commandkit.Invocation, struct{}) commandkit.Outcome { return base }})
|
|
|
|
|
app, err := commandkit.New(commandkit.Identity{Name: "example"}, command)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
var diagnostics bytes.Buffer
|
|
|
|
|
result := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{Err: &diagnostics})
|
|
|
|
|
want := commandkit.DeliveryNone
|
|
|
|
|
if base.Cause != nil {
|
|
|
|
|
want = commandkit.DeliveryComplete
|
|
|
|
|
}
|
|
|
|
|
if result.Kind != base.Kind || result.Status != base.Status || result.Domain != base.Domain || result.Cause != base.Cause || result.DeliveryError != nil || result.DiagnosticDelivery != want {
|
|
|
|
|
t.Fatalf("result=%#v base=%#v", result, base)
|
|
|
|
|
}
|
|
|
|
|
if base.Cause == nil && diagnostics.Len() != 0 {
|
|
|
|
|
t.Fatalf("unexpected output=%q", diagnostics.String())
|
|
|
|
|
}
|
|
|
|
|
if base.Cause != nil && strings.Count(diagnostics.String(), cause.Error()) != 1 {
|
|
|
|
|
t.Fatalf("cause output=%q", diagnostics.String())
|
|
|
|
|
}
|
|
|
|
|
if base.Cause != nil {
|
|
|
|
|
result = app.Execute(context.Background(), []string{"run"}, commandkit.Streams{Err: failingWriter{io.ErrClosedPipe}})
|
|
|
|
|
if !errors.Is(result.Cause, cause) || !errors.Is(result.DeliveryError, io.ErrClosedPipe) || result.DiagnosticDelivery != commandkit.DeliveryIncomplete {
|
|
|
|
|
t.Fatalf("failed delivery=%#v", result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
command := commandkit.NewCommand(commandkit.CommandSpec[struct{}]{
|
|
|
|
|
Name: "run",
|
|
|
|
|
Run: func(commandkit.Invocation, struct{}) commandkit.Outcome {
|
|
|
|
|
return commandkit.Failure("The operation failed.").WithCause(cause)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
app, err := commandkit.New(commandkit.Identity{Name: "example"}, command)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
result := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{})
|
|
|
|
|
if result.Kind != commandkit.OutcomeOperational || !errors.Is(result.Cause, cause) || result.Presentation.Diagnostics.State != commandkit.DeliveryComplete {
|
|
|
|
|
t.Fatalf("nil diagnostic destination changed the outcome: %#v", result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|