diff --git a/cuesonnet_decode_test.go b/cuesonnet_decode_test.go deleted file mode 100644 index 366847898f4e14f0d6c1db60c0f6cf72254f462e..0000000000000000000000000000000000000000 --- a/cuesonnet_decode_test.go +++ /dev/null @@ -1,618 +0,0 @@ -package cuesonnet_test - -import ( - "reflect" - "strings" - "testing" - - "go.jolheiser.com/cuesonnet" -) - -// checkDecode decodes data into T via sc and compares with expected using reflect.DeepEqual. -func checkDecode[T any](t *testing.T, sc cuesonnet.Schema, data string, expected T) { - t.Helper() - var got T - if err := sc.Decode(strings.NewReader(data), &got); err != nil { - t.Fatalf("decode error: %v", err) - } - if !reflect.DeepEqual(got, expected) { - t.Errorf("value mismatch:\n got: %+v\n want: %+v", got, expected) - } -} - -// decode wraps checkDecode into a check func for use in table-driven tests. -func decode[T any](expected T) func(*testing.T, cuesonnet.Schema, string) { - return func(t *testing.T, sc cuesonnet.Schema, data string) { - t.Helper() - checkDecode(t, sc, data, expected) - } -} - -type ( - PersonDecode struct { - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - Age int `json:"age"` - Birthday string `json:"birthday"` - Gopher bool `json:"gopher"` - } - - PrimitivesDecode struct { - Str string `json:"str"` - Num int `json:"num"` - Dec float64 `json:"dec"` - Flag bool `json:"flag"` - Qty float64 `json:"qty"` - } - - ConstraintsDecode struct { - Age int `json:"age"` - Score float64 `json:"score"` - Username string `json:"username"` - Bio string `json:"bio"` - Level int `json:"level"` - Slug string `json:"slug"` - } - - // Metadata and Annotations are _ in CUE; decoded type depends on the data. - AnyDecode struct { - Name string `json:"name"` - Metadata any `json:"metadata"` - Annotations any `json:"annotations,omitempty"` - } - - ClosedDecode struct { - Name string `json:"name"` - Age int `json:"age"` - } - - OptionalDecode struct { - Name string `json:"name"` - Email string `json:"email"` - Phone string `json:"phone,omitempty"` - Bio string `json:"bio,omitempty"` - } - - AddressDecode struct { - Street string `json:"street"` - City string `json:"city"` - Zip string `json:"zip"` - } - ContactDecode struct { - Label string `json:"label"` - Value string `json:"value"` - } - NestedDecode struct { - Name string `json:"name"` - Address AddressDecode `json:"address"` - Contacts []ContactDecode `json:"contacts"` - } - - ListItemDecode struct { - ID int `json:"id"` - Label string `json:"label"` - } - ListsDecode struct { - Items []ListItemDecode `json:"items"` - Tags []string `json:"tags"` - Counts []int `json:"counts"` - Limited []string `json:"limited"` - } - - // Value and Nullable are disjunction types; any holds the concrete runtime value. - DisjunctionsDecode struct { - Value any `json:"value"` - Mode string `json:"mode"` - Priority int `json:"priority"` - Nullable any `json:"nullable"` - } - - DefaultsDecode struct { - Name string `json:"name"` - Role string `json:"role"` - Enabled bool `json:"enabled"` - Timeout int `json:"timeout"` - Tags []string `json:"tags"` - } - - EnumsDecode struct { - Color string `json:"color"` - Status string `json:"status"` - Priority int `json:"priority"` - Flags []string `json:"flags"` - } - - DefNameDecode struct { - First string `json:"first"` - Last string `json:"last"` - } - DefContactDecode struct { - Email string `json:"email,omitempty"` - Phone string `json:"phone,omitempty"` - } - DefPersonDecode struct { - Name DefNameDecode `json:"name"` - Age int `json:"age"` - Contact DefContactDecode `json:"contact"` - } - - StdlibDecode struct { - CreatedAt string `json:"createdAt"` - Birthday string `json:"birthday"` - Username string `json:"username"` - Tags []string `json:"tags"` - Initials string `json:"initials"` - Angle float64 `json:"angle"` - } - - CompositionDecode struct { - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - CreatedAt string `json:"createdAt"` - UpdatedAt string `json:"updatedAt"` - Age int `json:"age"` - } - - PatternsDecode struct { - Name string `json:"name"` - Labels map[string]string `json:"labels"` - Counts map[string]int `json:"counts"` - } - - // CUE fixed-length tuples decode positionally; Tag is [string, int] so []any. - TuplesDecode struct { - Color []int `json:"color"` - Position []float64 `json:"position"` - Tag []any `json:"tag"` - } - - FunctionUserDecode struct { - Name string `json:"name"` - Greeting string `json:"greeting"` - Age int `json:"age"` - } - - ComprehensionItemDecode struct { - Index int `json:"index"` - Squared int `json:"squared"` - Label string `json:"label"` - } - - ConditionalEntryDecode struct { - Value int `json:"value"` - Category string `json:"category"` - Doubled int `json:"doubled"` - } - - InheritanceDecode struct { - Kind string `json:"kind"` - Version string `json:"version"` - Name string `json:"name"` - Replicas int `json:"replicas"` - Image string `json:"image"` - } - - MultilineDecode struct { - Description string `json:"description"` - Template string `json:"template"` - } - - SelfRefDecode struct { - Width int `json:"width"` - Height int `json:"height"` - Area int `json:"area"` - Perimeter int `json:"perimeter"` - } - - JStdlibDecode struct { - Upper string `json:"upper"` - Joined string `json:"joined"` - Formatted string `json:"formatted"` - Count int `json:"count"` - Words []string `json:"words"` - Mapped []string `json:"mapped"` - Filtered []string `json:"filtered"` - } -) - -func TestCUEsonnetDecode(t *testing.T) { - type decodeTest struct { - name string - schema string - data string - check func(*testing.T, cuesonnet.Schema, string) - } - - jim := PersonDecode{ - FirstName: "Jim", - LastName: "Jimbly", - Age: 45, - Birthday: "01/02/2003", - Gopher: true, - } - - tests := []decodeTest{ - // person - { - name: "person/valid", - schema: "testdata/person/schema.cue", - data: "testdata/person/valid.jsonnet", - check: decode(jim), - }, - { - name: "person/functions", - schema: "testdata/person/schema.cue", - data: "testdata/person/functions.jsonnet", - check: decode(jim), - }, - { - name: "person/list", - schema: "testdata/person/schema_list.cue", - data: "testdata/person/functions_list.jsonnet", - check: decode([]PersonDecode{jim}), - }, - - // primitives - { - name: "primitives/valid", - schema: "testdata/primitives/schema.cue", - data: "testdata/primitives/valid.jsonnet", - check: decode(PrimitivesDecode{Str: "hello", Num: 42, Dec: 3.14, Flag: true, Qty: 2.718}), - }, - - // constraints - { - name: "constraints/valid", - schema: "testdata/constraints/schema.cue", - data: "testdata/constraints/valid.jsonnet", - check: decode(ConstraintsDecode{Age: 30, Score: 95.5, Username: "john_doe", Bio: "A software engineer.", Level: 5, Slug: "my-slug"}), - }, - - // structs/any - // valid_scalar: metadata is a plain string — no type ambiguity. - { - name: "structs/any/valid_scalar", - schema: "testdata/structs/any/schema.cue", - data: "testdata/structs/any/valid_scalar.jsonnet", - check: decode(AnyDecode{Name: "Alice", Metadata: "just a plain string"}), - }, - // valid_object: metadata is a JSON object; CUE decodes it to map[string]any. - { - name: "structs/any/valid_object", - schema: "testdata/structs/any/schema.cue", - data: "testdata/structs/any/valid_object.jsonnet", - check: func(t *testing.T, sc cuesonnet.Schema, data string) { - t.Helper() - var got AnyDecode - if err := sc.Decode(strings.NewReader(data), &got); err != nil { - t.Fatalf("decode error: %v", err) - } - if got.Name != "Alice" { - t.Errorf("Name: got %q, want %q", got.Name, "Alice") - } - meta, ok := got.Metadata.(map[string]any) - if !ok { - t.Fatalf("Metadata: got %T, want map[string]any", got.Metadata) - } - if meta["role"] != "admin" { - t.Errorf("Metadata.role: got %v, want %q", meta["role"], "admin") - } - if _, ok := got.Annotations.(map[string]any); !ok { - t.Errorf("Annotations: got %T, want map[string]any", got.Annotations) - } - }, - }, - - // structs/closed - { - name: "structs/closed/valid", - schema: "testdata/structs/closed/schema.cue", - data: "testdata/structs/closed/valid.jsonnet", - check: decode(ClosedDecode{Name: "Alice", Age: 30}), - }, - - // structs/optional - { - name: "structs/optional/full", - schema: "testdata/structs/optional/schema.cue", - data: "testdata/structs/optional/valid_full.jsonnet", - check: decode(OptionalDecode{Name: "Alice", Email: "alice@example.com", Phone: "555-1234", Bio: "Software engineer."}), - }, - { - name: "structs/optional/minimal", - schema: "testdata/structs/optional/schema.cue", - data: "testdata/structs/optional/valid_minimal.jsonnet", - check: decode(OptionalDecode{Name: "Alice", Email: "alice@example.com"}), - }, - - // structs/nested - { - name: "structs/nested/valid", - schema: "testdata/structs/nested/schema.cue", - data: "testdata/structs/nested/valid.jsonnet", - check: decode(NestedDecode{ - Name: "Alice", - Address: AddressDecode{Street: "123 Main St", City: "Springfield", Zip: "12345"}, - Contacts: []ContactDecode{ - {Label: "email", Value: "alice@example.com"}, - {Label: "phone", Value: "555-1234"}, - }, - }), - }, - - // lists - { - name: "lists/valid", - schema: "testdata/lists/schema.cue", - data: "testdata/lists/valid.jsonnet", - check: decode(ListsDecode{ - Items: []ListItemDecode{{ID: 1, Label: "first"}, {ID: 2, Label: "second"}}, - Tags: []string{"go", "cue", "jsonnet"}, - Counts: []int{0, 1, 2, 100}, - Limited: []string{"only", "a", "few"}, - }), - }, - - // disjunctions - // valid_a: all any fields hold strings — no type ambiguity. - { - name: "disjunctions/valid_a", - schema: "testdata/disjunctions/schema.cue", - data: "testdata/disjunctions/valid_a.jsonnet", - check: decode(DisjunctionsDecode{Value: "text", Mode: "read", Priority: 1, Nullable: "present"}), - }, - // valid_b: Value is an integer and Nullable is null. - // CUE decodes integers into any as int64; null becomes nil. - { - name: "disjunctions/valid_b", - schema: "testdata/disjunctions/schema.cue", - data: "testdata/disjunctions/valid_b.jsonnet", - check: func(t *testing.T, sc cuesonnet.Schema, data string) { - t.Helper() - var got DisjunctionsDecode - if err := sc.Decode(strings.NewReader(data), &got); err != nil { - t.Fatalf("decode error: %v", err) - } - if got.Mode != "write" { - t.Errorf("Mode: got %q, want %q", got.Mode, "write") - } - if got.Priority != 3 { - t.Errorf("Priority: got %d, want 3", got.Priority) - } - if got.Nullable != nil { - t.Errorf("Nullable: got %v, want nil", got.Nullable) - } - switch v := got.Value.(type) { - case int64: - if v != 42 { - t.Errorf("Value: got %d, want 42", v) - } - case float64: - if v != 42 { - t.Errorf("Value: got %g, want 42", v) - } - default: - t.Errorf("Value: unexpected type %T (value %v)", got.Value, got.Value) - } - }, - }, - - // defaults - // minimal: only name provided; CUE fills role="user", enabled=true, timeout=30, tags=[]. - { - name: "defaults/minimal", - schema: "testdata/defaults/schema.cue", - data: "testdata/defaults/valid_minimal.jsonnet", - check: decode(DefaultsDecode{Name: "Alice", Role: "user", Enabled: true, Timeout: 30, Tags: []string{}}), - }, - { - name: "defaults/override", - schema: "testdata/defaults/schema.cue", - data: "testdata/defaults/valid_override.jsonnet", - check: decode(DefaultsDecode{Name: "Alice", Role: "admin", Enabled: false, Timeout: 60, Tags: []string{"api", "v2"}}), - }, - - // enums - { - name: "enums/valid", - schema: "testdata/enums/schema.cue", - data: "testdata/enums/valid.jsonnet", - check: decode(EnumsDecode{Color: "red", Status: "active", Priority: 3, Flags: []string{"a", "b"}}), - }, - - // definitions - { - name: "definitions/valid", - schema: "testdata/definitions/schema.cue", - data: "testdata/definitions/valid.jsonnet", - check: decode([]DefPersonDecode{ - {Name: DefNameDecode{First: "Alice", Last: "Smith"}, Age: 30, Contact: DefContactDecode{Email: "alice@example.com"}}, - {Name: DefNameDecode{First: "Bob", Last: "Jones"}, Age: 25, Contact: DefContactDecode{Phone: "555-123-4567"}}, - {Name: DefNameDecode{First: "Carol", Last: "White"}, Age: 42, Contact: DefContactDecode{Email: "carol@example.com", Phone: "123-456-7890"}}, - }), - }, - - // stdlib - { - name: "stdlib/valid", - schema: "testdata/stdlib/schema.cue", - data: "testdata/stdlib/valid.jsonnet", - check: decode(StdlibDecode{ - CreatedAt: "2024-01-15T10:30:00Z", - Birthday: "01/15/1990", - Username: "alice42", - Tags: []string{"go", "cue", "jsonnet"}, - Initials: "AB", - Angle: 3.14, - }), - }, - - // composition - { - name: "composition/valid", - schema: "testdata/composition/schema.cue", - data: "testdata/composition/valid.jsonnet", - check: decode([]CompositionDecode{ - {FirstName: "Alice", LastName: "Smith", CreatedAt: "2024-01-15T10:00:00Z", UpdatedAt: "2024-06-01T12:00:00Z", Age: 30}, - {FirstName: "Bob", LastName: "Jones", CreatedAt: "2023-05-20T08:30:00Z", UpdatedAt: "2023-05-20T08:30:00Z", Age: 25}, - }), - }, - - // patterns - { - name: "patterns/valid", - schema: "testdata/patterns/schema.cue", - data: "testdata/patterns/valid.jsonnet", - check: decode(PatternsDecode{ - Name: "service-a", - Labels: map[string]string{ - "env": "production", - "region": "us-east-1", - "team": "platform", - }, - Counts: map[string]int{ - "requests": 1000, - "errors": 5, - "warnings": 42, - }, - }), - }, - - // tuples - // Color and Position are uniformly typed; Tag is [string, int] so []any. - // The int element decodes as int64 or float64 depending on CUE version. - { - name: "tuples/valid", - schema: "testdata/tuples/schema.cue", - data: "testdata/tuples/valid.jsonnet", - check: func(t *testing.T, sc cuesonnet.Schema, data string) { - t.Helper() - var got TuplesDecode - if err := sc.Decode(strings.NewReader(data), &got); err != nil { - t.Fatalf("decode error: %v", err) - } - if !reflect.DeepEqual(got.Color, []int{255, 128, 0}) { - t.Errorf("Color: got %v, want [255 128 0]", got.Color) - } - if !reflect.DeepEqual(got.Position, []float64{1.5, 2.7}) { - t.Errorf("Position: got %v, want [1.5 2.7]", got.Position) - } - if len(got.Tag) != 2 { - t.Fatalf("Tag: got len %d, want 2", len(got.Tag)) - } - if got.Tag[0] != "priority" { - t.Errorf("Tag[0]: got %v, want %q", got.Tag[0], "priority") - } - switch v := got.Tag[1].(type) { - case int64: - if v != 1 { - t.Errorf("Tag[1]: got %d, want 1", v) - } - case float64: - if v != 1 { - t.Errorf("Tag[1]: got %g, want 1", v) - } - default: - t.Errorf("Tag[1]: unexpected type %T (value %v)", got.Tag[1], got.Tag[1]) - } - }, - }, - - // jsonnet/functions - { - name: "jsonnet/functions", - schema: "testdata/jsonnet/functions/schema.cue", - data: "testdata/jsonnet/functions/data.jsonnet", - check: decode([]FunctionUserDecode{ - {Name: "Alice", Greeting: "Hello, Alice!", Age: 30}, - {Name: "Bob", Greeting: "Hello, Bob!", Age: 25}, - {Name: "Carol", Greeting: "Hello, Carol!", Age: 35}, - }), - }, - - // jsonnet/comprehensions - { - name: "jsonnet/comprehensions", - schema: "testdata/jsonnet/comprehensions/schema.cue", - data: "testdata/jsonnet/comprehensions/data.jsonnet", - check: decode([]ComprehensionItemDecode{ - {Index: 0, Squared: 1, Label: "item-1"}, - {Index: 1, Squared: 4, Label: "item-2"}, - {Index: 2, Squared: 9, Label: "item-3"}, - {Index: 3, Squared: 16, Label: "item-4"}, - {Index: 4, Squared: 25, Label: "item-5"}, - }), - }, - - // jsonnet/conditionals - { - name: "jsonnet/conditionals", - schema: "testdata/jsonnet/conditionals/schema.cue", - data: "testdata/jsonnet/conditionals/data.jsonnet", - check: decode([]ConditionalEntryDecode{ - {Value: 3, Category: "small", Doubled: 6}, - {Value: 42, Category: "medium", Doubled: 84}, - {Value: 150, Category: "large", Doubled: 300}, - }), - }, - - // jsonnet/inheritance - { - name: "jsonnet/inheritance", - schema: "testdata/jsonnet/inheritance/schema.cue", - data: "testdata/jsonnet/inheritance/data.jsonnet", - check: decode(InheritanceDecode{Kind: "Deployment", Version: "v1", Name: "my-app", Replicas: 3, Image: "myapp:latest"}), - }, - - // jsonnet/multiline - { - name: "jsonnet/multiline", - schema: "testdata/jsonnet/multiline/schema.cue", - data: "testdata/jsonnet/multiline/data.jsonnet", - check: decode(MultilineDecode{ - Description: "This is a multi-line\nstring in Jsonnet.\nIt supports indentation.\n", - Template: "Name: my-app\nVersion: v1.0\n", - }), - }, - - // jsonnet/self_reference - { - name: "jsonnet/self_reference", - schema: "testdata/jsonnet/self_reference/schema.cue", - data: "testdata/jsonnet/self_reference/data.jsonnet", - check: decode(SelfRefDecode{Width: 10, Height: 20, Area: 200, Perimeter: 60}), - }, - - // jsonnet/object_comprehension - // Schema is [string]: int; decode directly into map[string]int. - { - name: "jsonnet/object_comprehension", - schema: "testdata/jsonnet/object_comprehension/schema.cue", - data: "testdata/jsonnet/object_comprehension/data.jsonnet", - check: decode(map[string]int{"alice_score": 95, "bob_score": 87, "carol_score": 92}), - }, - - // jsonnet/stdlib - { - name: "jsonnet/stdlib", - schema: "testdata/jsonnet/stdlib/schema.cue", - data: "testdata/jsonnet/stdlib/data.jsonnet", - check: decode(JStdlibDecode{ - Upper: "HELLO", - Joined: "hello, world, jsonnet", - Formatted: "count=3, first=hello", - Count: 3, - Words: []string{"hello", "world", "jsonnet"}, - Mapped: []string{"HELLO", "WORLD", "JSONNET"}, - Filtered: []string{"jsonnet"}, - }), - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - tc.check(t, cuesonnet.Schema(mustReadFile(t, tc.schema)), mustReadFile(t, tc.data)) - }) - } -} diff --git a/cuesonnet_test.go b/cuesonnet_test.go index 9c835d68e45956b24236d2e0d452a01771dce5dc..8f52a14d70c2e021ca7763fc7ada029882651bb9 100644 --- a/cuesonnet_test.go +++ b/cuesonnet_test.go @@ -1,363 +1,105 @@ package cuesonnet_test import ( - "os" + _ "embed" "strings" "testing" "go.jolheiser.com/cuesonnet" ) -type testCase struct { - name string - schema string - data string - wantErr bool - errContains []string -} - -var cases = []testCase{ - // person - { - name: "person/invalid", - schema: "testdata/person/schema.cue", - data: "testdata/person/invalid.jsonnet", - wantErr: true, - errContains: []string{"firstName", "age"}, - }, - { - name: "person/almost_valid", - schema: "testdata/person/schema.cue", - data: "testdata/person/almost_valid.jsonnet", - wantErr: true, - errContains: []string{"LastName"}, - }, - { - name: "person/valid", - schema: "testdata/person/schema.cue", - data: "testdata/person/valid.jsonnet", - }, - { - name: "person/functions", - schema: "testdata/person/schema.cue", - data: "testdata/person/functions.jsonnet", - }, - { - name: "person/list", - schema: "testdata/person/schema_list.cue", - data: "testdata/person/functions_list.jsonnet", - }, - - // primitives - { - name: "primitives/valid", - schema: "testdata/primitives/schema.cue", - data: "testdata/primitives/valid.jsonnet", - }, - { - name: "primitives/invalid", - schema: "testdata/primitives/schema.cue", - data: "testdata/primitives/invalid.jsonnet", - wantErr: true, - errContains: []string{"str", "num", "dec", "flag", "qty"}, - }, - - // constraints - { - name: "constraints/valid", - schema: "testdata/constraints/schema.cue", - data: "testdata/constraints/valid.jsonnet", - }, - { - name: "constraints/invalid_range", - schema: "testdata/constraints/schema.cue", - data: "testdata/constraints/invalid_range.jsonnet", - wantErr: true, - errContains: []string{"age", "score", "level"}, - }, - { - name: "constraints/invalid_pattern", - schema: "testdata/constraints/schema.cue", - data: "testdata/constraints/invalid_pattern.jsonnet", - wantErr: true, - errContains: []string{"username", "bio", "slug"}, - }, - - // structs/any - { - name: "structs/any/valid_object", - schema: "testdata/structs/any/schema.cue", - data: "testdata/structs/any/valid_object.jsonnet", - }, - { - name: "structs/any/valid_scalar", - schema: "testdata/structs/any/schema.cue", - data: "testdata/structs/any/valid_scalar.jsonnet", - }, - { - name: "structs/any/invalid", - schema: "testdata/structs/any/schema.cue", - data: "testdata/structs/any/invalid.jsonnet", - wantErr: true, - errContains: []string{"name"}, - }, - - // structs/closed - { - name: "structs/closed/valid", - schema: "testdata/structs/closed/schema.cue", - data: "testdata/structs/closed/valid.jsonnet", - }, - { - name: "structs/closed/invalid", - schema: "testdata/structs/closed/schema.cue", - data: "testdata/structs/closed/invalid_extra.jsonnet", - wantErr: true, - errContains: []string{"email"}, - }, - - // structs/optional - { - name: "structs/optional/full", - schema: "testdata/structs/optional/schema.cue", - data: "testdata/structs/optional/valid_full.jsonnet", - }, - { - name: "structs/optional/minimal", - schema: "testdata/structs/optional/schema.cue", - data: "testdata/structs/optional/valid_minimal.jsonnet", - }, - { - name: "structs/optional/invalid", - schema: "testdata/structs/optional/schema.cue", - data: "testdata/structs/optional/invalid.jsonnet", - wantErr: true, - errContains: []string{"email"}, - }, - - // structs/nested - { - name: "structs/nested/valid", - schema: "testdata/structs/nested/schema.cue", - data: "testdata/structs/nested/valid.jsonnet", - }, - { - name: "structs/nested/invalid", - schema: "testdata/structs/nested/schema.cue", - data: "testdata/structs/nested/invalid.jsonnet", - wantErr: true, - errContains: []string{"zip", "value"}, - }, - - // lists - { - name: "lists/valid", - schema: "testdata/lists/schema.cue", - data: "testdata/lists/valid.jsonnet", - }, - { - name: "lists/invalid_element", - schema: "testdata/lists/schema.cue", - data: "testdata/lists/invalid_element.jsonnet", - wantErr: true, - errContains: []string{"id", "label"}, - }, - { - name: "lists/invalid_length", - schema: "testdata/lists/schema.cue", - data: "testdata/lists/invalid_length.jsonnet", - wantErr: true, - errContains: []string{"limited"}, - }, - - // disjunctions - { - name: "disjunctions/valid_a", - schema: "testdata/disjunctions/schema.cue", - data: "testdata/disjunctions/valid_a.jsonnet", - }, - { - name: "disjunctions/valid_b", - schema: "testdata/disjunctions/schema.cue", - data: "testdata/disjunctions/valid_b.jsonnet", - }, - { - name: "disjunctions/invalid", - schema: "testdata/disjunctions/schema.cue", - data: "testdata/disjunctions/invalid.jsonnet", - wantErr: true, - errContains: []string{"mode", "priority"}, - }, - - // defaults - { - name: "defaults/minimal", - schema: "testdata/defaults/schema.cue", - data: "testdata/defaults/valid_minimal.jsonnet", - }, - { - name: "defaults/override", - schema: "testdata/defaults/schema.cue", - data: "testdata/defaults/valid_override.jsonnet", - }, - - // enums - { - name: "enums/valid", - schema: "testdata/enums/schema.cue", - data: "testdata/enums/valid.jsonnet", - }, - { - name: "enums/invalid", - schema: "testdata/enums/schema.cue", - data: "testdata/enums/invalid.jsonnet", - wantErr: true, - errContains: []string{"color", "status", "priority"}, - }, - - // definitions - { - name: "definitions/valid", - schema: "testdata/definitions/schema.cue", - data: "testdata/definitions/valid.jsonnet", - }, - { - name: "definitions/invalid", - schema: "testdata/definitions/schema.cue", - data: "testdata/definitions/invalid.jsonnet", - wantErr: true, - errContains: []string{"age", "email", "phone"}, - }, - - // stdlib (time, strings, list, math packages) - { - name: "stdlib/valid", - schema: "testdata/stdlib/schema.cue", - data: "testdata/stdlib/valid.jsonnet", - }, - { - name: "stdlib/invalid", - schema: "testdata/stdlib/schema.cue", - data: "testdata/stdlib/invalid.jsonnet", - wantErr: true, - errContains: []string{"createdAt", "birthday", "username", "tags", "initials", "angle"}, - }, - - // composition (definition embedding, let bindings) - { - name: "composition/valid", - schema: "testdata/composition/schema.cue", - data: "testdata/composition/valid.jsonnet", - }, - { - name: "composition/invalid", - schema: "testdata/composition/schema.cue", - data: "testdata/composition/invalid.jsonnet", - wantErr: true, - errContains: []string{"updatedAt", "age"}, - }, - - // patterns ([string]: type pattern constraints) - { - name: "patterns/valid", - schema: "testdata/patterns/schema.cue", - data: "testdata/patterns/valid.jsonnet", - }, - { - name: "patterns/invalid", - schema: "testdata/patterns/schema.cue", - data: "testdata/patterns/invalid.jsonnet", - wantErr: true, - errContains: []string{"labels", "counts"}, - }, - - // tuples (fixed-length positional lists) - { - name: "tuples/valid", - schema: "testdata/tuples/schema.cue", - data: "testdata/tuples/valid.jsonnet", - }, - { - name: "tuples/invalid", - schema: "testdata/tuples/schema.cue", - data: "testdata/tuples/invalid.jsonnet", - wantErr: true, - errContains: []string{"color", "position", "tag"}, - }, +var ( + //go:embed testdata/schema.cue + schema cuesonnet.Schema + //go:embed testdata/schema_list.cue + schemaList cuesonnet.Schema + //go:embed testdata/config.jsonnet + config string + //go:embed testdata/almost-fixed.jsonnet + almostFixed string + //go:embed testdata/fixed.jsonnet + fixed string + //go:embed testdata/kitchen.jsonnet + kitchen string + //go:embed testdata/kitchen_list.jsonnet + kitchenList string +) - // jsonnet features - { - name: "jsonnet/functions", - schema: "testdata/jsonnet/functions/schema.cue", - data: "testdata/jsonnet/functions/data.jsonnet", - }, - { - name: "jsonnet/comprehensions", - schema: "testdata/jsonnet/comprehensions/schema.cue", - data: "testdata/jsonnet/comprehensions/data.jsonnet", - }, - { - name: "jsonnet/object_comprehension", - schema: "testdata/jsonnet/object_comprehension/schema.cue", - data: "testdata/jsonnet/object_comprehension/data.jsonnet", - }, - { - name: "jsonnet/conditionals", - schema: "testdata/jsonnet/conditionals/schema.cue", - data: "testdata/jsonnet/conditionals/data.jsonnet", - }, - { - name: "jsonnet/inheritance", - schema: "testdata/jsonnet/inheritance/schema.cue", - data: "testdata/jsonnet/inheritance/data.jsonnet", - }, - { - name: "jsonnet/multiline", - schema: "testdata/jsonnet/multiline/schema.cue", - data: "testdata/jsonnet/multiline/data.jsonnet", - }, - { - name: "jsonnet/self_reference", - schema: "testdata/jsonnet/self_reference/schema.cue", - data: "testdata/jsonnet/self_reference/data.jsonnet", - }, - { - name: "jsonnet/stdlib", - schema: "testdata/jsonnet/stdlib/schema.cue", - data: "testdata/jsonnet/stdlib/data.jsonnet", - }, +type Schema struct { + FirstName string `json:"firstName"` + LastName string `json:"lastName"` + Age int `json:"age"` + Birthday string `json:"birthday"` + Gopher bool `json:"gopher"` } func TestCUEsonnet(t *testing.T) { - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - sc := cuesonnet.Schema(mustReadFile(t, tc.schema)) - var v any - err := sc.Decode(strings.NewReader(mustReadFile(t, tc.data)), &v) - if tc.wantErr { - if err == nil { - t.Fatal("expected error, got nil") - } - for _, sub := range tc.errContains { - if !strings.Contains(err.Error(), sub) { - t.Errorf("error missing %q\n full error: %v", sub, err) - } - } - return + t.Run("config", func(t *testing.T) { + t.Parallel() + var s Schema + err := schema.Decode(strings.NewReader(config), &s) + for _, s := range []string{"2", "firstName", "age"} { + if !strings.Contains(err.Error(), s) { + t.Logf("did not find %q in error", s) + t.Fail() } - if err != nil { - t.Fatalf("unexpected error: %v", err) + } + }) + + t.Run("almost-fixed", func(t *testing.T) { + t.Parallel() + var s Schema + err := schema.Decode(strings.NewReader(almostFixed), &s) + for _, s := range []string{"1", "LastName"} { + if !strings.Contains(err.Error(), s) { + t.Logf("did not find %q in error: %q", s, err) + t.Fail() } - }) - } -} + } + }) -func mustReadFile(t *testing.T, path string) string { - t.Helper() - b, err := os.ReadFile(path) - if err != nil { - t.Fatalf("read %s: %v", path, err) + expect := Schema{ + FirstName: "Jim", + LastName: "Jimbly", + Age: 45, + Birthday: "01/02/2003", + Gopher: true, } - return string(b) + t.Run("fixed", func(t *testing.T) { + t.Parallel() + var s Schema + if err := schema.Decode(strings.NewReader(fixed), &s); err != nil { + t.Logf("fixed config should not fail to decode: %v", err) + t.Fail() + } + if s != expect { + t.Logf("did not get expected decoding: %+v != %+v", s, expect) + t.Fail() + } + }) + t.Run("kitchen", func(t *testing.T) { + t.Parallel() + var s Schema + if err := schema.Decode(strings.NewReader(kitchen), &s); err != nil { + t.Logf("kitchen config should not fail to decode: %v", err) + t.Fail() + } + if s != expect { + t.Logf("did not get expected decoding: %+v != %+v", s, expect) + t.Fail() + } + }) + + t.Run("list", func(t *testing.T) { + t.Parallel() + var s []Schema + if err := schemaList.Decode(strings.NewReader(kitchenList), &s); err != nil { + t.Logf("kitchen_list config should not fail to decode: %v", err) + t.Fail() + } + if s[0] != expect { + t.Logf("did not get expected decoding: %+v != %+v", s, expect) + t.Fail() + } + }) } diff --git a/testdata/composition/invalid.jsonnet b/testdata/composition/invalid.jsonnet deleted file mode 100644 index 4780607208c5030b9348c8748ccb5630c2bc4868..0000000000000000000000000000000000000000 --- a/testdata/composition/invalid.jsonnet +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - firstName: 'Alice', - lastName: 'Smith', - createdAt: '2024-01-15T10:00:00Z', - updatedAt: 'not-a-timestamp', - age: 200, - }, -] diff --git a/testdata/composition/schema.cue b/testdata/composition/schema.cue deleted file mode 100644 index de5130045a7bac8718dbc3ffa645a50b1b1f000f..0000000000000000000000000000000000000000 --- a/testdata/composition/schema.cue +++ /dev/null @@ -1,23 +0,0 @@ -import "time" - -let MaxAge = 150 - -#Named: { - firstName: string - lastName: string -} - -#Timestamped: { - createdAt: time.Format(time.RFC3339) - updatedAt: time.Format(time.RFC3339) -} - -// Embed definitions inside the body to compose them with new fields. -// & between two closed definitions cannot add new fields; embedding can. -#Person: { - #Named - #Timestamped - age: int & >=0 & <=MaxAge -} - -[...#Person] diff --git a/testdata/composition/valid.jsonnet b/testdata/composition/valid.jsonnet deleted file mode 100644 index 2a063ddae0fa367e38cfa15b853ccacd9189a26b..0000000000000000000000000000000000000000 --- a/testdata/composition/valid.jsonnet +++ /dev/null @@ -1,16 +0,0 @@ -[ - { - firstName: 'Alice', - lastName: 'Smith', - createdAt: '2024-01-15T10:00:00Z', - updatedAt: '2024-06-01T12:00:00Z', - age: 30, - }, - { - firstName: 'Bob', - lastName: 'Jones', - createdAt: '2023-05-20T08:30:00Z', - updatedAt: '2023-05-20T08:30:00Z', - age: 25, - }, -] diff --git a/testdata/constraints/invalid_pattern.jsonnet b/testdata/constraints/invalid_pattern.jsonnet deleted file mode 100644 index dc09400648a89ff529cbd473599dd34be10db721..0000000000000000000000000000000000000000 --- a/testdata/constraints/invalid_pattern.jsonnet +++ /dev/null @@ -1,8 +0,0 @@ -{ - age: 30, - score: 50.0, - username: 'John Doe', - bio: '', - level: 3, - slug: 'Has Spaces!', -} diff --git a/testdata/constraints/invalid_range.jsonnet b/testdata/constraints/invalid_range.jsonnet deleted file mode 100644 index 5176e1c5e506a8aa120ebc180c332b163ba3ffa1..0000000000000000000000000000000000000000 --- a/testdata/constraints/invalid_range.jsonnet +++ /dev/null @@ -1,8 +0,0 @@ -{ - age: -1, - score: 101.0, - username: 'john_doe', - bio: 'A software engineer.', - level: 0, - slug: 'valid-slug', -} diff --git a/testdata/constraints/schema.cue b/testdata/constraints/schema.cue deleted file mode 100644 index 5fd3d5f853d5635e6cf46d7ecbca8e525838d342..0000000000000000000000000000000000000000 --- a/testdata/constraints/schema.cue +++ /dev/null @@ -1,11 +0,0 @@ -import "strings" - -#Schema: { - age: int & >=0 & <=150 - score: float & >=0.0 & <=100.0 - username: string & =~"^[a-z][a-z0-9_]{1,19}$" - bio: string & strings.MinRunes(1) & strings.MaxRunes(200) - level: int & !=0 - slug: string & !~"[^a-z0-9-]" -} -#Schema diff --git a/testdata/constraints/valid.jsonnet b/testdata/constraints/valid.jsonnet deleted file mode 100644 index 7ec10540399c856e816d17d91ee7e0f85dc3b44b..0000000000000000000000000000000000000000 --- a/testdata/constraints/valid.jsonnet +++ /dev/null @@ -1,8 +0,0 @@ -{ - age: 30, - score: 95.5, - username: 'john_doe', - bio: 'A software engineer.', - level: 5, - slug: 'my-slug', -} diff --git a/testdata/defaults/schema.cue b/testdata/defaults/schema.cue deleted file mode 100644 index d0a16302c240ac5fe3be6ea147a9a29b130a957a..0000000000000000000000000000000000000000 --- a/testdata/defaults/schema.cue +++ /dev/null @@ -1,8 +0,0 @@ -#Schema: { - name: string - role: "admin" | "user" | "guest" | *"user" - enabled: bool | *true - timeout: int | *30 - tags: [...string] | *[] -} -#Schema diff --git a/testdata/defaults/valid_minimal.jsonnet b/testdata/defaults/valid_minimal.jsonnet deleted file mode 100644 index d50010d13b8ca5671f7769ebea3e66ac96f82eb0..0000000000000000000000000000000000000000 --- a/testdata/defaults/valid_minimal.jsonnet +++ /dev/null @@ -1,3 +0,0 @@ -{ - name: 'Alice', -} diff --git a/testdata/defaults/valid_override.jsonnet b/testdata/defaults/valid_override.jsonnet deleted file mode 100644 index 6dbd7f7d47b3b87ce86a0031960348a64c38539f..0000000000000000000000000000000000000000 --- a/testdata/defaults/valid_override.jsonnet +++ /dev/null @@ -1,7 +0,0 @@ -{ - name: 'Alice', - role: 'admin', - enabled: false, - timeout: 60, - tags: ['api', 'v2'], -} diff --git a/testdata/definitions/invalid.jsonnet b/testdata/definitions/invalid.jsonnet deleted file mode 100644 index 89dec2f25a933c1a00a0384102957ac87bcd0811..0000000000000000000000000000000000000000 --- a/testdata/definitions/invalid.jsonnet +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - name: { first: 'Alice', last: 'Smith' }, - age: -1, - contact: { email: 'not-an-email' }, - }, - { - name: { first: 'Bob' }, - age: 25, - contact: { phone: '5551234567' }, - }, -] diff --git a/testdata/definitions/schema.cue b/testdata/definitions/schema.cue deleted file mode 100644 index a24508c56723ac43c24b66e1827357dfb476eb2c..0000000000000000000000000000000000000000 --- a/testdata/definitions/schema.cue +++ /dev/null @@ -1,17 +0,0 @@ -#Name: { - first: string - last: string -} - -#Contact: { - email?: =~"^[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}$" - phone?: =~"^[0-9]{3}-[0-9]{3}-[0-9]{4}$" -} - -#Person: { - name: #Name - age: int & >=0 - contact: #Contact -} - -[...#Person] diff --git a/testdata/definitions/valid.jsonnet b/testdata/definitions/valid.jsonnet deleted file mode 100644 index b17d4e1025ff148a269f96608d740f567201eee1..0000000000000000000000000000000000000000 --- a/testdata/definitions/valid.jsonnet +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - name: { first: 'Alice', last: 'Smith' }, - age: 30, - contact: { email: 'alice@example.com' }, - }, - { - name: { first: 'Bob', last: 'Jones' }, - age: 25, - contact: { phone: '555-123-4567' }, - }, - { - name: { first: 'Carol', last: 'White' }, - age: 42, - contact: { email: 'carol@example.com', phone: '123-456-7890' }, - }, -] diff --git a/testdata/disjunctions/invalid.jsonnet b/testdata/disjunctions/invalid.jsonnet deleted file mode 100644 index c77e81450b4a8b5795f5c954f929008912a1ab1a..0000000000000000000000000000000000000000 --- a/testdata/disjunctions/invalid.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - value: 3.14, - mode: 'exec', - priority: 5, - nullable: 42, -} diff --git a/testdata/disjunctions/schema.cue b/testdata/disjunctions/schema.cue deleted file mode 100644 index 4ed8057441b22dc508926a16f14427e0061f7d24..0000000000000000000000000000000000000000 --- a/testdata/disjunctions/schema.cue +++ /dev/null @@ -1,14 +0,0 @@ -#Schema: { - // Tagged union: string, int, or bool - value: string | int | bool - - // String enum (disjunction of literals) - mode: "read" | "write" | "readwrite" - - // Integer enum - priority: 1 | 2 | 3 - - // Nullable field - nullable: string | null -} -#Schema diff --git a/testdata/disjunctions/valid_a.jsonnet b/testdata/disjunctions/valid_a.jsonnet deleted file mode 100644 index a70f88a0bc29d4cd8c1396b19763c45466f6bdca..0000000000000000000000000000000000000000 --- a/testdata/disjunctions/valid_a.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - value: 'text', - mode: 'read', - priority: 1, - nullable: 'present', -} diff --git a/testdata/disjunctions/valid_b.jsonnet b/testdata/disjunctions/valid_b.jsonnet deleted file mode 100644 index b7f4f87f26e5e9e008becb72b7ae1ef7322a4543..0000000000000000000000000000000000000000 --- a/testdata/disjunctions/valid_b.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - value: 42, - mode: 'write', - priority: 3, - nullable: null, -} diff --git a/testdata/enums/invalid.jsonnet b/testdata/enums/invalid.jsonnet deleted file mode 100644 index f80b92ccf8ce39eb5b56ad27c1b8a116a28ee0ef..0000000000000000000000000000000000000000 --- a/testdata/enums/invalid.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - color: 'purple', - status: 'deleted', - priority: 6, - flags: ['a', 'd'], -} diff --git a/testdata/enums/schema.cue b/testdata/enums/schema.cue deleted file mode 100644 index dd8b91b1068bc4fced0ea2176f4f5e6f65419d48..0000000000000000000000000000000000000000 --- a/testdata/enums/schema.cue +++ /dev/null @@ -1,11 +0,0 @@ -#Color: "red" | "green" | "blue" -#Status: "active" | "inactive" | "pending" -#Priority: 1 | 2 | 3 | 4 | 5 - -#Schema: { - color: #Color - status: #Status - priority: #Priority - flags: [...("a" | "b" | "c")] -} -#Schema diff --git a/testdata/enums/valid.jsonnet b/testdata/enums/valid.jsonnet deleted file mode 100644 index 4b1c60021c02f77a2bb8378b70bdc7c9aaa46448..0000000000000000000000000000000000000000 --- a/testdata/enums/valid.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - color: 'red', - status: 'active', - priority: 3, - flags: ['a', 'b'], -} diff --git a/testdata/jsonnet/comprehensions/data.jsonnet b/testdata/jsonnet/comprehensions/data.jsonnet deleted file mode 100644 index 76719de64ca5e56515794e184319e2573b968ce1..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/comprehensions/data.jsonnet +++ /dev/null @@ -1,10 +0,0 @@ -local nums = [1, 2, 3, 4, 5]; - -[ - { - index: n - 1, - squared: n * n, - label: 'item-' + std.toString(n), - } - for n in nums -] diff --git a/testdata/jsonnet/comprehensions/schema.cue b/testdata/jsonnet/comprehensions/schema.cue deleted file mode 100644 index 951d5b7f89e50e70fbd2d990bf9c22eda9d51784..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/comprehensions/schema.cue +++ /dev/null @@ -1,6 +0,0 @@ -#Item: { - index: int & >=0 - squared: int & >=0 - label: string -} -[...#Item] diff --git a/testdata/jsonnet/conditionals/data.jsonnet b/testdata/jsonnet/conditionals/data.jsonnet deleted file mode 100644 index 6f2eb25a8b8c35420f5d457f0d85978a13d25bb7..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/conditionals/data.jsonnet +++ /dev/null @@ -1,15 +0,0 @@ -local classify = function(n) - if n < 10 then 'small' - else if n < 100 then 'medium' - else 'large'; - -local nums = [3, 42, 150]; - -[ - { - value: n, - category: classify(n), - doubled: n * 2, - } - for n in nums -] diff --git a/testdata/jsonnet/conditionals/schema.cue b/testdata/jsonnet/conditionals/schema.cue deleted file mode 100644 index 03b6ad2455eff2dc1729e2dc44c703e5052947a3..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/conditionals/schema.cue +++ /dev/null @@ -1,6 +0,0 @@ -#Entry: { - value: int - category: "small" | "medium" | "large" - doubled: int -} -[...#Entry] diff --git a/testdata/jsonnet/functions/data.jsonnet b/testdata/jsonnet/functions/data.jsonnet deleted file mode 100644 index 901ec9ab4b75e4e5262da635447218cdf6f74d35..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/functions/data.jsonnet +++ /dev/null @@ -1,13 +0,0 @@ -local greet = function(name) 'Hello, ' + name + '!'; - -local makeUser = function(name, age) { - name: name, - greeting: greet(name), - age: age, -}; - -[ - makeUser('Alice', 30), - makeUser('Bob', 25), - makeUser('Carol', 35), -] diff --git a/testdata/jsonnet/functions/schema.cue b/testdata/jsonnet/functions/schema.cue deleted file mode 100644 index 41ba021d2da2f5eccd4207800b2c1e5795f8d094..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/functions/schema.cue +++ /dev/null @@ -1,6 +0,0 @@ -#User: { - name: string - greeting: string - age: int & >=0 -} -[...#User] diff --git a/testdata/jsonnet/inheritance/data.jsonnet b/testdata/jsonnet/inheritance/data.jsonnet deleted file mode 100644 index b85eb4f1a7d1da97977bac73f0163c83e15ce710..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/inheritance/data.jsonnet +++ /dev/null @@ -1,13 +0,0 @@ -local base = { - kind: 'Deployment', - version: 'v1', - replicas: 1, -}; - -local production = base + { - name: 'my-app', - replicas: 3, - image: 'myapp:latest', -}; - -production diff --git a/testdata/jsonnet/inheritance/schema.cue b/testdata/jsonnet/inheritance/schema.cue deleted file mode 100644 index 3160904bdc68d7b516c732bc00ea725bd020ebc0..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/inheritance/schema.cue +++ /dev/null @@ -1,8 +0,0 @@ -#Schema: { - kind: string - version: string - name: string - replicas: int & >=1 - image: string -} -#Schema diff --git a/testdata/jsonnet/multiline/data.jsonnet b/testdata/jsonnet/multiline/data.jsonnet deleted file mode 100644 index d20f01a6971df4cb54f7b45ef5e2278c9ae2cb9b..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/multiline/data.jsonnet +++ /dev/null @@ -1,15 +0,0 @@ -local description = ||| - This is a multi-line - string in Jsonnet. - It supports indentation. -|||; - -local template = ||| - Name: %s - Version: %s -||| % ['my-app', 'v1.0']; - -{ - description: description, - template: template, -} diff --git a/testdata/jsonnet/multiline/schema.cue b/testdata/jsonnet/multiline/schema.cue deleted file mode 100644 index f60a8a8a6f18da7b8c54d2d26e028937837edbb2..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/multiline/schema.cue +++ /dev/null @@ -1,5 +0,0 @@ -#Schema: { - description: string - template: string -} -#Schema diff --git a/testdata/jsonnet/object_comprehension/data.jsonnet b/testdata/jsonnet/object_comprehension/data.jsonnet deleted file mode 100644 index 97f1f8164e91b1b79a40c4af753fa1b9a4b5e114..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/object_comprehension/data.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -local scores = { alice: 95, bob: 87, carol: 92 }; - -{ - [k + '_score']: scores[k] - for k in std.objectFields(scores) -} diff --git a/testdata/jsonnet/object_comprehension/schema.cue b/testdata/jsonnet/object_comprehension/schema.cue deleted file mode 100644 index 48b3cd92c13c35c51c423b408807cedb79879a21..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/object_comprehension/schema.cue +++ /dev/null @@ -1,5 +0,0 @@ -// Pattern constraint validates an object with arbitrary string keys. -#Schema: { - [string]: int & >=0 -} -#Schema diff --git a/testdata/jsonnet/self_reference/data.jsonnet b/testdata/jsonnet/self_reference/data.jsonnet deleted file mode 100644 index f88118c63d638b61b8e304f2bffdf7efd3aa60f5..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/self_reference/data.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - width: 10, - height: 20, - area: self.width * self.height, - perimeter: 2 * (self.width + self.height), -} diff --git a/testdata/jsonnet/self_reference/schema.cue b/testdata/jsonnet/self_reference/schema.cue deleted file mode 100644 index 30913447c3c57fac7c7539f54f8fb3150f97e3b9..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/self_reference/schema.cue +++ /dev/null @@ -1,7 +0,0 @@ -#Schema: { - width: int & >0 - height: int & >0 - area: int & >0 - perimeter: int & >0 -} -#Schema diff --git a/testdata/jsonnet/stdlib/data.jsonnet b/testdata/jsonnet/stdlib/data.jsonnet deleted file mode 100644 index 87b37d2cc97b6f0cbbff8afb3fdc80f456f7338d..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/stdlib/data.jsonnet +++ /dev/null @@ -1,11 +0,0 @@ -local words = ['hello', 'world', 'jsonnet']; - -{ - upper: std.asciiUpper(words[0]), - joined: std.join(', ', words), - formatted: std.format('count=%d, first=%s', [std.length(words), words[0]]), - count: std.length(words), - words: words, - mapped: std.map(function(w) std.asciiUpper(w), words), - filtered: std.filter(function(w) std.length(w) > 5, words), -} diff --git a/testdata/jsonnet/stdlib/schema.cue b/testdata/jsonnet/stdlib/schema.cue deleted file mode 100644 index d53cf96ae36adeda423fae36b25c33333dbfafc7..0000000000000000000000000000000000000000 --- a/testdata/jsonnet/stdlib/schema.cue +++ /dev/null @@ -1,10 +0,0 @@ -#Schema: { - upper: string - joined: string - formatted: string - count: int & >=0 - words: [...string] - mapped: [...string] - filtered: [...string] -} -#Schema diff --git a/testdata/lists/invalid_element.jsonnet b/testdata/lists/invalid_element.jsonnet deleted file mode 100644 index 3901ebdb253252ba4ca9a1a51b0a228b2f01ce94..0000000000000000000000000000000000000000 --- a/testdata/lists/invalid_element.jsonnet +++ /dev/null @@ -1,9 +0,0 @@ -{ - items: [ - { id: 0, label: 'bad-id' }, - { id: 1, label: 42 }, - ], - tags: ['a', 2, 'c'], - counts: [1, -1, 3], - limited: ['ok'], -} diff --git a/testdata/lists/invalid_length.jsonnet b/testdata/lists/invalid_length.jsonnet deleted file mode 100644 index d3d2fa32964c8736aa6e23152bfb95b69fd78f4e..0000000000000000000000000000000000000000 --- a/testdata/lists/invalid_length.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - items: [], - tags: [], - counts: [], - limited: ['a', 'b', 'c', 'd', 'e', 'f'], -} diff --git a/testdata/lists/schema.cue b/testdata/lists/schema.cue deleted file mode 100644 index ebae88dc81e9ecc9e1bbaa4e7ea3145d7105aa1b..0000000000000000000000000000000000000000 --- a/testdata/lists/schema.cue +++ /dev/null @@ -1,14 +0,0 @@ -import "list" - -#Item: { - id: int & >0 - label: string -} - -#Schema: { - items: [...#Item] - tags: [...string] - counts: [...int & >=0] - limited: list.MinItems(1) & list.MaxItems(5) & [...string] -} -#Schema diff --git a/testdata/lists/valid.jsonnet b/testdata/lists/valid.jsonnet deleted file mode 100644 index d72d418575bd40936343d3301289af778770be4d..0000000000000000000000000000000000000000 --- a/testdata/lists/valid.jsonnet +++ /dev/null @@ -1,9 +0,0 @@ -{ - items: [ - { id: 1, label: 'first' }, - { id: 2, label: 'second' }, - ], - tags: ['go', 'cue', 'jsonnet'], - counts: [0, 1, 2, 100], - limited: ['only', 'a', 'few'], -} diff --git a/testdata/patterns/invalid.jsonnet b/testdata/patterns/invalid.jsonnet deleted file mode 100644 index b0b5c37a3383bd7af4786150595c127ba701698a..0000000000000000000000000000000000000000 --- a/testdata/patterns/invalid.jsonnet +++ /dev/null @@ -1,9 +0,0 @@ -{ - name: 'service-a', - labels: { - env: 42, - }, - counts: { - requests: -1, - }, -} diff --git a/testdata/patterns/schema.cue b/testdata/patterns/schema.cue deleted file mode 100644 index 2f50ff4c4e7f18f85e5f3c033fdb5b65af013403..0000000000000000000000000000000000000000 --- a/testdata/patterns/schema.cue +++ /dev/null @@ -1,7 +0,0 @@ -// [string]: type constrains all values for arbitrary string keys. -#Schema: { - name: string - labels: {[string]: string} - counts: {[string]: int & >=0} -} -#Schema diff --git a/testdata/patterns/valid.jsonnet b/testdata/patterns/valid.jsonnet deleted file mode 100644 index e410039a99161c9ce92467a11257884ee2205694..0000000000000000000000000000000000000000 --- a/testdata/patterns/valid.jsonnet +++ /dev/null @@ -1,13 +0,0 @@ -{ - name: 'service-a', - labels: { - env: 'production', - region: 'us-east-1', - team: 'platform', - }, - counts: { - requests: 1000, - errors: 5, - warnings: 42, - }, -} diff --git a/testdata/person/almost_valid.jsonnet b/testdata/almost-fixed.jsonnet rename from testdata/person/almost_valid.jsonnet rename to testdata/almost-fixed.jsonnet diff --git a/testdata/person/functions.jsonnet b/testdata/kitchen.jsonnet rename from testdata/person/functions.jsonnet rename to testdata/kitchen.jsonnet diff --git a/testdata/person/functions_list.jsonnet b/testdata/kitchen_list.jsonnet rename from testdata/person/functions_list.jsonnet rename to testdata/kitchen_list.jsonnet diff --git a/testdata/person/invalid.jsonnet b/testdata/config.jsonnet rename from testdata/person/invalid.jsonnet rename to testdata/config.jsonnet diff --git a/testdata/person/schema.cue b/testdata/schema.cue rename from testdata/person/schema.cue rename to testdata/schema.cue index c937dff1fe4dc431092f73c65db212ae60f28c30..b23b930621669bc096d552ba6cd728f851830175 100644 --- a/testdata/person/schema.cue +++ b/testdata/schema.cue @@ -1,20 +1,20 @@ import "time" #Schema: { - // Basic fields + // Basic schema firstName: string lastName: string age: int birthday: string - // Refined constraints + // Refine as needed #Title: =~"^[A-Z]" | error("must start with an uppercase letter") firstName: #Title lastName: #Title age: >0 birthday: time.Format("01/02/2006") - // Default values + // Defaults gopher: bool | *true } diff --git a/testdata/person/schema_list.cue b/testdata/schema_list.cue rename from testdata/person/schema_list.cue rename to testdata/schema_list.cue index 9abfedb7f42f9f0353e041601e04a9e891f13ec8..02024313163d96024bd64c4f01ef2dbd7e83b788 100644 --- a/testdata/person/schema_list.cue +++ b/testdata/schema_list.cue @@ -1,22 +1,22 @@ import "time" #Schema: { - // Basic fields + // Basic schema firstName: string lastName: string age: int birthday: string - // Refined constraints + // Refine as needed #Title: =~"^[A-Z]" | error("must start with an uppercase letter") firstName: #Title lastName: #Title age: >0 birthday: time.Format("01/02/2006") - // Default values + // Defaults gopher: bool | *true } -// Apply the schema to a list +// Apply the schema to root [...#Schema] diff --git a/testdata/person/valid.jsonnet b/testdata/fixed.jsonnet rename from testdata/person/valid.jsonnet rename to testdata/fixed.jsonnet diff --git a/testdata/primitives/invalid.jsonnet b/testdata/primitives/invalid.jsonnet deleted file mode 100644 index cf6d5776dcf749ad41fe84ebd52208f931ad6bd8..0000000000000000000000000000000000000000 --- a/testdata/primitives/invalid.jsonnet +++ /dev/null @@ -1,7 +0,0 @@ -{ - str: 99, - num: 'not-a-number', - dec: false, - flag: 'yes', - qty: 'not-a-number', -} diff --git a/testdata/primitives/schema.cue b/testdata/primitives/schema.cue deleted file mode 100644 index 17bc916f80bc35eba968ef272813ce3aba7854fa..0000000000000000000000000000000000000000 --- a/testdata/primitives/schema.cue +++ /dev/null @@ -1,8 +0,0 @@ -#Schema: { - str: string - num: int - dec: float - flag: bool - qty: number -} -#Schema diff --git a/testdata/primitives/valid.jsonnet b/testdata/primitives/valid.jsonnet deleted file mode 100644 index 16ded5412a818dddf48578c1ca2a773996403660..0000000000000000000000000000000000000000 --- a/testdata/primitives/valid.jsonnet +++ /dev/null @@ -1,7 +0,0 @@ -{ - str: 'hello', - num: 42, - dec: 3.14, - flag: true, - qty: 2.718, -} diff --git a/testdata/stdlib/invalid.jsonnet b/testdata/stdlib/invalid.jsonnet deleted file mode 100644 index 8ec396e931bf3c3822cf34d5f4d86f578bac13f1..0000000000000000000000000000000000000000 --- a/testdata/stdlib/invalid.jsonnet +++ /dev/null @@ -1,8 +0,0 @@ -{ - createdAt: 'not-a-timestamp', - birthday: '1990-01-15', - username: 'ab', - tags: [], - initials: 'abc', - angle: 7.0, -} diff --git a/testdata/stdlib/schema.cue b/testdata/stdlib/schema.cue deleted file mode 100644 index c5104d116494fc25b387bf9d7a399159d671c9a2..0000000000000000000000000000000000000000 --- a/testdata/stdlib/schema.cue +++ /dev/null @@ -1,16 +0,0 @@ -import ( - "time" - "strings" - "list" - "math" -) - -#Schema: { - createdAt: time.Format(time.RFC3339) - birthday: time.Format("01/02/2006") - username: strings.MinRunes(3) & strings.MaxRunes(20) & =~"^[a-z]" - tags: list.MinItems(1) & list.MaxItems(10) & [...string] - initials: strings.MaxRunes(3) & =~"^[A-Z]+" - angle: float & >=0.0 & <=(math.Pi * 2) -} -#Schema diff --git a/testdata/stdlib/valid.jsonnet b/testdata/stdlib/valid.jsonnet deleted file mode 100644 index 55f3c358823ba2c7f9566775bfb1a1dc0c1f5132..0000000000000000000000000000000000000000 --- a/testdata/stdlib/valid.jsonnet +++ /dev/null @@ -1,8 +0,0 @@ -{ - createdAt: '2024-01-15T10:30:00Z', - birthday: '01/15/1990', - username: 'alice42', - tags: ['go', 'cue', 'jsonnet'], - initials: 'AB', - angle: 3.14, -} diff --git a/testdata/structs/any/invalid.jsonnet b/testdata/structs/any/invalid.jsonnet deleted file mode 100644 index cc91a2b3c3e734f7f556ed2d980ed31c225aa7c4..0000000000000000000000000000000000000000 --- a/testdata/structs/any/invalid.jsonnet +++ /dev/null @@ -1,4 +0,0 @@ -{ - name: 42, - metadata: 'anything', -} diff --git a/testdata/structs/any/schema.cue b/testdata/structs/any/schema.cue deleted file mode 100644 index d1b29ece2f7124bc795294f7e14960f3b1242616..0000000000000000000000000000000000000000 --- a/testdata/structs/any/schema.cue +++ /dev/null @@ -1,9 +0,0 @@ -// Fields typed as _ accept any concrete value while the rest of the -// definition stays closed. This is the correct escape hatch — using ... -// does not work because cue.Final() closes all open structs at validation time. -#Schema: { - name: string - metadata: _ // required; any concrete value accepted - annotations?: _ // optional; any concrete value accepted -} -#Schema diff --git a/testdata/structs/any/valid_object.jsonnet b/testdata/structs/any/valid_object.jsonnet deleted file mode 100644 index ae697f8c0307988996a77f8f7cf76fb5db28766e..0000000000000000000000000000000000000000 --- a/testdata/structs/any/valid_object.jsonnet +++ /dev/null @@ -1,12 +0,0 @@ -{ - name: 'Alice', - metadata: { - role: 'admin', - tags: ['a', 'b'], - active: true, - }, - annotations: { - created: '2024-01-15', - source: 'api', - }, -} diff --git a/testdata/structs/any/valid_scalar.jsonnet b/testdata/structs/any/valid_scalar.jsonnet deleted file mode 100644 index c6acaf141074546ab6ed32da91de0ab056a4dcd2..0000000000000000000000000000000000000000 --- a/testdata/structs/any/valid_scalar.jsonnet +++ /dev/null @@ -1,4 +0,0 @@ -{ - name: 'Alice', - metadata: 'just a plain string', -} diff --git a/testdata/structs/closed/invalid_extra.jsonnet b/testdata/structs/closed/invalid_extra.jsonnet deleted file mode 100644 index 008bec65ce3611fa0aff82dd84552e38d9783d81..0000000000000000000000000000000000000000 --- a/testdata/structs/closed/invalid_extra.jsonnet +++ /dev/null @@ -1,5 +0,0 @@ -{ - name: 'Alice', - age: 30, - email: 'alice@example.com', -} diff --git a/testdata/structs/closed/schema.cue b/testdata/structs/closed/schema.cue deleted file mode 100644 index c27474ead35f7591a87148cc2f4b40934d9218ce..0000000000000000000000000000000000000000 --- a/testdata/structs/closed/schema.cue +++ /dev/null @@ -1,6 +0,0 @@ -// Definition — closed by default; fields not listed here are rejected. -#Schema: { - name: string - age: int -} -#Schema diff --git a/testdata/structs/closed/valid.jsonnet b/testdata/structs/closed/valid.jsonnet deleted file mode 100644 index 3aa5ee8e796a53350b2d902bd99d5f0f3e68efca..0000000000000000000000000000000000000000 --- a/testdata/structs/closed/valid.jsonnet +++ /dev/null @@ -1,4 +0,0 @@ -{ - name: 'Alice', - age: 30, -} diff --git a/testdata/structs/nested/invalid.jsonnet b/testdata/structs/nested/invalid.jsonnet deleted file mode 100644 index 5b59b7ab93d4072cc18d0c13fd20cf7be7d1ae94..0000000000000000000000000000000000000000 --- a/testdata/structs/nested/invalid.jsonnet +++ /dev/null @@ -1,11 +0,0 @@ -{ - name: 'Alice', - address: { - street: '123 Main St', - city: 'Springfield', - zip: 'not-a-zip', - }, - contacts: [ - { label: 'email' }, - ], -} diff --git a/testdata/structs/nested/schema.cue b/testdata/structs/nested/schema.cue deleted file mode 100644 index fe696e34eb7653060e17a314ddd6177883a4b863..0000000000000000000000000000000000000000 --- a/testdata/structs/nested/schema.cue +++ /dev/null @@ -1,17 +0,0 @@ -#Address: { - street: string - city: string - zip: =~"^[0-9]{5}$" -} - -#Contact: { - label: string - value: string -} - -#Schema: { - name: string - address: #Address - contacts: [...#Contact] -} -#Schema diff --git a/testdata/structs/nested/valid.jsonnet b/testdata/structs/nested/valid.jsonnet deleted file mode 100644 index 4bf73fc867d9fe6e0394ee1bcd2747c71074a49b..0000000000000000000000000000000000000000 --- a/testdata/structs/nested/valid.jsonnet +++ /dev/null @@ -1,12 +0,0 @@ -{ - name: 'Alice', - address: { - street: '123 Main St', - city: 'Springfield', - zip: '12345', - }, - contacts: [ - { label: 'email', value: 'alice@example.com' }, - { label: 'phone', value: '555-1234' }, - ], -} diff --git a/testdata/structs/optional/invalid.jsonnet b/testdata/structs/optional/invalid.jsonnet deleted file mode 100644 index 01b8320e2fae613f1c9858435d1324779f07034c..0000000000000000000000000000000000000000 --- a/testdata/structs/optional/invalid.jsonnet +++ /dev/null @@ -1,4 +0,0 @@ -{ - name: 'Alice', - phone: '555-1234', -} diff --git a/testdata/structs/optional/schema.cue b/testdata/structs/optional/schema.cue deleted file mode 100644 index 8f02546a6fd326feca36004a004dda090fd25721..0000000000000000000000000000000000000000 --- a/testdata/structs/optional/schema.cue +++ /dev/null @@ -1,8 +0,0 @@ -// Required fields: name, email. Optional fields: phone, bio. -#Schema: { - name: string - email: string - phone?: string - bio?: string -} -#Schema diff --git a/testdata/structs/optional/valid_full.jsonnet b/testdata/structs/optional/valid_full.jsonnet deleted file mode 100644 index 2246204975553bc8d22091a7249c19e61fef3665..0000000000000000000000000000000000000000 --- a/testdata/structs/optional/valid_full.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - name: 'Alice', - email: 'alice@example.com', - phone: '555-1234', - bio: 'Software engineer.', -} diff --git a/testdata/structs/optional/valid_minimal.jsonnet b/testdata/structs/optional/valid_minimal.jsonnet deleted file mode 100644 index 44eaf4ef927571a56a320ee57fac468ac40ddbe4..0000000000000000000000000000000000000000 --- a/testdata/structs/optional/valid_minimal.jsonnet +++ /dev/null @@ -1,4 +0,0 @@ -{ - name: 'Alice', - email: 'alice@example.com', -} diff --git a/testdata/tuples/invalid.jsonnet b/testdata/tuples/invalid.jsonnet deleted file mode 100644 index efff60d93d4f4684b8f81682e2f33b643b497694..0000000000000000000000000000000000000000 --- a/testdata/tuples/invalid.jsonnet +++ /dev/null @@ -1,5 +0,0 @@ -{ - color: [256, 128, 0], - position: [1.5], - tag: ['priority', 'one'], -} diff --git a/testdata/tuples/schema.cue b/testdata/tuples/schema.cue deleted file mode 100644 index d21a3a338293abdcce01a9fd01bf72cd31b0b823..0000000000000000000000000000000000000000 --- a/testdata/tuples/schema.cue +++ /dev/null @@ -1,10 +0,0 @@ -// Fixed-length lists with typed positional elements. -#RGB: [int & >=0 & <=255, int & >=0 & <=255, int & >=0 & <=255] -#Point: [float, float] - -#Schema: { - color: #RGB - position: #Point - tag: [string, int] -} -#Schema diff --git a/testdata/tuples/valid.jsonnet b/testdata/tuples/valid.jsonnet deleted file mode 100644 index fe860e56b4255498946b7a19c08d6ce589d8f8e7..0000000000000000000000000000000000000000 --- a/testdata/tuples/valid.jsonnet +++ /dev/null @@ -1,5 +0,0 @@ -{ - color: [255, 128, 0], - position: [1.5, 2.7], - tag: ['priority', 1], -}