From 56e2bde57700cff81eb977229dfe2c6cd18ac8c3 Mon Sep 17 00:00:00 2001 From: Roger Peppe Date: Tue, 20 Aug 2024 13:21:57 +0100 Subject: [PATCH] encoding/jsonschema: encode oneOf etc using matchN This CL updates JSON Schema generation to use the newly added `matchN` primitive for `allOf`, `anyOf` and `oneOf`. This has a much closer correlation with the JSON Schema primitives than the current approach of using CUE's `&` and `|` operators. Specifically: - the schema arguments should not affect the final result other than to validate it, but both `&` and `|` can affect the result. - the result could become non-concrete due to `|` ambiguity in `anyOf`. Although this does fix a bunch of issues, there are some regressions. See issues #3418, #3420, #3422 for details. Comparative test stats (pre-matchN before post-matchN): ``` v2: schema extract (pass / total): 971 / 1637 = 59.3% schema extract (pass / total): 975 / 1637 = 59.6% tests (pass / total): 3081 / 7175 = 42.9% tests (pass / total): 3140 / 7175 = 43.8% tests on extracted schemas (pass / total): 3081 / 3542 = 87.0% tests on extracted schemas (pass / total): 3140 / 3546 = 88.6% v3: schema extract (pass / total): 971 / 1637 = 59.3% schema extract (pass / total): 967 / 1637 = 59.1% tests (pass / total): 3063 / 7175 = 42.7% tests (pass / total): 3074 / 7175 = 42.8% tests on extracted schemas (pass / total): 3063 / 3542 = 86.5% tests on extracted schemas (pass / total): 3074 / 3538 = 86.9% ``` For #3380 For #3165 Signed-off-by: Roger Peppe Change-Id: I2630a6d2b1614b2479802e788c16249d2cf4aa6b Dispatch-Trailer: {"type":"trybot","CL":1200526,"patchset":1,"ref":"refs/changes/26/1200526/1","targetBranch":"master"} --- encoding/jsonschema/constraints_combinator.go | 69 ++++++++++++++--- encoding/jsonschema/decode_test.go | 6 +- .../tests/draft2019-09/additionalItems.json | 4 +- .../external/tests/draft2019-09/allOf.json | 30 ++++++-- .../external/tests/draft2019-09/anyOf.json | 24 +++--- .../external/tests/draft2019-09/oneOf.json | 48 +++--------- .../external/tests/draft2020-12/allOf.json | 30 ++++++-- .../external/tests/draft2020-12/anyOf.json | 24 +++--- .../external/tests/draft2020-12/oneOf.json | 48 +++--------- .../tests/draft4/additionalItems.json | 4 +- .../testdata/external/tests/draft4/allOf.json | 30 ++++++-- .../testdata/external/tests/draft4/anyOf.json | 12 +-- .../testdata/external/tests/draft4/oneOf.json | 48 +++--------- .../tests/draft6/additionalItems.json | 4 +- .../testdata/external/tests/draft6/allOf.json | 30 ++++++-- .../testdata/external/tests/draft6/anyOf.json | 24 +++--- .../testdata/external/tests/draft6/oneOf.json | 48 +++--------- .../tests/draft7/additionalItems.json | 4 +- .../testdata/external/tests/draft7/allOf.json | 30 ++++++-- .../testdata/external/tests/draft7/anyOf.json | 24 +++--- .../testdata/external/tests/draft7/oneOf.json | 48 +++--------- .../testdata/txtar/boolschema.txtar | 3 +- .../testdata/txtar/emptyobjinanyof.txtar | 2 +- .../testdata/txtar/id_in_oneOf.txtar | 6 +- .../jsonschema/testdata/txtar/issue3176.txtar | 4 +- .../jsonschema/testdata/txtar/issue3351.txtar | 74 +++++++++++++++++++ encoding/jsonschema/testdata/txtar/type.txtar | 2 +- .../jsonschema/testdata/txtar/typedis.txtar | 6 +- .../testdata/txtar/typeexcluded.txtar | 6 +- encoding/jsonschema/testdata/txtar/used.txtar | 2 +- 30 files changed, 372 insertions(+), 322 deletions(-) diff --git a/encoding/jsonschema/constraints_combinator.go b/encoding/jsonschema/constraints_combinator.go index 3e042cb04..7932a1c92 100644 --- a/encoding/jsonschema/constraints_combinator.go +++ b/encoding/jsonschema/constraints_combinator.go @@ -15,17 +15,28 @@ package jsonschema import ( + "strconv" + "cuelang.org/go/cue" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/token" ) +// TODO We're invoking the `matchN` builtin in these constaints but what +// if there's a field named "matchN" in scope ? How can we guard against +// that while avoiding the use of __matchN in the usual case? + // Constraint combinators. func constraintAllOf(key string, n cue.Value, s *state) { - var a []ast.Expr var knownTypes cue.Kind - for _, v := range s.listItems("allOf", n, false) { + items := s.listItems("allOf", n, false) + if len(items) == 0 { + s.errf(n, "allOf requires at least one subschema") + return + } + a := make([]ast.Expr, 0, len(items)) + for _, v := range items { x, sub := s.schemaState(v, s.allowedTypes, nil, true) s.allowedTypes &= sub.allowedTypes if sub.hasConstraints() { @@ -44,33 +55,60 @@ func constraintAllOf(key string, n cue.Value, s *state) { // as that's a known-impossible assertion? if len(a) > 0 { s.knownTypes &= knownTypes - s.all.add(n, ast.NewBinExpr(token.AND, a...)) + s.all.add(n, ast.NewCall( + ast.NewIdent("matchN"), + // TODO it would be nice to be able to use a special sentinel "all" value + // here rather than redundantly encoding the length of the list. + &ast.BasicLit{ + Kind: token.INT, + Value: strconv.Itoa(len(items)), + }, + ast.NewList(a...), + )) } } func constraintAnyOf(key string, n cue.Value, s *state) { var types cue.Kind - var a []ast.Expr var knownTypes cue.Kind - for _, v := range s.listItems("anyOf", n, false) { + items := s.listItems("anyOf", n, false) + if len(items) == 0 { + s.errf(n, "anyOf requires at least one subschema") + return + } + a := make([]ast.Expr, 0, len(items)) + for _, v := range items { x, sub := s.schemaState(v, s.allowedTypes, nil, true) types |= sub.allowedTypes knownTypes |= sub.knownTypes a = append(a, x) } s.allowedTypes &= types - if len(a) > 0 { - s.knownTypes &= knownTypes - s.all.add(n, ast.NewBinExpr(token.OR, a...)) - } + s.knownTypes &= knownTypes + s.all.add(n, ast.NewCall( + ast.NewIdent("matchN"), + &ast.UnaryExpr{ + Op: token.GEQ, + X: &ast.BasicLit{ + Kind: token.INT, + Value: "1", + }, + }, + ast.NewList(a...), + )) } func constraintOneOf(key string, n cue.Value, s *state) { var types cue.Kind var knownTypes cue.Kind - var a []ast.Expr hasSome := false - for _, v := range s.listItems("oneOf", n, false) { + items := s.listItems("oneOf", n, false) + if len(items) == 0 { + s.errf(n, "oneOf requires at least one subschema") + return + } + a := make([]ast.Expr, 0, len(items)) + for _, v := range items { x, sub := s.schemaState(v, s.allowedTypes, nil, true) types |= sub.allowedTypes @@ -89,7 +127,14 @@ func constraintOneOf(key string, n cue.Value, s *state) { s.allowedTypes &= types if len(a) > 0 && hasSome { s.knownTypes &= knownTypes - s.all.add(n, ast.NewBinExpr(token.OR, a...)) + s.all.add(n, ast.NewCall( + ast.NewIdent("matchN"), + &ast.BasicLit{ + Kind: token.INT, + Value: "1", + }, + ast.NewList(a...), + )) } // TODO: oneOf({a:x}, {b:y}, ..., not(anyOf({a:x}, {b:y}, ...))), diff --git a/encoding/jsonschema/decode_test.go b/encoding/jsonschema/decode_test.go index 30788ed59..a3111286f 100644 --- a/encoding/jsonschema/decode_test.go +++ b/encoding/jsonschema/decode_test.go @@ -68,6 +68,10 @@ func TestDecode(t *testing.T) { test.Run(t, func(t *cuetxtar.Test) { cfg := &jsonschema.Config{} + if t.HasTag("brokenInV2") && t.M.Name() == "v2" { + t.Skip("skipping because test is broken under the v2 evaluator") + } + if t.HasTag("openapi") { cfg.Root = "#/components/schemas/" cfg.Map = func(p token.Pos, a []string) ([]ast.Label, error) { @@ -119,7 +123,7 @@ func TestDecode(t *testing.T) { // Verify that the generated CUE compiles. schemav := ctx.CompileBytes(b, cue.Filename("generated.cue")) if err := schemav.Err(); err != nil { - t.Fatal(errors.Details(err, nil)) + t.Fatal(errors.Details(err, nil), qt.Commentf("generated code: %q", b)) } testEntries, err := fs.ReadDir(fsys, "test") if err != nil { diff --git a/encoding/jsonschema/testdata/external/tests/draft2019-09/additionalItems.json b/encoding/jsonschema/testdata/external/tests/draft2019-09/additionalItems.json index 7778e0463..23b27d9e2 100644 --- a/encoding/jsonschema/testdata/external/tests/draft2019-09/additionalItems.json +++ b/encoding/jsonschema/testdata/external/tests/draft2019-09/additionalItems.json @@ -230,8 +230,8 @@ ], "valid": true, "skip": { - "v2": "5 errors in empty disjunction:\nconflicting values [1,null] and {...} (mismatched types list and struct):\n generated.cue:2:1\n generated.cue:2:41\n instance.json:1:1\nconflicting values bool and [1,null] (mismatched types bool and list):\n generated.cue:2:8\n instance.json:1:1\nconflicting values null and [1,null] (mismatched types null and list):\n generated.cue:2:1\n instance.json:1:1\nconflicting values number and [1,null] (mismatched types number and list):\n generated.cue:2:15\n instance.json:1:1\nconflicting values string and [1,null] (mismatched types string and list):\n generated.cue:2:24\n instance.json:1:1\n", - "v3": "conflicting values [1,null] and {...} (mismatched types list and struct):\n generated.cue:2:41\n instance.json:1:1\nconflicting values bool and [1,null] (mismatched types bool and list):\n generated.cue:2:8\n instance.json:1:1\nconflicting values null and [1,null] (mismatched types null and list):\n generated.cue:2:1\n instance.json:1:1\nconflicting values number and [1,null] (mismatched types number and list):\n generated.cue:2:15\n instance.json:1:1\nconflicting values string and [1,null] (mismatched types string and list):\n generated.cue:2:24\n instance.json:1:1\nincompatible list lengths (1 and 2):\n instance.json:1:1\n" + "v2": "invalid value [1,null] (does not satisfy matchN(1, [null | bool | number | string | [int] | {}])): 0 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n", + "v3": "invalid value [1,null] (does not satisfy matchN(1, [null | bool | number | string | [int] | {}])): 0 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } } ] diff --git a/encoding/jsonschema/testdata/external/tests/draft2019-09/allOf.json b/encoding/jsonschema/testdata/external/tests/draft2019-09/allOf.json index 963335588..fe4c995b7 100644 --- a/encoding/jsonschema/testdata/external/tests/draft2019-09/allOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft2019-09/allOf.json @@ -40,14 +40,20 @@ "data": { "foo": "baz" }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch first", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "wrong type", @@ -118,7 +124,10 @@ "bar": 2, "baz": null }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch second allOf", @@ -126,14 +135,20 @@ "foo": "quux", "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch both", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } } ] }, @@ -369,7 +384,10 @@ { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, - "valid": false + "valid": false, + "skip": { + "v2": "unexpected success" + } }, { "description": "allOf: true, anyOf: false, oneOf: false", diff --git a/encoding/jsonschema/testdata/external/tests/draft2019-09/anyOf.json b/encoding/jsonschema/testdata/external/tests/draft2019-09/anyOf.json index a3c6b724e..7ff57eb68 100644 --- a/encoding/jsonschema/testdata/external/tests/draft2019-09/anyOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft2019-09/anyOf.json @@ -93,11 +93,17 @@ false ] }, + "skip": { + "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:17\n" + }, "tests": [ { "description": "any value is valid", "data": "foo", - "valid": true + "valid": true, + "skip": { + "v3": "could not compile schema" + } } ] }, @@ -111,8 +117,7 @@ ] }, "skip": { - "v2": "extract error: cannot compile resulting schema: 2 errors in empty disjunction:\nexplicit error (_|_ literal) in source:\n generated.cue:2:1\nexplicit error (_|_ literal) in source:\n generated.cue:2:7\n", - "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:1\nexplicit error (_|_ literal) in source:\n generated.cue:2:7\n" + "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:14\n" }, "tests": [ { @@ -120,7 +125,6 @@ "data": "foo", "valid": false, "skip": { - "v2": "could not compile schema", "v3": "could not compile schema" } } @@ -159,22 +163,14 @@ "data": { "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" - } + "valid": true }, { "description": "second anyOf valid (complex)", "data": { "foo": "baz" }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" - } + "valid": true }, { "description": "both anyOf valid (complex)", diff --git a/encoding/jsonschema/testdata/external/tests/draft2019-09/oneOf.json b/encoding/jsonschema/testdata/external/tests/draft2019-09/oneOf.json index 642adb01a..3ef719697 100644 --- a/encoding/jsonschema/testdata/external/tests/draft2019-09/oneOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft2019-09/oneOf.json @@ -26,11 +26,7 @@ { "description": "both oneOf valid", "data": 3, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid", @@ -67,11 +63,7 @@ { "description": "both oneOf valid", "data": "foo", - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -194,8 +186,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" + "v3": "invalid value {bar:2} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -205,8 +196,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" + "v3": "invalid value {foo:\"baz\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -215,11 +205,7 @@ "foo": "baz", "bar": 2 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid (complex)", @@ -293,11 +279,7 @@ "foo": 1, "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n", - "v3": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n" - } + "valid": true }, { "description": "second valid - valid", @@ -305,11 +287,7 @@ "foo": 1, "baz": 3 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n", - "v3": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n" - } + "valid": true }, { "description": "both valid - invalid", @@ -318,11 +296,7 @@ "bar": 2, "baz": 3 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -358,8 +332,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n", - "v3": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n" + "v3": "invalid value {bar:8} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -369,8 +342,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n", - "v3": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n" + "v3": "invalid value {foo:\"foo\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { diff --git a/encoding/jsonschema/testdata/external/tests/draft2020-12/allOf.json b/encoding/jsonschema/testdata/external/tests/draft2020-12/allOf.json index 78bf421f9..fcdc1ba76 100644 --- a/encoding/jsonschema/testdata/external/tests/draft2020-12/allOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft2020-12/allOf.json @@ -40,14 +40,20 @@ "data": { "foo": "baz" }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch first", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "wrong type", @@ -118,7 +124,10 @@ "bar": 2, "baz": null }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch second allOf", @@ -126,14 +135,20 @@ "foo": "quux", "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch both", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } } ] }, @@ -369,7 +384,10 @@ { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, - "valid": false + "valid": false, + "skip": { + "v2": "unexpected success" + } }, { "description": "allOf: true, anyOf: false, oneOf: false", diff --git a/encoding/jsonschema/testdata/external/tests/draft2020-12/anyOf.json b/encoding/jsonschema/testdata/external/tests/draft2020-12/anyOf.json index d6d22394d..2119f1425 100644 --- a/encoding/jsonschema/testdata/external/tests/draft2020-12/anyOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft2020-12/anyOf.json @@ -93,11 +93,17 @@ false ] }, + "skip": { + "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:17\n" + }, "tests": [ { "description": "any value is valid", "data": "foo", - "valid": true + "valid": true, + "skip": { + "v3": "could not compile schema" + } } ] }, @@ -111,8 +117,7 @@ ] }, "skip": { - "v2": "extract error: cannot compile resulting schema: 2 errors in empty disjunction:\nexplicit error (_|_ literal) in source:\n generated.cue:2:1\nexplicit error (_|_ literal) in source:\n generated.cue:2:7\n", - "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:1\nexplicit error (_|_ literal) in source:\n generated.cue:2:7\n" + "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:14\n" }, "tests": [ { @@ -120,7 +125,6 @@ "data": "foo", "valid": false, "skip": { - "v2": "could not compile schema", "v3": "could not compile schema" } } @@ -159,22 +163,14 @@ "data": { "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" - } + "valid": true }, { "description": "second anyOf valid (complex)", "data": { "foo": "baz" }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" - } + "valid": true }, { "description": "both anyOf valid (complex)", diff --git a/encoding/jsonschema/testdata/external/tests/draft2020-12/oneOf.json b/encoding/jsonschema/testdata/external/tests/draft2020-12/oneOf.json index 9b0d8f5c1..eda13ac38 100644 --- a/encoding/jsonschema/testdata/external/tests/draft2020-12/oneOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft2020-12/oneOf.json @@ -26,11 +26,7 @@ { "description": "both oneOf valid", "data": 3, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid", @@ -67,11 +63,7 @@ { "description": "both oneOf valid", "data": "foo", - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -194,8 +186,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" + "v3": "invalid value {bar:2} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -205,8 +196,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" + "v3": "invalid value {foo:\"baz\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -215,11 +205,7 @@ "foo": "baz", "bar": 2 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid (complex)", @@ -293,11 +279,7 @@ "foo": 1, "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n", - "v3": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n" - } + "valid": true }, { "description": "second valid - valid", @@ -305,11 +287,7 @@ "foo": 1, "baz": 3 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n", - "v3": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n" - } + "valid": true }, { "description": "both valid - invalid", @@ -318,11 +296,7 @@ "bar": 2, "baz": 3 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -358,8 +332,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n", - "v3": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n" + "v3": "invalid value {bar:8} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -369,8 +342,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n", - "v3": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n" + "v3": "invalid value {foo:\"foo\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:1:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { diff --git a/encoding/jsonschema/testdata/external/tests/draft4/additionalItems.json b/encoding/jsonschema/testdata/external/tests/draft4/additionalItems.json index 361d96851..dedd6fbba 100644 --- a/encoding/jsonschema/testdata/external/tests/draft4/additionalItems.json +++ b/encoding/jsonschema/testdata/external/tests/draft4/additionalItems.json @@ -192,8 +192,8 @@ ], "valid": true, "skip": { - "v2": "5 errors in empty disjunction:\nconflicting values [1,null] and {...} (mismatched types list and struct):\n generated.cue:2:1\n generated.cue:2:41\n instance.json:1:1\nconflicting values bool and [1,null] (mismatched types bool and list):\n generated.cue:2:8\n instance.json:1:1\nconflicting values null and [1,null] (mismatched types null and list):\n generated.cue:2:1\n instance.json:1:1\nconflicting values number and [1,null] (mismatched types number and list):\n generated.cue:2:15\n instance.json:1:1\nconflicting values string and [1,null] (mismatched types string and list):\n generated.cue:2:24\n instance.json:1:1\n", - "v3": "conflicting values [1,null] and {...} (mismatched types list and struct):\n generated.cue:2:41\n instance.json:1:1\nconflicting values bool and [1,null] (mismatched types bool and list):\n generated.cue:2:8\n instance.json:1:1\nconflicting values null and [1,null] (mismatched types null and list):\n generated.cue:2:1\n instance.json:1:1\nconflicting values number and [1,null] (mismatched types number and list):\n generated.cue:2:15\n instance.json:1:1\nconflicting values string and [1,null] (mismatched types string and list):\n generated.cue:2:24\n instance.json:1:1\nincompatible list lengths (1 and 2):\n instance.json:1:1\n" + "v2": "invalid value [1,null] (does not satisfy matchN(1, [null | bool | number | string | [int] | {}])): 0 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n", + "v3": "invalid value [1,null] (does not satisfy matchN(1, [null | bool | number | string | [int] | {}])): 0 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } } ] diff --git a/encoding/jsonschema/testdata/external/tests/draft4/allOf.json b/encoding/jsonschema/testdata/external/tests/draft4/allOf.json index 3c65acb8f..4bdeb0a47 100644 --- a/encoding/jsonschema/testdata/external/tests/draft4/allOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft4/allOf.json @@ -39,14 +39,20 @@ "data": { "foo": "baz" }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch first", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "wrong type", @@ -116,7 +122,10 @@ "bar": 2, "baz": null }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch second allOf", @@ -124,14 +133,20 @@ "foo": "quux", "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch both", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } } ] }, @@ -301,7 +316,10 @@ { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, - "valid": false + "valid": false, + "skip": { + "v2": "unexpected success" + } }, { "description": "allOf: true, anyOf: false, oneOf: false", diff --git a/encoding/jsonschema/testdata/external/tests/draft4/anyOf.json b/encoding/jsonschema/testdata/external/tests/draft4/anyOf.json index 39347b1f7..7c157961c 100644 --- a/encoding/jsonschema/testdata/external/tests/draft4/anyOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft4/anyOf.json @@ -97,22 +97,14 @@ "data": { "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" - } + "valid": true }, { "description": "second anyOf valid (complex)", "data": { "foo": "baz" }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" - } + "valid": true }, { "description": "both anyOf valid (complex)", diff --git a/encoding/jsonschema/testdata/external/tests/draft4/oneOf.json b/encoding/jsonschema/testdata/external/tests/draft4/oneOf.json index a337e2aaf..9531b105b 100644 --- a/encoding/jsonschema/testdata/external/tests/draft4/oneOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft4/oneOf.json @@ -25,11 +25,7 @@ { "description": "both oneOf valid", "data": 3, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid", @@ -65,11 +61,7 @@ { "description": "both oneOf valid", "data": "foo", - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -107,8 +99,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" + "v3": "invalid value {bar:2} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -118,8 +109,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" + "v3": "invalid value {foo:\"baz\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -128,11 +118,7 @@ "foo": "baz", "bar": 2 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid (complex)", @@ -204,11 +190,7 @@ "foo": 1, "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n", - "v3": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n" - } + "valid": true }, { "description": "second valid - valid", @@ -216,11 +198,7 @@ "foo": 1, "baz": 3 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n", - "v3": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n" - } + "valid": true }, { "description": "both valid - invalid", @@ -229,11 +207,7 @@ "bar": 2, "baz": 3 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -268,8 +242,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n", - "v3": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n" + "v3": "invalid value {bar:8} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -279,8 +252,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n", - "v3": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n" + "v3": "invalid value {foo:\"foo\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { diff --git a/encoding/jsonschema/testdata/external/tests/draft6/additionalItems.json b/encoding/jsonschema/testdata/external/tests/draft6/additionalItems.json index 3943c2ba5..b6442fbcd 100644 --- a/encoding/jsonschema/testdata/external/tests/draft6/additionalItems.json +++ b/encoding/jsonschema/testdata/external/tests/draft6/additionalItems.json @@ -223,8 +223,8 @@ ], "valid": true, "skip": { - "v2": "5 errors in empty disjunction:\nconflicting values [1,null] and {...} (mismatched types list and struct):\n generated.cue:2:1\n generated.cue:2:41\n instance.json:1:1\nconflicting values bool and [1,null] (mismatched types bool and list):\n generated.cue:2:8\n instance.json:1:1\nconflicting values null and [1,null] (mismatched types null and list):\n generated.cue:2:1\n instance.json:1:1\nconflicting values number and [1,null] (mismatched types number and list):\n generated.cue:2:15\n instance.json:1:1\nconflicting values string and [1,null] (mismatched types string and list):\n generated.cue:2:24\n instance.json:1:1\n", - "v3": "conflicting values [1,null] and {...} (mismatched types list and struct):\n generated.cue:2:41\n instance.json:1:1\nconflicting values bool and [1,null] (mismatched types bool and list):\n generated.cue:2:8\n instance.json:1:1\nconflicting values null and [1,null] (mismatched types null and list):\n generated.cue:2:1\n instance.json:1:1\nconflicting values number and [1,null] (mismatched types number and list):\n generated.cue:2:15\n instance.json:1:1\nconflicting values string and [1,null] (mismatched types string and list):\n generated.cue:2:24\n instance.json:1:1\nincompatible list lengths (1 and 2):\n instance.json:1:1\n" + "v2": "invalid value [1,null] (does not satisfy matchN(1, [null | bool | number | string | [int] | {}])): 0 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n", + "v3": "invalid value [1,null] (does not satisfy matchN(1, [null | bool | number | string | [int] | {}])): 0 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } } ] diff --git a/encoding/jsonschema/testdata/external/tests/draft6/allOf.json b/encoding/jsonschema/testdata/external/tests/draft6/allOf.json index 16c231de0..209a5b98a 100644 --- a/encoding/jsonschema/testdata/external/tests/draft6/allOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft6/allOf.json @@ -39,14 +39,20 @@ "data": { "foo": "baz" }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch first", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "wrong type", @@ -116,7 +122,10 @@ "bar": 2, "baz": null }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch second allOf", @@ -124,14 +133,20 @@ "foo": "quux", "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch both", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } } ] }, @@ -357,7 +372,10 @@ { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, - "valid": false + "valid": false, + "skip": { + "v2": "unexpected success" + } }, { "description": "allOf: true, anyOf: false, oneOf: false", diff --git a/encoding/jsonschema/testdata/external/tests/draft6/anyOf.json b/encoding/jsonschema/testdata/external/tests/draft6/anyOf.json index e64af7e59..3fc55e106 100644 --- a/encoding/jsonschema/testdata/external/tests/draft6/anyOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft6/anyOf.json @@ -89,11 +89,17 @@ false ] }, + "skip": { + "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:17\n" + }, "tests": [ { "description": "any value is valid", "data": "foo", - "valid": true + "valid": true, + "skip": { + "v3": "could not compile schema" + } } ] }, @@ -106,8 +112,7 @@ ] }, "skip": { - "v2": "extract error: cannot compile resulting schema: 2 errors in empty disjunction:\nexplicit error (_|_ literal) in source:\n generated.cue:2:1\nexplicit error (_|_ literal) in source:\n generated.cue:2:7\n", - "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:1\nexplicit error (_|_ literal) in source:\n generated.cue:2:7\n" + "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:14\n" }, "tests": [ { @@ -115,7 +120,6 @@ "data": "foo", "valid": false, "skip": { - "v2": "could not compile schema", "v3": "could not compile schema" } } @@ -153,22 +157,14 @@ "data": { "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" - } + "valid": true }, { "description": "second anyOf valid (complex)", "data": { "foo": "baz" }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" - } + "valid": true }, { "description": "both anyOf valid (complex)", diff --git a/encoding/jsonschema/testdata/external/tests/draft6/oneOf.json b/encoding/jsonschema/testdata/external/tests/draft6/oneOf.json index 9a599a1de..73f96da2a 100644 --- a/encoding/jsonschema/testdata/external/tests/draft6/oneOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft6/oneOf.json @@ -25,11 +25,7 @@ { "description": "both oneOf valid", "data": 3, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid", @@ -65,11 +61,7 @@ { "description": "both oneOf valid", "data": "foo", - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -187,8 +179,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" + "v3": "invalid value {bar:2} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -198,8 +189,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" + "v3": "invalid value {foo:\"baz\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -208,11 +198,7 @@ "foo": "baz", "bar": 2 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid (complex)", @@ -284,11 +270,7 @@ "foo": 1, "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n", - "v3": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n" - } + "valid": true }, { "description": "second valid - valid", @@ -296,11 +278,7 @@ "foo": 1, "baz": 3 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n", - "v3": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n" - } + "valid": true }, { "description": "both valid - invalid", @@ -309,11 +287,7 @@ "bar": 2, "baz": 3 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -348,8 +322,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n", - "v3": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n" + "v3": "invalid value {bar:8} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -359,8 +332,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n", - "v3": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n" + "v3": "invalid value {foo:\"foo\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { diff --git a/encoding/jsonschema/testdata/external/tests/draft7/additionalItems.json b/encoding/jsonschema/testdata/external/tests/draft7/additionalItems.json index 3943c2ba5..b6442fbcd 100644 --- a/encoding/jsonschema/testdata/external/tests/draft7/additionalItems.json +++ b/encoding/jsonschema/testdata/external/tests/draft7/additionalItems.json @@ -223,8 +223,8 @@ ], "valid": true, "skip": { - "v2": "5 errors in empty disjunction:\nconflicting values [1,null] and {...} (mismatched types list and struct):\n generated.cue:2:1\n generated.cue:2:41\n instance.json:1:1\nconflicting values bool and [1,null] (mismatched types bool and list):\n generated.cue:2:8\n instance.json:1:1\nconflicting values null and [1,null] (mismatched types null and list):\n generated.cue:2:1\n instance.json:1:1\nconflicting values number and [1,null] (mismatched types number and list):\n generated.cue:2:15\n instance.json:1:1\nconflicting values string and [1,null] (mismatched types string and list):\n generated.cue:2:24\n instance.json:1:1\n", - "v3": "conflicting values [1,null] and {...} (mismatched types list and struct):\n generated.cue:2:41\n instance.json:1:1\nconflicting values bool and [1,null] (mismatched types bool and list):\n generated.cue:2:8\n instance.json:1:1\nconflicting values null and [1,null] (mismatched types null and list):\n generated.cue:2:1\n instance.json:1:1\nconflicting values number and [1,null] (mismatched types number and list):\n generated.cue:2:15\n instance.json:1:1\nconflicting values string and [1,null] (mismatched types string and list):\n generated.cue:2:24\n instance.json:1:1\nincompatible list lengths (1 and 2):\n instance.json:1:1\n" + "v2": "invalid value [1,null] (does not satisfy matchN(1, [null | bool | number | string | [int] | {}])): 0 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n", + "v3": "invalid value [1,null] (does not satisfy matchN(1, [null | bool | number | string | [int] | {}])): 0 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } } ] diff --git a/encoding/jsonschema/testdata/external/tests/draft7/allOf.json b/encoding/jsonschema/testdata/external/tests/draft7/allOf.json index 16c231de0..209a5b98a 100644 --- a/encoding/jsonschema/testdata/external/tests/draft7/allOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft7/allOf.json @@ -39,14 +39,20 @@ "data": { "foo": "baz" }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch first", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "wrong type", @@ -116,7 +122,10 @@ "bar": 2, "baz": null }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch second allOf", @@ -124,14 +133,20 @@ "foo": "quux", "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } }, { "description": "mismatch both", "data": { "bar": 2 }, - "valid": false + "valid": false, + "skip": { + "v3": "unexpected success" + } } ] }, @@ -357,7 +372,10 @@ { "description": "allOf: false, anyOf: true, oneOf: true", "data": 15, - "valid": false + "valid": false, + "skip": { + "v2": "unexpected success" + } }, { "description": "allOf: true, anyOf: false, oneOf: false", diff --git a/encoding/jsonschema/testdata/external/tests/draft7/anyOf.json b/encoding/jsonschema/testdata/external/tests/draft7/anyOf.json index e64af7e59..3fc55e106 100644 --- a/encoding/jsonschema/testdata/external/tests/draft7/anyOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft7/anyOf.json @@ -89,11 +89,17 @@ false ] }, + "skip": { + "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:17\n" + }, "tests": [ { "description": "any value is valid", "data": "foo", - "valid": true + "valid": true, + "skip": { + "v3": "could not compile schema" + } } ] }, @@ -106,8 +112,7 @@ ] }, "skip": { - "v2": "extract error: cannot compile resulting schema: 2 errors in empty disjunction:\nexplicit error (_|_ literal) in source:\n generated.cue:2:1\nexplicit error (_|_ literal) in source:\n generated.cue:2:7\n", - "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:1\nexplicit error (_|_ literal) in source:\n generated.cue:2:7\n" + "v3": "extract error: cannot compile resulting schema: explicit error (_|_ literal) in source:\n generated.cue:2:14\n" }, "tests": [ { @@ -115,7 +120,6 @@ "data": "foo", "valid": false, "skip": { - "v2": "could not compile schema", "v3": "could not compile schema" } } @@ -153,22 +157,14 @@ "data": { "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" - } + "valid": true }, { "description": "second anyOf valid (complex)", "data": { "foo": "baz" }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" - } + "valid": true }, { "description": "both anyOf valid (complex)", diff --git a/encoding/jsonschema/testdata/external/tests/draft7/oneOf.json b/encoding/jsonschema/testdata/external/tests/draft7/oneOf.json index 9a599a1de..73f96da2a 100644 --- a/encoding/jsonschema/testdata/external/tests/draft7/oneOf.json +++ b/encoding/jsonschema/testdata/external/tests/draft7/oneOf.json @@ -25,11 +25,7 @@ { "description": "both oneOf valid", "data": 3, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid", @@ -65,11 +61,7 @@ { "description": "both oneOf valid", "data": "foo", - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -187,8 +179,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:2} | {bar:2,foo!:string}\n", - "v3": "incomplete value {bar:2} | {bar:2,foo!:string}\n" + "v3": "invalid value {bar:2} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -198,8 +189,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n", - "v3": "incomplete value {foo:\"baz\",bar!:int} | {foo:\"baz\"}\n" + "v3": "invalid value {foo:\"baz\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:int},null | bool | number | string | [] | {foo!:string}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -208,11 +198,7 @@ "foo": "baz", "bar": 2 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false }, { "description": "neither oneOf valid (complex)", @@ -284,11 +270,7 @@ "foo": 1, "bar": 2 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n", - "v3": "incomplete value {foo:1,bar:2} | {foo:1,bar:2,baz!:_}\n" - } + "valid": true }, { "description": "second valid - valid", @@ -296,11 +278,7 @@ "foo": 1, "baz": 3 }, - "valid": true, - "skip": { - "v2": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n", - "v3": "incomplete value {foo:1,baz:3,bar!:_} | {foo:1,baz:3}\n" - } + "valid": true }, { "description": "both valid - invalid", @@ -309,11 +287,7 @@ "bar": 2, "baz": 3 }, - "valid": false, - "skip": { - "v2": "unexpected success", - "v3": "unexpected success" - } + "valid": false } ] }, @@ -348,8 +322,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n", - "v3": "incomplete value {bar:8,baz?:_} | {bar:8,foo!:_}\n" + "v3": "invalid value {bar:8} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { @@ -359,8 +332,7 @@ }, "valid": true, "skip": { - "v2": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n", - "v3": "incomplete value {foo:\"foo\",bar!:_,baz?:_} | {foo:\"foo\"}\n" + "v3": "invalid value {foo:\"foo\"} (does not satisfy matchN(1, [null | bool | number | string | [] | {bar!:_,baz?:_},null | bool | number | string | [] | {foo!:_}])): 2 matched, expected 1:\n generated.cue:2:1\n generated.cue:2:8\n instance.json:1:1\n" } }, { diff --git a/encoding/jsonschema/testdata/txtar/boolschema.txtar b/encoding/jsonschema/testdata/txtar/boolschema.txtar index 6deb8daa9..1b48028bb 100644 --- a/encoding/jsonschema/testdata/txtar/boolschema.txtar +++ b/encoding/jsonschema/testdata/txtar/boolschema.txtar @@ -1,3 +1,4 @@ +#noverify -- schema.json -- { "anyOf": [ @@ -7,4 +8,4 @@ } -- out/decode/extract -- -_ | _|_ +matchN(>=1, [_, _|_]) diff --git a/encoding/jsonschema/testdata/txtar/emptyobjinanyof.txtar b/encoding/jsonschema/testdata/txtar/emptyobjinanyof.txtar index fb566f4e9..0290c9454 100644 --- a/encoding/jsonschema/testdata/txtar/emptyobjinanyof.txtar +++ b/encoding/jsonschema/testdata/txtar/emptyobjinanyof.txtar @@ -23,4 +23,4 @@ -- out/decode/extract -- _ -#shell: string | ("bash" | "sh" | "cmd" | "powershell") +#shell: matchN(>=1, [string, "bash" | "sh" | "cmd" | "powershell"]) diff --git a/encoding/jsonschema/testdata/txtar/id_in_oneOf.txtar b/encoding/jsonschema/testdata/txtar/id_in_oneOf.txtar index e9be88abf..5a2848adb 100644 --- a/encoding/jsonschema/testdata/txtar/id_in_oneOf.txtar +++ b/encoding/jsonschema/testdata/txtar/id_in_oneOf.txtar @@ -19,10 +19,10 @@ -- out/decode/extract -- @jsonschema(schema="http://json-schema.org/draft-07/schema#") @jsonschema(id="https://test.example/foo") -{ +matchN(1, [{ @jsonschema(id="https://1.test.example/string") string -} | { +}, { @jsonschema(id="https://2.test.example/object") ... -} +}]) diff --git a/encoding/jsonschema/testdata/txtar/issue3176.txtar b/encoding/jsonschema/testdata/txtar/issue3176.txtar index b9d8348c9..232755e0b 100644 --- a/encoding/jsonschema/testdata/txtar/issue3176.txtar +++ b/encoding/jsonschema/testdata/txtar/issue3176.txtar @@ -18,9 +18,9 @@ -- out/decode/extract -- import "strings" -({ +matchN(1, [{ ... -} | strings.MaxRunes(3)) & (string | { +}, strings.MaxRunes(3)]) & (string | { {[=~"^x-" & !~"^()$"]: string} ... }) diff --git a/encoding/jsonschema/testdata/txtar/issue3351.txtar b/encoding/jsonschema/testdata/txtar/issue3351.txtar index 73b3e9c79..b3ef07873 100644 --- a/encoding/jsonschema/testdata/txtar/issue3351.txtar +++ b/encoding/jsonschema/testdata/txtar/issue3351.txtar @@ -1,3 +1,5 @@ +#noverify +#brokenInV2 -- schema.json -- { "$schema": "https://json-schema.org/draft/2019-09/schema", @@ -62,6 +64,78 @@ "title": "JSON-e templates", "type": "object" } +-- out/decode-v3/extract -- +_schema +_schema: { + // JSON-e templates + @jsonschema(schema="https://json-schema.org/draft/2019-09/schema") + @jsonschema(id="https://www.sourcemeta.com/schemas/vendor/json-e@1.json") + $else?: #["jsone-value"] + $let?: [string]: null | bool | number | string | [...] | { + [string]: _schema + } + $sort?: matchN(>=1, [_schema, [...number]]) + {[!~"^($else|$let|$sort)$"]: #["jsone-value"]} + + #: "jsone-value": matchN(1, [_schema, [..._schema]]) + + #: "jsone-array": [...#["jsone-value"]] + + #: "jsone-object-array": [..._schema] +} +-- diff/-out/decode-v3/extract<==>+out/decode/extract -- +diff old new +--- old ++++ new +@@ -7,10 +7,10 @@ + $let?: [string]: null | bool | number | string | [...] | { + [string]: _schema + } +- $sort?: _schema | [...number] ++ $sort?: matchN(>=1, [_schema, [...number]]) + {[!~"^($else|$let|$sort)$"]: #["jsone-value"]} + +- #: "jsone-value": _schema | [..._schema] ++ #: "jsone-value": matchN(1, [_schema, [..._schema]]) + + #: "jsone-array": [...#["jsone-value"]] + +-- out/decode-v3-noshare/extract -- +_schema +_schema: { + // JSON-e templates + @jsonschema(schema="https://json-schema.org/draft/2019-09/schema") + @jsonschema(id="https://www.sourcemeta.com/schemas/vendor/json-e@1.json") + $else?: #["jsone-value"] + $let?: [string]: null | bool | number | string | [...] | { + [string]: _schema + } + $sort?: matchN(>=1, [_schema, [...number]]) + {[!~"^($else|$let|$sort)$"]: #["jsone-value"]} + + #: "jsone-value": matchN(1, [_schema, [..._schema]]) + + #: "jsone-array": [...#["jsone-value"]] + + #: "jsone-object-array": [..._schema] +} +-- diff/-out/decode-v3-noshare/extract<==>+out/decode/extract -- +diff old new +--- old ++++ new +@@ -7,10 +7,10 @@ + $let?: [string]: null | bool | number | string | [...] | { + [string]: _schema + } +- $sort?: _schema | [...number] ++ $sort?: matchN(>=1, [_schema, [...number]]) + {[!~"^($else|$let|$sort)$"]: #["jsone-value"]} + +- #: "jsone-value": _schema | [..._schema] ++ #: "jsone-value": matchN(1, [_schema, [..._schema]]) + + #: "jsone-array": [...#["jsone-value"]] + -- out/decode/extract -- _schema _schema: { diff --git a/encoding/jsonschema/testdata/txtar/type.txtar b/encoding/jsonschema/testdata/txtar/type.txtar index d9384c4ea..491ab7c0e 100644 --- a/encoding/jsonschema/testdata/txtar/type.txtar +++ b/encoding/jsonschema/testdata/txtar/type.txtar @@ -39,4 +39,4 @@ object?: { baz: 1.3 ... } -numOrList?: number | [...number] | *[1, 2, 3] +numOrList?: matchN(1, [number, [...number]]) | *[1, 2, 3] diff --git a/encoding/jsonschema/testdata/txtar/typedis.txtar b/encoding/jsonschema/testdata/txtar/typedis.txtar index b276f08c4..82d328f77 100644 --- a/encoding/jsonschema/testdata/txtar/typedis.txtar +++ b/encoding/jsonschema/testdata/txtar/typedis.txtar @@ -39,7 +39,7 @@ -- out/decode/extract -- // Main schema intOrString1?: int | string -intOrString2?: int | string -intOrString3?: int | string -disjunction?: int | string | int & >=3 +intOrString2?: matchN(1, [int, string]) +intOrString3?: matchN(>=1, [int, string]) +disjunction?: matchN(1, [matchN(>=1, [int, string]), int & >=3]) ... diff --git a/encoding/jsonschema/testdata/txtar/typeexcluded.txtar b/encoding/jsonschema/testdata/txtar/typeexcluded.txtar index a2092b05d..ffbcea419 100644 --- a/encoding/jsonschema/testdata/txtar/typeexcluded.txtar +++ b/encoding/jsonschema/testdata/txtar/typeexcluded.txtar @@ -120,11 +120,11 @@ e3?: list.UniqueItems() & [_, ...] & [...strings.MinRunes(1)] e4?: [...string] e5?: int & >=0 e6?: [...=~"^[A-Za-z0-9 _.-]+$"] -e7?: true | { +e7?: matchN(>=1, [true, matchN(1, [{ disableFix?: bool ... -} & { +}]) & { ignoreMediaFeatureNames?: list.UniqueItems() & [_, ...] & [...string] ... -} +}]) ... diff --git a/encoding/jsonschema/testdata/txtar/used.txtar b/encoding/jsonschema/testdata/txtar/used.txtar index 6ddc5e229..69554ec14 100644 --- a/encoding/jsonschema/testdata/txtar/used.txtar +++ b/encoding/jsonschema/testdata/txtar/used.txtar @@ -45,4 +45,4 @@ _ #enum: "a" | "b" | "c" -#lists: "a" | "b" | "c" | (["X"] | ["X", "a" | "b" | "c"] | ["X", "d" | "e" | "f"]) +#lists: matchN(1, ["a" | "b" | "c", matchN(1, [["X"], ["X", "a" | "b" | "c"], ["X", "d" | "e" | "f"]])])