Migrate prompt fixtures to direct definitions
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -24,6 +25,8 @@ func newPromptTestApp(t *testing.T, commands ...commandkit.Command) *commandkit.
|
||||
return app
|
||||
}
|
||||
|
||||
func testStringPointer(value string) *string { return &value }
|
||||
|
||||
func TestCommandBuildsIndependentOptionalTrees(t *testing.T) {
|
||||
promptOnly := newPromptTestApp(t, Command(Suite[struct{}, struct{}]{InspectPrompt: func(context.Context, PromptRequest, struct{}, struct{}) (commandkit.Acquired[*promptkit.PromptInspection], error) {
|
||||
return commandkit.Acquired[*promptkit.PromptInspection]{}, errors.New("unused")
|
||||
@@ -121,8 +124,7 @@ func TestRequirementsCommandCapturesContextAndVariableAssignments(t *testing.T)
|
||||
providerCalls++
|
||||
received, receivedInput, receivedState = request, value, gotState
|
||||
return commandkit.Acquired[*promptkit.RequirementInspection]{Value: &promptkit.RequirementInspection{
|
||||
PromptID: request.Inspection.PromptID, PromptVersion: request.Inspection.PromptVersion,
|
||||
ProfileID: request.Inspection.ProfileID, Complete: true,
|
||||
PromptID: request.Inspection.PromptID, ProfileID: request.Inspection.ProfileID, Complete: true,
|
||||
}}, nil
|
||||
},
|
||||
}
|
||||
@@ -139,7 +141,7 @@ func TestRequirementsCommandCapturesContextAndVariableAssignments(t *testing.T)
|
||||
if familyOutcome.Kind != commandkit.OutcomeSuccess || !strings.Contains(familyHelp.String(), "requirements") || strings.Contains(familyHelp.String(), "\n show ") || strings.Contains(familyHelp.String(), "\n list ") {
|
||||
t.Fatalf("requirements-only family help = (%#v, %q)", familyOutcome, familyHelp.String())
|
||||
}
|
||||
for _, flag := range []string{"--config", "--overlay", "--version", "--profile", "--session-id", "--var", "--format", "--campaign"} {
|
||||
for _, flag := range []string{"--config", "--overlay", "--profile", "--session-id", "--var", "--format", "--campaign"} {
|
||||
if !strings.Contains(help.String(), flag) {
|
||||
t.Errorf("requirements help omits %s: %q", flag, help.String())
|
||||
}
|
||||
@@ -152,7 +154,7 @@ func TestRequirementsCommandCapturesContextAndVariableAssignments(t *testing.T)
|
||||
args := []string{
|
||||
"promptkit", "requirements", "show", "briefing", "--campaign", "spring",
|
||||
"--config", "before.yml", "--config=", "--overlay", "base.yml", "--overlay=",
|
||||
"--version", "1", "--version", "2", "--profile", "first", "--profile", "editorial",
|
||||
"--profile", "first", "--profile", "editorial",
|
||||
"--session-id", "old-session", "--session-id", "session-42", "--format", "text", "--format", "yaml",
|
||||
"--var", "note=hello, world", "--var", "empty=", "--var", "token=a=b", "--var", "=value",
|
||||
"--var", "mode=brief", "--var", "mode=full",
|
||||
@@ -168,7 +170,7 @@ func TestRequirementsCommandCapturesContextAndVariableAssignments(t *testing.T)
|
||||
t.Fatalf("configuration selection = %#v", received.Selection)
|
||||
}
|
||||
wantVariables := map[string]string{"note": "hello, world", "empty": "", "token": "a=b", "": "value", "mode": "full"}
|
||||
if received.Inspection.PromptID != "briefing" || received.Inspection.PromptVersion != "2" || received.Inspection.ProfileID != "editorial" || received.Inspection.SessionID != "session-42" || !reflect.DeepEqual(received.Inspection.Vars, wantVariables) {
|
||||
if received.Inspection.PromptID != "briefing" || received.Inspection.ProfileID != "editorial" || received.Inspection.SessionID != "session-42" || !reflect.DeepEqual(received.Inspection.Vars, wantVariables) {
|
||||
t.Fatalf("native request = %#v, want vars %#v", received.Inspection, wantVariables)
|
||||
}
|
||||
if !receivedInput.campaign.Set || receivedInput.campaign.Value != "spring" || receivedState.call != 1 {
|
||||
@@ -184,7 +186,7 @@ func TestRequirementsCommandCapturesContextAndVariableAssignments(t *testing.T)
|
||||
if outcome.Kind != commandkit.OutcomeSuccess || newInputCalls != 2 || checkInputCalls != 2 || newStateCalls != 2 || providerCalls != 2 {
|
||||
t.Fatalf("second invocation = %#v, calls=%d/%d/%d/%d", outcome, newInputCalls, checkInputCalls, newStateCalls, providerCalls)
|
||||
}
|
||||
if len(received.Inspection.Vars) != 0 || received.Inspection.PromptVersion != "" || received.Inspection.ProfileID != "" || received.Inspection.SessionID != "" {
|
||||
if len(received.Inspection.Vars) != 0 || received.Inspection.ProfileID != "" || received.Inspection.SessionID != "" {
|
||||
t.Fatalf("second invocation retained native values: %#v", received.Inspection)
|
||||
}
|
||||
var defaultReport map[string]any
|
||||
@@ -299,7 +301,7 @@ func TestCatalogListUsesPreparedInputAndPreflightsFormat(t *testing.T) {
|
||||
ListPrompts: func(_ context.Context, selection ckconfig.Selection, value input, gotState state) (commandkit.Acquired[[]promptkit.PromptIdentity], error) {
|
||||
providerCalls++
|
||||
received, receivedSelection, receivedState = value, selection, gotState
|
||||
return commandkit.Acquired[[]promptkit.PromptIdentity]{Value: []promptkit.PromptIdentity{{ID: "briefing", Version: "1"}}}, nil
|
||||
return commandkit.Acquired[[]promptkit.PromptIdentity]{Value: []promptkit.PromptIdentity{{ID: "briefing", Version: testStringPointer("1")}}}, nil
|
||||
},
|
||||
}
|
||||
app := newPromptTestApp(t, Command(suite))
|
||||
@@ -437,9 +439,10 @@ func TestCatalogNilFactoriesSupplyZeroValues(t *testing.T) {
|
||||
|
||||
func TestCatalogCommandsRenderNativeValuesAndEmptySequences(t *testing.T) {
|
||||
prompts := []promptkit.PromptIdentity{
|
||||
{ID: "later", Version: "1.10"},
|
||||
{ID: "001", Version: " 03 "},
|
||||
{ID: "a: true", Version: "yes"},
|
||||
{ID: "later", Version: testStringPointer("1.10")},
|
||||
{ID: "001", Version: testStringPointer(" 03 ")},
|
||||
{ID: "a: true", Version: testStringPointer("yes")},
|
||||
{ID: "without-version"},
|
||||
}
|
||||
profiles := []string{"later", "001", "a: true", "later"}
|
||||
suite := Suite[struct{}, struct{}]{
|
||||
@@ -465,9 +468,16 @@ func TestCatalogCommandsRenderNativeValuesAndEmptySequences(t *testing.T) {
|
||||
}
|
||||
for index, entry := range promptEntries {
|
||||
id, idOK := entry["id"].(string)
|
||||
version, versionOK := entry["version"].(string)
|
||||
if len(entry) != 2 || !idOK || !versionOK || id != prompts[index].ID || version != prompts[index].Version {
|
||||
t.Errorf("prompt entry %d = %#v, want string id/version %q/%q", index, entry, prompts[index].ID, prompts[index].Version)
|
||||
if !idOK || id != prompts[index].ID {
|
||||
t.Errorf("prompt entry %d = %#v, want ID %q", index, entry, prompts[index].ID)
|
||||
}
|
||||
version, versionExists := entry["version"]
|
||||
if prompts[index].Version == nil {
|
||||
if versionExists || len(entry) != 1 {
|
||||
t.Errorf("prompt entry %d emitted absent version: %#v", index, entry)
|
||||
}
|
||||
} else if !versionExists || version != *prompts[index].Version || len(entry) != 2 {
|
||||
t.Errorf("prompt entry %d version = %#v, want %q", index, version, *prompts[index].Version)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +575,7 @@ func TestCatalogFailuresRetainDiagnosticsAndDeliveryState(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
canceled := newPromptTestApp(t, Command(Suite[struct{}, struct{}]{ListPrompts: func(context.Context, ckconfig.Selection, struct{}, struct{}) (commandkit.Acquired[[]promptkit.PromptIdentity], error) {
|
||||
cancel()
|
||||
return commandkit.Acquired[[]promptkit.PromptIdentity]{Value: []promptkit.PromptIdentity{{ID: "briefing", Version: "1"}}, Diagnostics: []commandkit.Diagnostic{diagnostic}}, nil
|
||||
return commandkit.Acquired[[]promptkit.PromptIdentity]{Value: []promptkit.PromptIdentity{{ID: "briefing", Version: testStringPointer("1")}}, Diagnostics: []commandkit.Diagnostic{diagnostic}}, nil
|
||||
}}))
|
||||
var output bytes.Buffer
|
||||
outcome = canceled.Execute(ctx, []string{"promptkit", "list", "prompts"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
||||
@@ -584,7 +594,7 @@ func TestCatalogFailuresRetainDiagnosticsAndDeliveryState(t *testing.T) {
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
writerApp := newPromptTestApp(t, Command(Suite[struct{}, struct{}]{ListPrompts: func(context.Context, ckconfig.Selection, struct{}, struct{}) (commandkit.Acquired[[]promptkit.PromptIdentity], error) {
|
||||
return commandkit.Acquired[[]promptkit.PromptIdentity]{Value: []promptkit.PromptIdentity{{ID: "briefing", Version: "1"}}, Diagnostics: []commandkit.Diagnostic{diagnostic}}, nil
|
||||
return commandkit.Acquired[[]promptkit.PromptIdentity]{Value: []promptkit.PromptIdentity{{ID: "briefing", Version: testStringPointer("1")}}, Diagnostics: []commandkit.Diagnostic{diagnostic}}, nil
|
||||
}}))
|
||||
outcome := writerApp.Execute(context.Background(), []string{"promptkit", "list", "prompts"}, 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 || !hasCatalogWarning(outcome.Diagnostics) {
|
||||
@@ -663,22 +673,22 @@ func TestDefinitionInputAndStateLifetimesFollowChecks(t *testing.T) {
|
||||
},
|
||||
InspectPrompt: func(ctx context.Context, request PromptRequest, input *inspectInput, state *runState) (commandkit.Acquired[*promptkit.PromptInspection], error) {
|
||||
callbacks++
|
||||
if ctx != wantContext || input != checked || request.ID != "briefing" || !request.Version.Set || request.Version.Value != "2" || state == nil {
|
||||
if ctx != wantContext || input != checked || request.ID != "briefing" || state == nil {
|
||||
t.Errorf("prompt callback arguments = ctx=%v request=%#v input=%p state=%p", ctx, request, input, state)
|
||||
}
|
||||
return commandkit.Acquired[*promptkit.PromptInspection]{Value: &promptkit.PromptInspection{PromptID: request.ID, PromptVersion: request.Version.Value}}, nil
|
||||
return commandkit.Acquired[*promptkit.PromptInspection]{Value: &promptkit.PromptInspection{PromptID: request.ID}}, nil
|
||||
},
|
||||
}
|
||||
app := newPromptTestApp(t, Command(suite))
|
||||
wantContext = context.WithValue(context.Background(), struct{}{}, "context")
|
||||
var output bytes.Buffer
|
||||
outcome := app.Execute(wantContext, []string{"promptkit", "show", "prompt", "briefing", "--campaign", "spring", "--config", "base.yml", "--overlay", "local.yml", "--version", "2"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
||||
outcome := app.Execute(wantContext, []string{"promptkit", "show", "prompt", "briefing", "--campaign", "spring", "--config", "base.yml", "--overlay", "local.yml"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
||||
if outcome.Kind != commandkit.OutcomeSuccess || newInputs != 1 || newStates != 1 || checks != 1 || callbacks != 1 || conversions != 1 {
|
||||
t.Fatalf("execution outcome=%#v counts conversion/input/state/check/callback=%d/%d/%d/%d/%d report=%q", outcome, conversions, newInputs, newStates, checks, callbacks, output.String())
|
||||
}
|
||||
rejectInput = true
|
||||
output.Reset()
|
||||
outcome = app.Execute(wantContext, []string{"promptkit", "show", "prompt", "briefing", "--campaign", "spring", "--config", "base.yml", "--overlay", "local.yml", "--version", "2"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
||||
outcome = app.Execute(wantContext, []string{"promptkit", "show", "prompt", "briefing", "--campaign", "spring", "--config", "base.yml", "--overlay", "local.yml"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
||||
if outcome.Kind != commandkit.OutcomeUsage || newInputs != 2 || newStates != 1 || checks != 2 || callbacks != 1 || conversions != 2 {
|
||||
t.Fatalf("rejected input reached state/callback: outcome=%#v counts=%d/%d/%d/%d/%d", outcome, conversions, newInputs, newStates, checks, callbacks)
|
||||
}
|
||||
@@ -694,7 +704,7 @@ func TestDefinitionReportsRetainNativeFieldsAndSafeCredentialReferences(t *testi
|
||||
})
|
||||
app := newPromptTestApp(t, Command(suite))
|
||||
var output bytes.Buffer
|
||||
outcome := app.Execute(context.Background(), []string{"promptkit", "show", "prompt", "briefing", "--version", "1", "--format", "yaml"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
||||
outcome := app.Execute(context.Background(), []string{"promptkit", "show", "prompt", "briefing", "--format", "yaml"}, commandkit.Streams{Out: &output, Err: io.Discard})
|
||||
if outcome.Kind != commandkit.OutcomeSuccess || loadCalls != 1 {
|
||||
t.Fatalf("prompt report outcome=%#v load calls=%d report=%s", outcome, loadCalls, output.String())
|
||||
}
|
||||
@@ -756,6 +766,75 @@ func TestDefinitionReportsRetainNativeFieldsAndSafeCredentialReferences(t *testi
|
||||
}
|
||||
}
|
||||
|
||||
func TestOptionalPromptVersionsPreserveAbsenceAndEmptyValues(t *testing.T) {
|
||||
empty := ""
|
||||
label := "release-1"
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
version *string
|
||||
present bool
|
||||
want string
|
||||
}{
|
||||
{name: "absent"},
|
||||
{name: "present empty", version: &empty, present: true, want: ""},
|
||||
{name: "nonempty", version: &label, present: true, want: "release-1"},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
prompt := promptReportFromInspection(&promptkit.PromptInspection{PromptID: "briefing", PromptVersion: test.version})
|
||||
promptBytes, err := encodePromptYAMLBytes(prompt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var promptReport map[string]any
|
||||
if err := yaml.Unmarshal(promptBytes, &promptReport); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assertOptionalVersion(t, promptReport, test.present, test.want)
|
||||
text := formatPromptText(prompt)
|
||||
if test.present && !strings.Contains(text, "Prompt version: "+strconv.Quote(test.want)+"\n") {
|
||||
t.Errorf("text omitted present version %q: %q", test.want, text)
|
||||
}
|
||||
if !test.present && strings.Contains(text, "Prompt version:") {
|
||||
t.Errorf("text emitted absent version: %q", text)
|
||||
}
|
||||
|
||||
requirementsBytes, err := encodePromptYAMLBytes(requirementsReportFromInspection(&promptkit.RequirementInspection{PromptID: "briefing", PromptVersion: test.version}))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var requirementsReport map[string]any
|
||||
if err := yaml.Unmarshal(requirementsBytes, &requirementsReport); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assertOptionalVersion(t, requirementsReport, test.present, test.want)
|
||||
|
||||
catalogBytes, err := encodePromptCatalog([]promptkit.PromptIdentity{{ID: "briefing", Version: test.version}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var catalog []map[string]any
|
||||
if err := yaml.Unmarshal(catalogBytes, &catalog); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(catalog) != 1 || catalog[0]["id"] != "briefing" {
|
||||
t.Fatalf("catalog = %#v", catalog)
|
||||
}
|
||||
assertOptionalVersion(t, catalog[0], test.present, test.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assertOptionalVersion(t *testing.T, report map[string]any, present bool, want string) {
|
||||
t.Helper()
|
||||
version, found := report["version"]
|
||||
if found != present {
|
||||
t.Fatalf("version presence = %t in %#v, want %t", found, report, present)
|
||||
}
|
||||
if present && version != want {
|
||||
t.Errorf("version = %#v, want %q", version, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNativeLookupErrorsAndBlankIDsReachCallbacks(t *testing.T) {
|
||||
nativeErr := errors.New("native lookup failure")
|
||||
calls := 0
|
||||
@@ -780,6 +859,18 @@ func TestNativeLookupErrorsAndBlankIDsReachCallbacks(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamedPromptInspectionRejectsRemovedVersionFlag(t *testing.T) {
|
||||
calls := 0
|
||||
app := newPromptTestApp(t, Command(Suite[struct{}, struct{}]{InspectPrompt: func(_ context.Context, request PromptRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.PromptInspection], error) {
|
||||
calls++
|
||||
return commandkit.Acquired[*promptkit.PromptInspection]{Value: &promptkit.PromptInspection{PromptID: request.ID}}, nil
|
||||
}}))
|
||||
outcome := app.Execute(context.Background(), []string{"promptkit", "show", "prompt", "briefing", "--version", "1"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||||
if outcome.Kind != commandkit.OutcomeUsage || calls != 0 {
|
||||
t.Fatalf("removed version flag outcome = %#v, provider calls=%d", outcome, calls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelledInspectionDoesNotRender(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
called := 0
|
||||
@@ -838,9 +929,9 @@ func TestProfileTextUsesCredentialNamesAndExplicitEmptyExtraParams(t *testing.T)
|
||||
|
||||
func TestPromptCatalogYAMLPreservesSchemaStringsAndOrder(t *testing.T) {
|
||||
want := []promptkit.PromptIdentity{
|
||||
{ID: " briefing ", Version: " 03 "},
|
||||
{ID: "001", Version: "1.10"},
|
||||
{ID: " briefing ", Version: " 03 "},
|
||||
{ID: " briefing ", Version: testStringPointer(" 03 ")},
|
||||
{ID: "001", Version: testStringPointer("1.10")},
|
||||
{ID: " briefing ", Version: testStringPointer(" 03 ")},
|
||||
}
|
||||
output, err := encodePromptCatalog(want)
|
||||
if err != nil {
|
||||
@@ -859,8 +950,8 @@ func TestPromptCatalogYAMLPreservesSchemaStringsAndOrder(t *testing.T) {
|
||||
}
|
||||
id, idOK := entry["id"].(string)
|
||||
version, versionOK := entry["version"].(string)
|
||||
if !idOK || !versionOK || id != want[index].ID || version != want[index].Version {
|
||||
t.Errorf("entry %d = %#v, want id/version %q/%q as strings", index, entry, want[index].ID, want[index].Version)
|
||||
if !idOK || !versionOK || id != want[index].ID || want[index].Version == nil || version != *want[index].Version {
|
||||
t.Errorf("entry %d = %#v, want id/version %q/%#v", index, entry, want[index].ID, want[index].Version)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -917,11 +1008,14 @@ func TestRequirementsReportRendersEmptyInventoriesAndFalseValues(t *testing.T) {
|
||||
if err := yaml.Unmarshal(output, &report); err != nil {
|
||||
t.Fatalf("decode requirements report %q: %v", output, err)
|
||||
}
|
||||
for _, key := range []string{"prompt_id", "prompt_version", "profile_id", "complete", "inputs", "variables", "issues"} {
|
||||
for _, key := range []string{"prompt_id", "profile_id", "complete", "inputs", "variables", "issues"} {
|
||||
if _, ok := report[key]; !ok {
|
||||
t.Errorf("requirements report is missing %q: %q", key, output)
|
||||
}
|
||||
}
|
||||
if _, ok := report["version"]; ok {
|
||||
t.Errorf("absent prompt version was emitted: %q", output)
|
||||
}
|
||||
if report["complete"] != false {
|
||||
t.Errorf("complete = %#v, want false", report["complete"])
|
||||
}
|
||||
@@ -931,7 +1025,7 @@ func TestRequirementsReportRendersEmptyInventoriesAndFalseValues(t *testing.T) {
|
||||
t.Errorf("%s = %#v, want an empty sequence", key, report[key])
|
||||
}
|
||||
}
|
||||
for _, key := range []string{"prompt_id", "prompt_version", "profile_id"} {
|
||||
for _, key := range []string{"prompt_id", "profile_id"} {
|
||||
if report[key] != "" {
|
||||
t.Errorf("%s = %#v, want an explicitly present empty string", key, report[key])
|
||||
}
|
||||
@@ -943,7 +1037,7 @@ func TestRequirementsReportPreservesNativeFieldsAndMetadata(t *testing.T) {
|
||||
contentType := "true"
|
||||
inspection := &promptkit.RequirementInspection{
|
||||
PromptID: "true",
|
||||
PromptVersion: "001",
|
||||
PromptVersion: testStringPointer("001"),
|
||||
ProfileID: "null",
|
||||
Complete: true,
|
||||
Inputs: []promptkit.InputRequirement{
|
||||
@@ -973,7 +1067,7 @@ func TestRequirementsReportPreservesNativeFieldsAndMetadata(t *testing.T) {
|
||||
if err := yaml.Unmarshal(output, &report); err != nil {
|
||||
t.Fatalf("decode requirements report %q: %v", output, err)
|
||||
}
|
||||
if report["complete"] != complete || report["prompt_id"] != "true" || report["prompt_version"] != "001" || report["profile_id"] != "null" {
|
||||
if report["complete"] != complete || report["prompt_id"] != "true" || report["version"] != "001" || report["profile_id"] != "null" {
|
||||
t.Fatalf("selected context or completeness = %#v", report)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user