Migrate ConfigKit reports to the reporter

This commit is contained in:
2026-10-26 03:20:17 +00:00
parent 5f37aac70f
commit c0e0010683
9 changed files with 177 additions and 129 deletions

View File

@@ -101,21 +101,30 @@ func TestConfigDiffRunsComparisonOnlyScopeAndRejectsUnsupportedScopeBeforeWork(t
func TestConfigDiffProviderFailureRetainsDiagnosticsAndCause(t *testing.T) {
wantErr := errors.New("provider unavailable")
diagnostic := commandkit.Diagnostic{Severity: commandkit.SeverityError, Write: func(writer io.Writer) error {
diagnostic := commandkit.Diagnostic{Severity: commandkit.SeverityWarning, Write: func(writer io.Writer) error {
_, err := io.WriteString(writer, "provider warning\n")
return err
}}
app := newConfigTestApp(t, Command(Suite[struct{}, struct{}]{Scopes: []Scope[struct{}, struct{}]{{
Name: "app", Operations: []Operation{Diff},
Compare: func(context.Context, ComparisonRequest[struct{}], struct{}) (commandkit.Acquired[[]configkit.Difference], error) {
return commandkit.Acquired[[]configkit.Difference]{Diagnostics: []commandkit.Diagnostic{diagnostic}}, fmt.Errorf("comparison setup: %w", wantErr)
return commandkit.Acquired[[]configkit.Difference]{
Diagnostics: []commandkit.Diagnostic{diagnostic},
Explanation: commandkit.Explanation{Details: []commandkit.Detail{func(writer io.Writer) error {
_, err := io.WriteString(writer, "native comparison context\n")
return err
}}},
}, fmt.Errorf("comparison setup: %w", wantErr)
},
}}}))
var output bytes.Buffer
outcome := app.Execute(context.Background(), []string{"config", "diff"}, commandkit.Streams{Out: &output, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeOperational || !errors.Is(outcome.Cause, wantErr) || outcome.ReportIncomplete || outcome.DeliveryError != nil || output.Len() != 0 || len(outcome.Diagnostics) < 1 || outcome.Diagnostics[0].Severity != commandkit.SeverityError {
var output, diagnosticOutput bytes.Buffer
outcome := app.Execute(context.Background(), []string{"config", "diff", "--verbose"}, commandkit.Streams{Out: &output, Err: &diagnosticOutput})
if outcome.Kind != commandkit.OutcomeOperational || !errors.Is(outcome.Cause, wantErr) || output.Len() != 0 {
t.Fatalf("provider failure outcome/output = %#v / %q", outcome, output.String())
}
if got := diagnosticOutput.String(); !strings.Contains(got, "provider warning") || !strings.Contains(got, "native comparison context") || strings.Index(got, "provider warning") > strings.Index(got, "native comparison context") || strings.Contains(got, wantErr.Error()) {
t.Fatalf("provider messages and terminal context = %q", got)
}
}
func TestConfigDiffReportPreparationFailureWritesNoReport(t *testing.T) {
@@ -128,8 +137,8 @@ func TestConfigDiffReportPreparationFailureWritesNoReport(t *testing.T) {
},
}}}))
var output bytes.Buffer
outcome := app.Execute(context.Background(), []string{"config", "diff"}, commandkit.Streams{Out: &output, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeOperational || outcome.ReportIncomplete || outcome.DeliveryError != nil || output.Len() != 0 {
outcome := app.Execute(context.Background(), []string{"config", "diff", "--quiet"}, commandkit.Streams{Out: failingOutput{err: errors.New("quiet destination should not be called")}, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeOperational || outcome.Cause != nil || outcome.Presentation.Output.State != commandkit.DeliveryIncomplete || outcome.Presentation.Output.RenderError == nil || output.Len() != 0 {
t.Fatalf("report preparation failure outcome/output = %#v / %q", outcome, output.String())
}
}
@@ -146,8 +155,8 @@ func TestConfigDiffCancellationAfterAcquisitionRetainsDiagnosticsWithoutWriting(
}}}))
defer cancel()
var output bytes.Buffer
outcome := app.Execute(ctx, []string{"config", "diff"}, commandkit.Streams{Out: &output, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeOperational || !errors.Is(outcome.Cause, context.Canceled) || outcome.ReportIncomplete || output.Len() != 0 || len(outcome.Diagnostics) < 1 || outcome.Diagnostics[0].Severity != commandkit.SeverityWarning {
outcome := app.Execute(ctx, []string{"config", "diff", "--verbose"}, commandkit.Streams{Out: &output, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeOperational || !errors.Is(outcome.Cause, context.Canceled) || output.Len() != 0 {
t.Fatalf("cancelled comparison outcome/output = %#v / %q", outcome, output.String())
}
}
@@ -170,13 +179,36 @@ func TestConfigDiffOutputErrorsCarryIncompleteDeliveryOutcome(t *testing.T) {
} {
t.Run(test.name, func(t *testing.T) {
outcome := app.Execute(context.Background(), []string{"config", "diff"}, commandkit.Streams{Out: test.writer, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeOperational || !errors.Is(outcome.DeliveryError, test.want) || !errors.Is(outcome.Cause, test.want) || !outcome.ReportIncomplete {
if outcome.Kind != commandkit.OutcomeOperational || outcome.Cause != nil || !errors.Is(outcome.Presentation.Output.WriteError, test.want) || outcome.Presentation.Output.State != commandkit.DeliveryIncomplete {
t.Fatalf("delivery failure outcome = %#v", outcome)
}
})
}
}
func TestConfigDiffDiagnosticDestinationFailureIsPresentationEvidence(t *testing.T) {
app := newConfigTestApp(t, Command(Suite[struct{}, struct{}]{Scopes: []Scope[struct{}, struct{}]{{
Name: "app", Operations: []Operation{Diff},
Compare: func(context.Context, ComparisonRequest[struct{}], struct{}) (commandkit.Acquired[[]configkit.Difference], error) {
return commandkit.Acquired[[]configkit.Difference]{
Diagnostics: []commandkit.Diagnostic{{Severity: commandkit.SeverityWarning, Write: func(writer io.Writer) error {
_, err := io.WriteString(writer, "provider warning\n")
return err
}}},
}, nil
},
}}}))
writeErr := errors.New("diagnostic destination failed")
var output bytes.Buffer
outcome := app.Execute(context.Background(), []string{"config", "diff", "--verbose"}, commandkit.Streams{Out: &output, Err: failingOutput{err: writeErr}})
if outcome.Kind != commandkit.OutcomeOperational || outcome.Cause != nil || !errors.Is(outcome.Presentation.Diagnostics.WriteError, writeErr) || outcome.Presentation.Diagnostics.State != commandkit.DeliveryIncomplete {
t.Fatalf("diagnostic delivery failure outcome = %#v", outcome)
}
if output.Len() == 0 {
t.Fatal("healthy result destination did not receive the diff report")
}
}
func TestConfigDiffRepeatedInvocationsPrepareFreshInputsAndState(t *testing.T) {
type input struct {
ID int