diff options
author | Julian Berman <Julian@GrayVines.com> | 2021-04-12 21:09:51 -0400 |
---|---|---|
committer | Julian Berman <Julian@GrayVines.com> | 2021-04-12 21:09:51 -0400 |
commit | 61d6022ad9cceb91eb634d01eecfc15358b1d8a1 (patch) | |
tree | 1d88ab4660f2a28ae9e98c7b9538d58d85816ed3 /tests/draft2019-09 | |
parent | 037b4438fc54e52584cf8fb5e469cf3413751a1f (diff) | |
download | jsonschema-61d6022ad9cceb91eb634d01eecfc15358b1d8a1.tar.gz |
Squashed 'json/' changes from 3627cc1..15ec577
15ec577 Merge pull request #471 from json-schema-org/ether/id-anchor-in-enum
9f97865 test for confusing not-identifiers in enums
0f7ecd4 Merge pull request #475 from marksparkza/marksparkza-patch-1
783d22a Add jschon
fc68499 Merge pull request #472 from json-schema-org/ether/unevaluatedProperties_uncles
ed4cf5f more test cases for unevaluatedItems, unevaluatedProperties
d0d814d Merge pull request #469 from json-schema-org/ether/ipv4-vulnerability
7ca5f36 reject ipv4 strings with an octet with a leading zero
8e1e1c1 fix spelling error in test descriptions
77f1d10 Merge pull request #462 from jdesrosiers/dynamic-ref-tests
72a32fe Merge pull request #468 from json-schema-org/ether/combine-test-cases
0c48ffb Merge pull request #453 from notEthan/float-overflow-d4-int
76a4ba0 these test cases can be combined since the schemas are the same
cd73775 Merge pull request #464 from json-schema-org/ether/format-by-default-always-validates
043dc63 by default, "format" only annotates, not validates
3c45b81 Merge pull request #460 from amosonn/remove-remotes-from-script
b09e48d Fix $ref with siblings in pre-2019-09 tests
ff9f22e Add tests for $dynamicRef/$dynamicAnchor
0faaf09 Fix refs to Draft 2019-09 schema to be refs to 2020-12
ebbcbc8 Use flask to server remotes directly
bb98b03 Remove remotes from bin/jsonschema_suite
fcae732 Merge pull request #455 from jdesrosiers/bootstrap-202012
e002409 Update tests for 2020-12
405b3fb Copy 2019-09 tests to bootstrap 2020-12 tests
1636a22 draft4 float-overflow instance may be considered not an integer
8daea3f Merge pull request #451 from json-schema-org/ether/more-relative-json-pointer
69fe40f some more relative-json-pointer tests
6505944 Merge pull request #450 from json-schema-org/ether/recursiveRef-dynamic-path
afd0cd3 Move content* keyword tests to non-optional
e2b2a4b Change all content* keyword tests to always validate
8999eae $recursiveRef example demonstrating dynamic nature of the resolution scope
f47003f fix duplicate test description
bcf1dc8 Merge pull request #391 from ether/recursiveRef (rebased, squashed)
3d88f34 test $recursiveRef + $recursiveAnchor
3b79a45 Merge pull request #418 from ChALkeR/chalker/contentSchema
29f609b Add tests for contentSchema
git-subtree-dir: json
git-subtree-split: 15ec577f5ddee0115319f4e7f856cd57567a9c78
Diffstat (limited to 'tests/draft2019-09')
-rw-r--r-- | tests/draft2019-09/anchor.json | 57 | ||||
-rw-r--r-- | tests/draft2019-09/content.json | 127 | ||||
-rw-r--r-- | tests/draft2019-09/defs.json | 10 | ||||
-rw-r--r-- | tests/draft2019-09/format.json | 95 | ||||
-rw-r--r-- | tests/draft2019-09/id.json | 50 | ||||
-rw-r--r-- | tests/draft2019-09/optional/content.json | 77 | ||||
-rw-r--r-- | tests/draft2019-09/optional/format/ipv4.json | 11 | ||||
-rw-r--r-- | tests/draft2019-09/optional/format/iri.json | 2 | ||||
-rw-r--r-- | tests/draft2019-09/optional/format/relative-json-pointer.json | 15 | ||||
-rw-r--r-- | tests/draft2019-09/optional/format/uri.json | 2 | ||||
-rw-r--r-- | tests/draft2019-09/recursiveRef.json | 356 | ||||
-rw-r--r-- | tests/draft2019-09/unevaluatedItems.json | 52 | ||||
-rw-r--r-- | tests/draft2019-09/unevaluatedProperties.json | 142 |
13 files changed, 909 insertions, 87 deletions
diff --git a/tests/draft2019-09/anchor.json b/tests/draft2019-09/anchor.json index 42dde7e..045cdc3 100644 --- a/tests/draft2019-09/anchor.json +++ b/tests/draft2019-09/anchor.json @@ -77,5 +77,62 @@ "valid": false } ] + }, + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] } ] diff --git a/tests/draft2019-09/content.json b/tests/draft2019-09/content.json new file mode 100644 index 0000000..44688e8 --- /dev/null +++ b/tests/draft2019-09/content.json @@ -0,0 +1,127 @@ +[ + { + "description": "validation of string-encoded content based on media type", + "schema": { + "contentMediaType": "application/json" + }, + "tests": [ + { + "description": "a valid JSON document", + "data": "{\"foo\": \"bar\"}", + "valid": true + }, + { + "description": "an invalid JSON document; validates true", + "data": "{:}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary string-encoding", + "schema": { + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64 string", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "an invalid base64 string (% is not a valid character); validates true", + "data": "eyJmb28iOi%iYmFyIn0K", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents with schema", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64", + "contentSchema": { "required": ["foo"], "properties": { "foo": { "type": "string" } } } + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "another valid base64-encoded JSON document", + "data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==", + "valid": true + }, + { + "description": "an invalid base64-encoded JSON document; validates true", + "data": "eyJib28iOiAyMH0=", + "valid": true + }, + { + "description": "an empty object as a base64-encoded JSON document; validates true", + "data": "e30=", + "valid": true + }, + { + "description": "an empty array as a base64-encoded JSON document", + "data": "W10=", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + } +] diff --git a/tests/draft2019-09/defs.json b/tests/draft2019-09/defs.json index f2fbec4..70e9dc0 100644 --- a/tests/draft2019-09/defs.json +++ b/tests/draft2019-09/defs.json @@ -1,19 +1,13 @@ [ { - "description": "valid definition", + "description": "validate definition against metaschema", "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, "tests": [ { "description": "valid definition schema", "data": {"$defs": {"foo": {"type": "integer"}}}, "valid": true - } - ] - }, - { - "description": "invalid definition", - "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, - "tests": [ + }, { "description": "invalid definition schema", "data": {"$defs": {"foo": {"type": 1}}}, diff --git a/tests/draft2019-09/format.json b/tests/draft2019-09/format.json index dddea86..0eb5048 100644 --- a/tests/draft2019-09/format.json +++ b/tests/draft2019-09/format.json @@ -32,6 +32,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid email string is only an annotation by default", + "data": "2962", + "valid": true } ] }, @@ -68,6 +73,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid idn-email string is only an annotation by default", + "data": "2962", + "valid": true } ] }, @@ -104,6 +114,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid regex string is only an annotation by default", + "data": "^(abc]", + "valid": true } ] }, @@ -140,6 +155,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid ipv4 string is only an annotation by default", + "data": "127.0.0.0.1", + "valid": true } ] }, @@ -176,6 +196,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid ipv6 string is only an annotation by default", + "data": "12345::", + "valid": true } ] }, @@ -212,6 +237,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid idn-hostname string is only an annotation by default", + "data": "〮실례.테스트", + "valid": true } ] }, @@ -248,6 +278,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid hostname string is only an annotation by default", + "data": "-a-host-name-that-starts-with--", + "valid": true } ] }, @@ -284,6 +319,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid date string is only an annotation by default", + "data": "06/19/1963", + "valid": true } ] }, @@ -320,6 +360,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid date-time string is only an annotation by default", + "data": "1990-02-31T15:59:60.123-08:00", + "valid": true } ] }, @@ -356,6 +401,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid time string is only an annotation by default", + "data": "08:30:06 PST", + "valid": true } ] }, @@ -392,6 +442,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid json-pointer string is only an annotation by default", + "data": "/foo/bar~", + "valid": true } ] }, @@ -428,6 +483,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid relative-json-pointer string is only an annotation by default", + "data": "/foo/bar", + "valid": true } ] }, @@ -464,6 +524,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid iri string is only an annotation by default", + "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "valid": true } ] }, @@ -500,6 +565,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid iri-reference string is only an annotation by default", + "data": "\\\\WINDOWS\\filëßåré", + "valid": true } ] }, @@ -536,6 +606,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid uri string is only an annotation by default", + "data": "//foo.bar/?baz=qux#quux", + "valid": true } ] }, @@ -572,6 +647,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid uri-reference string is only an annotation by default", + "data": "\\\\WINDOWS\\fileshare", + "valid": true } ] }, @@ -608,6 +688,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid uri-template string is only an annotation by default", + "data": "http://example.com/dictionary/{term:1}/{term", + "valid": true } ] }, @@ -644,6 +729,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid uuid string is only an annotation by default", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", + "valid": true } ] }, @@ -680,6 +770,11 @@ "description": "ignores null", "data": null, "valid": true + }, + { + "description": "invalid duration string is only an annotation by default", + "data": "PT1D", + "valid": true } ] } diff --git a/tests/draft2019-09/id.json b/tests/draft2019-09/id.json index cd97d59..1fd3417 100644 --- a/tests/draft2019-09/id.json +++ b/tests/draft2019-09/id.json @@ -202,5 +202,55 @@ "valid": true } ] + }, + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] } ] diff --git a/tests/draft2019-09/optional/content.json b/tests/draft2019-09/optional/content.json deleted file mode 100644 index 3f5a743..0000000 --- a/tests/draft2019-09/optional/content.json +++ /dev/null @@ -1,77 +0,0 @@ -[ - { - "description": "validation of string-encoded content based on media type", - "schema": { - "contentMediaType": "application/json" - }, - "tests": [ - { - "description": "a valid JSON document", - "data": "{\"foo\": \"bar\"}", - "valid": true - }, - { - "description": "an invalid JSON document", - "data": "{:}", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - }, - { - "description": "validation of binary string-encoding", - "schema": { - "contentEncoding": "base64" - }, - "tests": [ - { - "description": "a valid base64 string", - "data": "eyJmb28iOiAiYmFyIn0K", - "valid": true - }, - { - "description": "an invalid base64 string (% is not a valid character)", - "data": "eyJmb28iOi%iYmFyIn0K", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - }, - { - "description": "validation of binary-encoded media type documents", - "schema": { - "contentMediaType": "application/json", - "contentEncoding": "base64" - }, - "tests": [ - { - "description": "a valid base64-encoded JSON document", - "data": "eyJmb28iOiAiYmFyIn0K", - "valid": true - }, - { - "description": "a validly-encoded invalid JSON document", - "data": "ezp9Cg==", - "valid": false - }, - { - "description": "an invalid base64 string that is valid JSON", - "data": "{}", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - } -] diff --git a/tests/draft2019-09/optional/format/ipv4.json b/tests/draft2019-09/optional/format/ipv4.json index 8b99b9f..e36a381 100644 --- a/tests/draft2019-09/optional/format/ipv4.json +++ b/tests/draft2019-09/optional/format/ipv4.json @@ -32,6 +32,17 @@ "description": "an IP address as an integer (decimal)", "data": "2130706433", "valid": false + }, + { + "description": "leading zeroes should be rejected, as they are treated as octals", + "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", + "data": "087.10.0.1", + "valid": false + }, + { + "description": "value without leading zero is valid", + "data": "87.10.0.1", + "valid": true } ] } diff --git a/tests/draft2019-09/optional/format/iri.json b/tests/draft2019-09/optional/format/iri.json index ed54094..1414f2e 100644 --- a/tests/draft2019-09/optional/format/iri.json +++ b/tests/draft2019-09/optional/format/iri.json @@ -9,7 +9,7 @@ "valid": true }, { - "description": "a valid IRI with anchor tag and parantheses", + "description": "a valid IRI with anchor tag and parentheses", "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", "valid": true }, diff --git a/tests/draft2019-09/optional/format/relative-json-pointer.json b/tests/draft2019-09/optional/format/relative-json-pointer.json index 17816c9..22fb14e 100644 --- a/tests/draft2019-09/optional/format/relative-json-pointer.json +++ b/tests/draft2019-09/optional/format/relative-json-pointer.json @@ -32,6 +32,21 @@ "description": "negative prefix", "data": "-1/foo/bar", "valid": false + }, + { + "description": "## is not a valid json-pointer", + "data": "0##", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus json-pointer", + "data": "01/a", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus octothorpe", + "data": "01#", + "valid": false } ] } diff --git a/tests/draft2019-09/optional/format/uri.json b/tests/draft2019-09/optional/format/uri.json index 4306a68..58d3085 100644 --- a/tests/draft2019-09/optional/format/uri.json +++ b/tests/draft2019-09/optional/format/uri.json @@ -9,7 +9,7 @@ "valid": true }, { - "description": "a valid URL with anchor tag and parantheses", + "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, diff --git a/tests/draft2019-09/recursiveRef.json b/tests/draft2019-09/recursiveRef.json new file mode 100644 index 0000000..1a221ec --- /dev/null +++ b/tests/draft2019-09/recursiveRef.json @@ -0,0 +1,356 @@ +[ + { + "description": "$recursiveRef without $recursiveAnchor works like $ref", + "schema": { + "properties": { + "foo": { "$recursiveRef": "#" } + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": { "foo": { "foo": false } }, + "valid": true + }, + { + "description": "mismatch", + "data": { "bar": false }, + "valid": false + }, + { + "description": "recursive mismatch", + "data": { "foo": { "bar": false } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef without using nesting", + "schema": { + "$id": "http://localhost:4242/recursiveRef2/schema.json", + "$defs": { + "myobject": { + "$id": "myobject.json", + "$recursiveAnchor": true, + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" } + } + ] + } + }, + "anyOf": [ + { "type": "integer" }, + { "$ref": "#/$defs/myobject" } + ] + }, + "tests": [ + { + "description": "integer matches at the outer level", + "data": 1, + "valid": true + }, + { + "description": "single level match", + "data": { "foo": "hi" }, + "valid": true + }, + { + "description": "integer does not match as a property value", + "data": { "foo": 1 }, + "valid": false + }, + { + "description": "two levels, properties match with inner definition", + "data": { "foo": { "bar": "hi" } }, + "valid": true + }, + { + "description": "two levels, no match", + "data": { "foo": { "bar": 1 } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef with nesting", + "schema": { + "$id": "http://localhost:4242/recursiveRef3/schema.json", + "$recursiveAnchor": true, + "$defs": { + "myobject": { + "$id": "myobject.json", + "$recursiveAnchor": true, + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" } + } + ] + } + }, + "anyOf": [ + { "type": "integer" }, + { "$ref": "#/$defs/myobject" } + ] + }, + "tests": [ + { + "description": "integer matches at the outer level", + "data": 1, + "valid": true + }, + { + "description": "single level match", + "data": { "foo": "hi" }, + "valid": true + }, + { + "description": "integer now matches as a property value", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "two levels, properties match with inner definition", + "data": { "foo": { "bar": "hi" } }, + "valid": true + }, + { + "description": "two levels, properties match with $recursiveRef", + "data": { "foo": { "bar": 1 } }, + "valid": true + } + ] + }, + { + "description": "$recursiveRef with $recursiveAnchor: false works like $ref", + "schema": { + "$id": "http://localhost:4242/recursiveRef4/schema.json", + "$recursiveAnchor": false, + "$defs": { + "myobject": { + "$id": "myobject.json", + "$recursiveAnchor": false, + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" } + } + ] + } + }, + "anyOf": [ + { "type": "integer" }, + { "$ref": "#/$defs/myobject" } + ] + }, + "tests": [ + { + "description": "integer matches at the outer level", + "data": 1, + "valid": true + }, + { + "description": "single level match", + "data": { "foo": "hi" }, + "valid": true + }, + { + "description": "integer does not match as a property value", + "data": { "foo": 1 }, + "valid": false + }, + { + "description": "two levels, properties match with inner definition", + "data": { "foo": { "bar": "hi" } }, + "valid": true + }, + { + "description": "two levels, integer does not match as a property value", + "data": { "foo": { "bar": 1 } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef with no $recursiveAnchor works like $ref", + "schema": { + "$id": "http://localhost:4242/recursiveRef5/schema.json", + "$defs": { + "myobject": { + "$id": "myobject.json", + "$recursiveAnchor": false, + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" } + } + ] + } + }, + "anyOf": [ + { "type": "integer" }, + { "$ref": "#/$defs/myobject" } + ] + }, + "tests": [ + { + "description": "integer matches at the outer level", + "data": 1, + "valid": true + }, + { + "description": "single level match", + "data": { "foo": "hi" }, + "valid": true + }, + { + "description": "integer does not match as a property value", + "data": { "foo": 1 }, + "valid": false + }, + { + "description": "two levels, properties match with inner definition", + "data": { "foo": { "bar": "hi" } }, + "valid": true + }, + { + "description": "two levels, integer does not match as a property value", + "data": { "foo": { "bar": 1 } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef with no $recursiveAnchor in the initial target schema resource", + "schema": { + "$id": "http://localhost:4242/recursiveRef6/base.json", + "$recursiveAnchor": true, + "anyOf": [ + { "type": "boolean" }, + { + "type": "object", + "additionalProperties": { + "$id": "http://localhost:4242/recursiveRef6/inner.json", + "$comment": "there is no $recursiveAnchor: true here, so we do NOT recurse to the base", + "anyOf": [ + { "type": "integer" }, + { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } + ] + } + } + ] + }, + "tests": [ + { + "description": "leaf node does not match; no recursion", + "data": { "foo": true }, + "valid": false + }, + { + "description": "leaf node matches: recursion uses the inner schema", + "data": { "foo": { "bar": 1 } }, + "valid": true + }, + { + "description": "leaf node does not match: recursion uses the inner schema", + "data": { "foo": { "bar": true } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef with no $recursiveAnchor in the outer schema resource", + "schema": { + "$id": "http://localhost:4242/recursiveRef7/base.json", + "anyOf": [ + { "type": "boolean" }, + { + "type": "object", + "additionalProperties": { + "$id": "http://localhost:4242/recursiveRef7/inner.json", + "$recursiveAnchor": true, + "anyOf": [ + { "type": "integer" }, + { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } + ] + } + } + ] + }, + "tests": [ + { + "description": "leaf node does not match; no recursion", + "data": { "foo": true }, + "valid": false + }, + { + "description": "leaf node matches: recursion only uses inner schema", + "data": { "foo": { "bar": 1 } }, + "valid": true + }, + { + "description": "leaf node does not match: recursion only uses inner schema", + "data": { "foo": { "bar": true } }, + "valid": false + } + ] + }, + { + "description": "multiple dynamic paths to the $recursiveRef keyword", + "schema": { + "$id": "recursiveRef8_main.json", + "$defs": { + "inner": { + "$id": "recursiveRef8_inner.json", + "$recursiveAnchor": true, + "title": "inner", + "additionalProperties": { + "$recursiveRef": "#" + } + } + }, + "if": { + "propertyNames": { + "pattern": "^[a-m]" + } + }, + "then": { + "title": "any type of node", + "$id": "recursiveRef8_anyLeafNode.json", + "$recursiveAnchor": true, + "$ref": "recursiveRef8_main.json#/$defs/inner" + }, + "else": { + "title": "integer node", + "$id": "recursiveRef8_integerNode.json", + "$recursiveAnchor": true, + "type": [ "object", "integer" ], + "$ref": "recursiveRef8_main.json#/$defs/inner" + } + }, + "tests": [ + { + "description": "recurse to anyLeafNode - floats are allowed", + "data": { "alpha": 1.1 }, + "valid": true + }, + { + "description": "recurse to integerNode - floats are not allowed", + "data": { "november": 1.1 }, + "valid": false + } + ] + } +] diff --git a/tests/draft2019-09/unevaluatedItems.json b/tests/draft2019-09/unevaluatedItems.json index 32f13f8..84f5e31 100644 --- a/tests/draft2019-09/unevaluatedItems.json +++ b/tests/draft2019-09/unevaluatedItems.json @@ -433,5 +433,57 @@ "valid": false } ] + }, + { + "description": "item is evaluated in an uncle schema to unevaluatedItems", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "array", + "items": [ + { + "type": "string" + } + ], + "unevaluatedItems": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "items": [ + true, + { + "type": "string" + } + ] + } + } + } + ] + }, + "tests": [ + { + "description": "no extra items", + "data": { + "foo": [ + "test" + ] + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": [ + "test", + "test" + ] + }, + "valid": false + } + ] } ] diff --git a/tests/draft2019-09/unevaluatedProperties.json b/tests/draft2019-09/unevaluatedProperties.json index b634be5..31933c1 100644 --- a/tests/draft2019-09/unevaluatedProperties.json +++ b/tests/draft2019-09/unevaluatedProperties.json @@ -809,5 +809,147 @@ "valid": false } ] + }, + { + "description": "property is evaluated in an uncle schema to unevaluatedProperties", + "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "object", + "properties": { + "bar": { + "type": "string" + } + }, + "unevaluatedProperties": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "properties": { + "faz": { + "type": "string" + } + } + } + } + } + ] + }, + "tests": [ + { + "description": "no extra properties", + "data": { + "foo": { + "bar": "test" + } + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": { + "bar": "test", + "faz": "test" + } + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, allOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + }, + "unevaluatedProperties": false + } + ], + "anyOf": [ + { + "properties": { + "bar": true + } + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": true + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, anyOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + } + } + ], + "anyOf": [ + { + "properties": { + "bar": true + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": true + } + ] } ] |