Separate PromptKit messages from terminal context
This commit is contained in:
@@ -239,7 +239,7 @@ func TestWithSmokeTestingRetainsNilLoaderIssueAndChecksCancellationBeforeBuild(t
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithSmokeTestingRetainsLoaderDiagnosticsAndErrorIdentity(t *testing.T) {
|
||||
func TestWithSmokeTestingRetainsLoaderExplanationAndErrorIdentity(t *testing.T) {
|
||||
_, loadErr := configkit.Load[map[string]any](configkit.Bytes("invalid smoke configuration", []byte("broken: [")))
|
||||
if loadErr == nil {
|
||||
t.Fatal("invalid configuration unexpectedly loaded")
|
||||
@@ -249,7 +249,7 @@ func TestWithSmokeTestingRetainsLoaderDiagnosticsAndErrorIdentity(t *testing.T)
|
||||
}, nil)
|
||||
acquired, err := suite.SmokeTest(context.Background(), SmokeRequest{}, 0, 0)
|
||||
var retained *configkit.LoadError
|
||||
if !errors.Is(err, loadErr) || !errors.As(err, &retained) || retained != loadErr || acquired.Value != nil || len(acquired.Diagnostics) == 0 {
|
||||
if !errors.Is(err, loadErr) || !errors.As(err, &retained) || retained != loadErr || acquired.Value != nil || len(acquired.Explanation.Details) == 0 {
|
||||
t.Fatalf("smoke load failure = (%#v, %v)", acquired, err)
|
||||
}
|
||||
}
|
||||
@@ -394,7 +394,7 @@ func TestConfigScopeCompareStopsAfterLeftLoadFailure(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigScopeCompareRetainsRightLoadDiagnosticsAndErrorIdentity(t *testing.T) {
|
||||
func TestConfigScopeCompareRetainsRightLoadExplanationAndErrorIdentity(t *testing.T) {
|
||||
_, loadErr := configkit.Load[map[string]any](configkit.Bytes("invalid right prompt config", []byte("broken: [")))
|
||||
if loadErr == nil {
|
||||
t.Fatal("invalid right configuration unexpectedly loaded")
|
||||
@@ -415,12 +415,12 @@ func TestConfigScopeCompareRetainsRightLoadDiagnosticsAndErrorIdentity(t *testin
|
||||
|
||||
acquired, err := scope.Compare(context.Background(), request, struct{}{})
|
||||
var retained *configkit.LoadError
|
||||
if !errors.Is(err, loadErr) || !errors.As(err, &retained) || retained != loadErr || len(calls) != 2 || len(acquired.Diagnostics) == 0 {
|
||||
if !errors.Is(err, loadErr) || !errors.As(err, &retained) || retained != loadErr || len(calls) != 2 || len(acquired.Explanation.Details) == 0 {
|
||||
t.Fatalf("right failure = (%#v, %v), calls=%#v", acquired, err, calls)
|
||||
}
|
||||
var output bytes.Buffer
|
||||
if writeErr := acquired.Diagnostics[0].Write(&output); writeErr != nil || !strings.Contains(output.String(), `Configuration scope "promptkit" (right):`) {
|
||||
t.Fatalf("right diagnostic = %q, %v", output.String(), writeErr)
|
||||
if writeErr := acquired.Explanation.Details[0](&output); writeErr != nil || !strings.Contains(output.String(), `Configuration scope "promptkit" (right):`) {
|
||||
t.Fatalf("right explanation = %q, %v", output.String(), writeErr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ func TestFromEngineInspectsRequirementsWithNativeRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromEngineRequirementsRetainLoadDiagnosticsAndSelectionErrors(t *testing.T) {
|
||||
func TestFromEngineRequirementsRetainLoadExplanationAndSelectionErrors(t *testing.T) {
|
||||
_, loadErr := configkit.Load[map[string]any](configkit.Bytes("invalid requirements configuration", []byte("broken: [")))
|
||||
if loadErr == nil {
|
||||
t.Fatal("invalid configuration unexpectedly loaded")
|
||||
@@ -544,11 +544,8 @@ func TestFromEngineRequirementsRetainLoadDiagnosticsAndSelectionErrors(t *testin
|
||||
})
|
||||
acquired, err := loadFailure.InspectRequirements(context.Background(), RequirementsRequest{}, 0, 0)
|
||||
var retained *configkit.LoadError
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Diagnostics) == 0 || acquired.Value != nil {
|
||||
t.Fatalf("requirements load failure = (%#v, %v), want original ConfigKit error and diagnostics", acquired, err)
|
||||
}
|
||||
if acquired.Diagnostics[0].Severity != commandkit.SeverityError {
|
||||
t.Fatalf("load diagnostics = %#v, want error severity", acquired.Diagnostics)
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Explanation.Details) == 0 || acquired.Value != nil {
|
||||
t.Fatalf("requirements load failure = (%#v, %v), want original ConfigKit error and terminal context", acquired, err)
|
||||
}
|
||||
|
||||
nilEngine := FromEngine[int, int](func(context.Context, ckconfig.Selection, int, int) (*promptkit.Engine, error) {
|
||||
@@ -651,7 +648,7 @@ func TestFromEngineListsNativeCatalogsWithInvocationValues(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromEngineCatalogsRetainLoadDiagnosticsAndErrorIdentity(t *testing.T) {
|
||||
func TestFromEngineCatalogsRetainLoadExplanationAndErrorIdentity(t *testing.T) {
|
||||
_, loadErr := configkit.Load[map[string]any](configkit.Bytes("invalid catalog configuration", []byte("broken: [")))
|
||||
if loadErr == nil {
|
||||
t.Fatal("invalid configuration unexpectedly loaded")
|
||||
@@ -666,42 +663,42 @@ func TestFromEngineCatalogsRetainLoadDiagnosticsAndErrorIdentity(t *testing.T) {
|
||||
{name: "prompts", call: func() (int, error) {
|
||||
acquired, err := suite.ListPrompts(context.Background(), CatalogRequest{}, 0, 0)
|
||||
var retained *configkit.LoadError
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Diagnostics) == 0 {
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Explanation.Details) == 0 {
|
||||
t.Errorf("prompt load failure = (%#v, %v)", acquired, err)
|
||||
}
|
||||
return len(acquired.Diagnostics), err
|
||||
return len(acquired.Diagnostics) + len(acquired.Explanation.Details), err
|
||||
}},
|
||||
{name: "profiles", call: func() (int, error) {
|
||||
acquired, err := suite.ListProfiles(context.Background(), CatalogRequest{}, 0, 0)
|
||||
var retained *configkit.LoadError
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Diagnostics) == 0 {
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Explanation.Details) == 0 {
|
||||
t.Errorf("profile load failure = (%#v, %v)", acquired, err)
|
||||
}
|
||||
return len(acquired.Diagnostics), err
|
||||
return len(acquired.Diagnostics) + len(acquired.Explanation.Details), err
|
||||
}},
|
||||
{name: "backends", call: func() (int, error) {
|
||||
acquired, err := suite.ListBackends(context.Background(), CatalogRequest{}, 0, 0)
|
||||
var retained *configkit.LoadError
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Diagnostics) == 0 {
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Explanation.Details) == 0 {
|
||||
t.Errorf("backend load failure = (%#v, %v)", acquired, err)
|
||||
}
|
||||
return len(acquired.Diagnostics), err
|
||||
return len(acquired.Diagnostics) + len(acquired.Explanation.Details), err
|
||||
}},
|
||||
{name: "namespaces", call: func() (int, error) {
|
||||
acquired, err := suite.ListNamespaces(context.Background(), NamespaceRequest{}, 0, 0)
|
||||
var retained *configkit.LoadError
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Diagnostics) == 0 {
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Explanation.Details) == 0 {
|
||||
t.Errorf("namespace load failure = (%#v, %v)", acquired, err)
|
||||
}
|
||||
return len(acquired.Diagnostics), err
|
||||
return len(acquired.Diagnostics) + len(acquired.Explanation.Details), err
|
||||
}},
|
||||
{name: "collections", call: func() (int, error) {
|
||||
acquired, err := suite.ListCollections(context.Background(), ckconfig.Selection{}, 0, 0)
|
||||
var retained *configkit.LoadError
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Diagnostics) == 0 {
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Explanation.Details) == 0 {
|
||||
t.Errorf("collection load failure = (%#v, %v)", acquired, err)
|
||||
}
|
||||
return len(acquired.Diagnostics), err
|
||||
return len(acquired.Diagnostics) + len(acquired.Explanation.Details), err
|
||||
}},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
@@ -782,7 +779,7 @@ func TestAdapterAcquisitionPreservesLoadAndContextErrors(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromEngineRetainsConfigKitLoadDiagnostics(t *testing.T) {
|
||||
func TestFromEngineRetainsConfigKitLoadExplanation(t *testing.T) {
|
||||
_, loadErr := configkit.Load[map[string]any](configkit.Bytes("invalid PromptKit config", []byte("broken: [")))
|
||||
if loadErr == nil {
|
||||
t.Fatal("invalid configuration unexpectedly loaded")
|
||||
@@ -793,11 +790,8 @@ func TestFromEngineRetainsConfigKitLoadDiagnostics(t *testing.T) {
|
||||
|
||||
acquired, err := suite.InspectProfile(context.Background(), ProfileRequest{ID: "default"}, 0, 0)
|
||||
var retained *configkit.LoadError
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Diagnostics) == 0 {
|
||||
t.Fatalf("load failure = (%#v, %v), want original ConfigKit error and diagnostics", acquired, err)
|
||||
}
|
||||
if acquired.Diagnostics[0].Severity != commandkit.SeverityError {
|
||||
t.Fatalf("load diagnostics = %#v, want error severity", acquired.Diagnostics)
|
||||
if !errors.As(err, &retained) || retained != loadErr || len(acquired.Explanation.Details) == 0 {
|
||||
t.Fatalf("load failure = (%#v, %v), want original ConfigKit error and terminal context", acquired, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,25 +817,55 @@ func TestPromptKitDiagnosticsRemainDeferredAndPropagateWriterErrors(t *testing.T
|
||||
Severity: configkit.SeverityWarning,
|
||||
Message: "safe warning",
|
||||
}}
|
||||
diagnostics := promptKitDiagnostics("promptkit", "", sources, records)
|
||||
if len(diagnostics) != 1 || diagnostics[0].Severity != commandkit.SeverityWarning {
|
||||
t.Fatalf("diagnostics = %#v", diagnostics)
|
||||
messages := promptKitDiagnostics("promptkit", "", sources, records)
|
||||
if len(messages.diagnostics) != 1 || messages.diagnostics[0].Severity != commandkit.SeverityWarning || len(messages.explanation.Details) != 0 {
|
||||
t.Fatalf("diagnostic messages = %#v", messages)
|
||||
}
|
||||
if err := diagnostics[0].Write(failingDiagnosticWriter{err: writeErr}); !errors.Is(err, writeErr) {
|
||||
if err := messages.diagnostics[0].Write(failingDiagnosticWriter{err: writeErr}); !errors.Is(err, writeErr) {
|
||||
t.Fatalf("diagnostic write error = %v", err)
|
||||
}
|
||||
var output bytes.Buffer
|
||||
if err := diagnostics[0].Write(&output); err != nil || !strings.Contains(output.String(), `Configuration scope "promptkit":`) || !strings.Contains(output.String(), "safe warning") || !strings.Contains(output.String(), `"source"`) {
|
||||
if err := messages.diagnostics[0].Write(&output); err != nil || !strings.Contains(output.String(), `Configuration scope "promptkit":`) || !strings.Contains(output.String(), "safe warning") || !strings.Contains(output.String(), `"source"`) {
|
||||
t.Fatalf("diagnostic text = %q, %v", output.String(), err)
|
||||
}
|
||||
|
||||
sideDiagnostics := promptKitDiagnostics("promptkit", "left", sources, records)
|
||||
output.Reset()
|
||||
if err := sideDiagnostics[0].Write(&output); err != nil || !strings.Contains(output.String(), `Configuration scope "promptkit" (left):`) {
|
||||
if err := sideDiagnostics.diagnostics[0].Write(&output); err != nil || !strings.Contains(output.String(), `Configuration scope "promptkit" (left):`) {
|
||||
t.Fatalf("comparison-side diagnostic text = %q, %v", output.String(), err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPromptKitDiagnosticsSeparateIndependentWarningsAndTerminalRecords(t *testing.T) {
|
||||
sources := []configkit.SourceInfo{{ID: "source", Label: "safe label", Path: "config.yml"}}
|
||||
primary := configkit.Location{SourceID: "source", Line: 3, Column: 2}
|
||||
related := configkit.Location{SourceID: "base.yml", Line: 7, Column: 4}
|
||||
messages := promptKitDiagnostics("promptkit", "right", sources, []configkit.Diagnostic{
|
||||
{Severity: configkit.SeverityWarning, Message: "independent warning", Primary: &primary, Related: []configkit.Location{related}},
|
||||
{Severity: configkit.SeverityError, Message: "terminal configuration error", Primary: &related, Related: []configkit.Location{primary}},
|
||||
})
|
||||
if len(messages.diagnostics) != 1 || len(messages.explanation.Details) != 1 {
|
||||
t.Fatalf("mixed acquisition messages = %#v", messages)
|
||||
}
|
||||
writeErr := errors.New("terminal explanation writer failed")
|
||||
if err := messages.explanation.Details[0](failingDiagnosticWriter{err: writeErr}); !errors.Is(err, writeErr) {
|
||||
t.Fatalf("terminal explanation write error = %v", err)
|
||||
}
|
||||
var warning, terminal bytes.Buffer
|
||||
if err := messages.diagnostics[0].Write(&warning); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := messages.explanation.Details[0](&terminal); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := warning.String(); !strings.Contains(got, "independent warning") || !strings.Contains(got, `Configuration scope "promptkit" (right):`) || !strings.Contains(got, `"source": label="safe label", path="config.yml"`) || !strings.Contains(got, "source:3:2") || !strings.Contains(got, "related: base.yml:7:4") || strings.Contains(got, "terminal configuration error") {
|
||||
t.Fatalf("independent warning report = %q", got)
|
||||
}
|
||||
if got := terminal.String(); !strings.Contains(got, "terminal configuration error") || !strings.Contains(got, `Configuration scope "promptkit" (right):`) || !strings.Contains(got, `"source": label="safe label", path="config.yml"`) || !strings.Contains(got, "base.yml:7:4") || !strings.Contains(got, "related: source:3:2") || strings.Contains(got, "independent warning") {
|
||||
t.Fatalf("terminal explanation report = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
type failingDiagnosticWriter struct{ err error }
|
||||
|
||||
func (writer failingDiagnosticWriter) Write([]byte) (int, error) { return 0, writer.err }
|
||||
|
||||
Reference in New Issue
Block a user