Files
promptkit/internal/configuration/interpretation_test.go

153 lines
7.2 KiB
Go

package configuration
import (
"context"
"strings"
"testing"
"go.maximumdirect.net/configkit"
)
func TestTargetResolutionNormalizesNestedValues(t *testing.T) {
state, err := load(mapping("padded target", map[string]any{
"backends": []any{map[string]any{
"id": "local", "endpoint": " HTTPS://example.invalid/v1 ", "concurrency_limit": 1,
"smoke_tests": map[string]any{
"reachability": map[string]any{"endpoint": " https://example.invalid/health "},
"authentication": map[string]any{"kind": " NONE ", "endpoint": " https://example.invalid/key "},
},
}},
"profiles": []any{map[string]any{"id": "partial", "backend": "local", "service_tier": " standard ", "api_key_env": " TOKEN "}},
}), nil)
if err != nil {
t.Fatal(err)
}
backend, err := state.GetBackend("local")
if err != nil || backend.Endpoint != "https://example.invalid/v1" || backend.QueueCapacity != 1024 ||
backend.SmokeTests == nil || *backend.SmokeTests.Reachability.Endpoint != "https://example.invalid/health" ||
*backend.SmokeTests.Authentication.Kind != "none" || *backend.SmokeTests.Authentication.Endpoint != "https://example.invalid/key" {
t.Fatalf("interpreted backend = %+v, %v", backend, err)
}
profile, err := state.GetProfile(context.Background(), "partial")
if err != nil || profile.ResolvedTarget.ServiceTier != "standard" || profile.ResolvedTarget.APIKeyEnv != "TOKEN" {
t.Fatalf("interpreted profile = %+v, %v", profile, err)
}
composed := state.result.Config.Backends[0]
if *composed.Endpoint != "https://example.invalid/v1" || composed.QueueCapacity == nil || *composed.QueueCapacity != 1024 ||
*composed.SmokeTests.Reachability.Endpoint != "https://example.invalid/health" ||
*composed.SmokeTests.Authentication.Kind != "none" || *composed.SmokeTests.Authentication.Endpoint != "https://example.invalid/key" ||
*state.result.Config.Profiles[0].ServiceTier != "standard" || *state.result.Config.Profiles[0].APIKeyEnv != "TOKEN" {
t.Fatalf("resolved values were not normalized: %+v", state.result.Config)
}
path := configkit.Keys("backends").Index(0).Key("smoke_tests").Key("authentication").Key("endpoint")
field, found := state.result.Metadata().Lookup(path)
if !found || field.Origin.Operation != configkit.ChangeNormalization {
t.Fatalf("nested field origin changed: %+v", field)
}
for _, path := range []configkit.Path{
configkit.Keys("backends").Index(0).Key("endpoint"),
configkit.Keys("backends").Index(0).Key("smoke_tests").Key("reachability").Key("endpoint"),
configkit.Keys("backends").Index(0).Key("smoke_tests").Key("authentication").Key("kind"),
configkit.Keys("profiles").Index(0).Key("service_tier"),
configkit.Keys("profiles").Index(0).Key("api_key_env"),
} {
field, found := state.result.Metadata().Lookup(path)
if !found || field.Origin.Operation != configkit.ChangeNormalization {
t.Errorf("normalization at %v: %+v", path, field)
}
}
}
func TestPromptResolutionNormalizesOutputAndRejectsDuplicateNames(t *testing.T) {
definition := map[string]any{
"id": "example", "inputs": []any{map[string]any{"name": " document "}},
"messages": []any{map[string]any{"role": "user", "content": "hello"}},
"output": map[string]any{"format": "json", "validation_mode": "json_schema", "schema_path": " schema.json "},
}
state, err := load(mapping("prompt metadata", map[string]any{"prompts": []any{definition}}), nil)
if err != nil {
t.Fatal(err)
}
selected, inspection, err := state.prompt("example")
if err != nil || selected.Validation.SchemaPath != "schema.json" || inspection.OutputContract.SchemaPath != "schema.json" || selected.Inputs[0].Name != "document" {
t.Fatalf("interpreted prompt = %+v, %+v, %v", selected, inspection, err)
}
composed := state.result.Config.Prompts[0]
if *composed.Output.SchemaPath != "schema.json" || composed.Inputs[0].Name != "document" {
t.Fatalf("prompt was not normalized: %+v", composed)
}
definition["inputs"] = []any{map[string]any{"name": " document "}, map[string]any{"name": "document"}}
_, err = load(mapping("duplicate inputs", map[string]any{"prompts": []any{definition}}), nil)
if err == nil || !strings.Contains(err.Error(), "/prompts/0/inputs/1") || !strings.Contains(err.Error(), "duplicated") {
t.Fatalf("duplicate normalized names were not rejected: %v", err)
}
}
func TestPromptResolutionRecordsMessageFields(t *testing.T) {
loadPrompt := func(role, cacheType, ttl string) *loaded {
t.Helper()
state, err := load(mapping("prompt", map[string]any{"prompts": []any{map[string]any{
"id": "example", "inputs": []any{map[string]any{"name": " input ", "content_type": nil, "description": " text "}},
"messages": []any{map[string]any{"role": role, "content": "", "cache_control": map[string]any{"type": cacheType, "ttl": ttl}}},
"output": map[string]any{"format": "text", "validation_mode": "basic"},
}}}), nil)
if err != nil {
t.Fatal(err)
}
return state
}
padded := loadPrompt(" USER ", " ephemeral ", " 1h ")
canonical := loadPrompt("user", "ephemeral", "1h")
definition, inspection, err := padded.prompt("example")
if err != nil {
t.Fatal(err)
}
other, otherInspection, err := canonical.prompt("example")
if err != nil || inspection.PromptHash != otherInspection.PromptHash || definition.Templates[0].Role != other.Templates[0].Role || definition.Templates[0].Content != "" {
t.Fatalf("equivalent prompt mismatch: %+v %+v %v", definition, other, err)
}
base := configkit.Keys("prompts").Index(0)
for _, path := range []configkit.Path{base.Key("inputs").Index(0).Key("name"), base.Key("inputs").Index(0).Key("description"), base.Key("messages").Index(0).Key("role"), base.Key("messages").Index(0).Key("cache_control").Key("type"), base.Key("messages").Index(0).Key("cache_control").Key("ttl")} {
field, found := padded.result.Metadata().Lookup(path)
if !found || field.Origin.Operation != configkit.ChangeNormalization {
t.Errorf("normalization at %v: %+v", path, field)
}
}
if padded.promptMetadata["example"][0].contentType != fieldNull {
t.Fatal("null input metadata was not retained")
}
}
func TestResolutionRecordsTargetDependencies(t *testing.T) {
backend := func(id string) map[string]any {
return map[string]any{"id": id, "endpoint": " HTTPS://example.invalid/v1 ", "concurrency_limit": 2, "queue_capacity": nil}
}
state, err := load(mapping("targets", map[string]any{
"backends": []any{backend("root")},
"collections": map[string]any{"scoped": map[string]any{"backends": []any{backend("local")}}},
}), nil)
if err != nil {
t.Fatal(err)
}
for _, base := range []configkit.Path{configkit.Keys("backends").Index(0), configkit.Keys("collections", "scoped", "backends").Index(0)} {
endpoint, ok := state.result.Explain(base.Key("endpoint"))
if !ok || !strings.Contains(endpoint.Effective.YAML, "https://example.invalid/v1") {
t.Fatalf("endpoint explanation: %+v", endpoint)
}
history := state.result.Metadata().History(base.Key("queue_capacity"))
found := false
for _, change := range history {
if change.Origin.Operation == configkit.ChangeDerivedDefault {
for _, dependency := range change.Dependencies {
if dependency.String() == base.Key("concurrency_limit").String() {
found = true
}
}
}
}
if !found {
t.Fatalf("missing queue dependency: %+v", history)
}
}
}