Skip to content

Commit

Permalink
encoding/jsonschema: close structs and mark fields as required in enu…
Browse files Browse the repository at this point in the history
…m and const

The validation of the keywords `enum` and `const` should succeed only
when the values of structs are exactly the same.

This closes structs and marks the fields as required.

Fixes #3561

Change-Id: Ib27dc1edd52e13ef1d4153bec3ccfd0af6e7808b
Signed-off-by: haoqixu <[email protected]>
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1204477
Reviewed-by: Roger Peppe <[email protected]>
Unity-Result: CUE porcuepine <[email protected]>
TryBot-Result: CUEcueckoo <[email protected]>
  • Loading branch information
haoqixu authored and rogpeppe committed Nov 25, 2024
1 parent 407cccd commit 0ad2119
Show file tree
Hide file tree
Showing 19 changed files with 64 additions and 74 deletions.
4 changes: 2 additions & 2 deletions encoding/jsonschema/constraints_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func constraintComment(key string, n cue.Value, s *state) {
}

func constraintConst(key string, n cue.Value, s *state) {
s.all.add(n, s.value(n))
s.all.add(n, s.constValue(n))
s.allowedTypes &= n.Kind()
s.knownTypes &= n.Kind()
}
Expand Down Expand Up @@ -93,7 +93,7 @@ func constraintEnum(key string, n cue.Value, s *state) {
// not in the allowed type set.
continue
}
a = append(a, s.value(x))
a = append(a, s.constValue(x))
types |= x.Kind()
}
s.knownTypes &= types
Expand Down
28 changes: 28 additions & 0 deletions encoding/jsonschema/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,34 @@ func (s0 *state) schemaState(n cue.Value, types cue.Kind, idRef []label) (ast.Ex
return s.finalize(), s
}

func (s *state) constValue(n cue.Value) ast.Expr {
k := n.Kind()
switch k {
case cue.ListKind:
a := []ast.Expr{}
for i, _ := n.List(); i.Next(); {
a = append(a, s.constValue(i.Value()))
}
return setPos(ast.NewList(a...), n)

case cue.StructKind:
a := []ast.Decl{}
s.processMap(n, func(key string, n cue.Value) {
a = append(a, &ast.Field{
Label: ast.NewString(key),
Value: s.constValue(n),
Constraint: token.NOT,
})
})
return setPos(ast.NewCall(ast.NewIdent("close"), &ast.StructLit{Elts: a}), n)
default:
if !n.IsConcrete() {
s.errf(n, "invalid non-concrete value")
}
return n.Syntax(cue.Final()).(ast.Expr)
}
}

func (s *state) value(n cue.Value) ast.Expr {
k := n.Kind()
switch k {
Expand Down
8 changes: 4 additions & 4 deletions encoding/jsonschema/external_teststats.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Generated by CUE_UPDATE=1 go test. DO NOT EDIT
v2:
schema extract (pass / total): 1013 / 1363 = 74.3%
tests (pass / total): 3646 / 4803 = 75.9%
tests on extracted schemas (pass / total): 3646 / 3865 = 94.3%
tests (pass / total): 3659 / 4803 = 76.2%
tests on extracted schemas (pass / total): 3659 / 3865 = 94.7%

v3:
schema extract (pass / total): 1013 / 1363 = 74.3%
tests (pass / total): 3636 / 4803 = 75.7%
tests on extracted schemas (pass / total): 3636 / 3865 = 94.1%
tests (pass / total): 3649 / 4803 = 76.0%
tests on extracted schemas (pass / total): 3649 / 3865 = 94.4%

Optional tests

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,7 @@
"data": {
"foo": "bar"
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
},
{
"description": "another type is invalid",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@
"foo": 12,
"boo": 42
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -665,11 +665,7 @@
"data": {
"type": "string"
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
},
{
"description": "match the enum exactly",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,7 @@
"data": {
"foo": "bar"
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
},
{
"description": "another type is invalid",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@
"foo": 12,
"boo": 42
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -665,11 +665,7 @@
"data": {
"type": "string"
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
},
{
"description": "match the enum exactly",
Expand Down
6 changes: 1 addition & 5 deletions encoding/jsonschema/testdata/external/tests/draft4/enum.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@
"foo": 12,
"boo": 42
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@
"data": {
"foo": "bar"
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
},
{
"description": "another type is invalid",
Expand Down
6 changes: 1 addition & 5 deletions encoding/jsonschema/testdata/external/tests/draft6/enum.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@
"foo": 12,
"boo": 42
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
}
]
},
Expand Down
6 changes: 1 addition & 5 deletions encoding/jsonschema/testdata/external/tests/draft6/ref.json
Original file line number Diff line number Diff line change
Expand Up @@ -804,11 +804,7 @@
"data": {
"type": "string"
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
},
{
"description": "match the enum exactly",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@
"data": {
"foo": "bar"
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
},
{
"description": "another type is invalid",
Expand Down
6 changes: 1 addition & 5 deletions encoding/jsonschema/testdata/external/tests/draft7/enum.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@
"foo": 12,
"boo": 42
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
}
]
},
Expand Down
6 changes: 1 addition & 5 deletions encoding/jsonschema/testdata/external/tests/draft7/ref.json
Original file line number Diff line number Diff line change
Expand Up @@ -804,11 +804,7 @@
"data": {
"type": "string"
},
"valid": false,
"skip": {
"v2": "unexpected success",
"v3": "unexpected success"
}
"valid": false
},
{
"description": "match the enum exactly",
Expand Down
4 changes: 3 additions & 1 deletion encoding/jsonschema/testdata/txtar/constobj.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
}

-- out/decode/extract --
a: 1
close({
a!: 1
})
14 changes: 14 additions & 0 deletions encoding/jsonschema/testdata/txtar/enumobj.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- schema.json --
{
"type": "object",
"enum": [{ "a": 1, "b": [1, 2, 3], "c": { "d": 1 } }]
}

-- out/decode/extract --
close({
a!: 1
b!: [1, 2, 3]
c!: close({
d!: 1
})
})
2 changes: 0 additions & 2 deletions encoding/jsonschema/testdata/txtar/numericenum.txtar
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Test that we can use a "number" type constraint with a numeric enum.
# See issue #3173.

# TODO fix this so it works.

-- schema.json --
{
"type": "number",
Expand Down

0 comments on commit 0ad2119

Please sign in to comment.