diff --git a/src/main/java/com/networknt/schema/uri/URITranslator.java b/src/main/java/com/networknt/schema/uri/URITranslator.java index 8783e97d0..aea812010 100644 --- a/src/main/java/com/networknt/schema/uri/URITranslator.java +++ b/src/main/java/com/networknt/schema/uri/URITranslator.java @@ -5,7 +5,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; -import java.util.Locale; import java.util.Map; import java.util.Objects; @@ -141,14 +140,14 @@ class PrefixReplacer implements URITranslator { private final String tgt; public PrefixReplacer(String src, String tgt) { - this.src = src.toLowerCase(Locale.US); + this.src = src; this.tgt = tgt; } @Override public URI translate(URI original) { if (null != original) { - String o = original.toASCIIString().toLowerCase(Locale.US); + String o = original.toString(); if (o.startsWith(src)) { o = tgt + o.substring(src.length()); return URI.create(o); diff --git a/src/test/java/com/networknt/schema/AbstractJsonSchemaTestSuite.java b/src/test/java/com/networknt/schema/AbstractJsonSchemaTestSuite.java index bb57f9fff..4879b495e 100644 --- a/src/test/java/com/networknt/schema/AbstractJsonSchemaTestSuite.java +++ b/src/test/java/com/networknt/schema/AbstractJsonSchemaTestSuite.java @@ -111,8 +111,8 @@ private JsonSchemaFactory buildValidatorFactory(VersionFlag defaultVersion, Test .builder(base) .objectMapper(mapper) .addUriTranslator(URITranslator.combine( - URITranslator.prefix("http://json-schema.org", "resource:"), - URITranslator.prefix("https://json-schema.org", "resource:") + URITranslator.prefix("https://", "http://"), + URITranslator.prefix("http://json-schema.org", "resource:") )) .build(); } diff --git a/src/test/suite/bin/jsonschema_suite b/src/test/suite/bin/jsonschema_suite index b4792a051..9fee8d7ba 100755 --- a/src/test/suite/bin/jsonschema_suite +++ b/src/test/suite/bin/jsonschema_suite @@ -498,6 +498,13 @@ class SanityTests(unittest.TestCase): "title", "type", "uniqueItems", + + # Technically this is wrong, $comment doesn't exist in this + # draft, but the point of this test is to detect mistakes by, + # test authors, whereas the point of the $comment keyword is + # to just standardize a place for a comment, so it's not a + # mistake to use it in earlier drafts in tests per se. + "$comment", }, "draft3": { "$ref", @@ -528,6 +535,13 @@ class SanityTests(unittest.TestCase): "title", "type", "uniqueItems", + + # Technically this is wrong, $comment doesn't exist in this + # draft, but the point of this test is to detect mistakes by, + # test authors, whereas the point of the $comment keyword is + # to just standardize a place for a comment, so it's not a + # mistake to use it in earlier drafts in tests per se. + "$comment", }, } diff --git a/src/test/suite/output-tests/README.md b/src/test/suite/output-tests/README.md index 0cd7c87b7..d209bdb25 100644 --- a/src/test/suite/output-tests/README.md +++ b/src/test/suite/output-tests/README.md @@ -2,21 +2,21 @@ These tests are intended to validate that implementations are correctly generati Output was initially specified with draft 2019-09. It remained largely unchanged for draft 2020-12, but will receive an update with the next release. -***NOTE** Although the formats didn't change between 2019-09 and 2020-12, the tests are replicated for 2020-12 because the `$schema` is different and implementations may (but shouldn't) produce different output.* +_**NOTE** Although the formats didn't change much between 2019-09 and 2020-12, the tests are copied for 2020-12 because the `$schema` is different and implementations may (but shouldn't) produce different output._ ## Organization The tests are organized by specification release and then into two categories: content and structure. -Content tests verify that the keywords are producing the correct annotations and/or error messages. Since there are no requirements on the content of error messages, there's not much that can be verified for them, but it is possible to identify when a error message _could_ be present. Primarily, these tests need to extensively cover the annotation behaviors of each keyword. The only output format needed for these tests is `basic` for 2019-09/2020/12 and `list` for later versions. +Content tests verify that the keywords are producing the correct annotations and/or error messages. Since there are no requirements on the content of error messages, there's not much that can be verified for them, but it is possible to identify when a error message _could_ be present. Primarily, these tests need to extensively cover the annotation behaviors of each keyword. The only output format needed for these tests is `basic` for 2019-09/2020-12 and `list` for later versions. -Structure tests verify that the structures of the various formats (i.e. `flag`, `basic`, `detailed`, `verbose` for 2019/2020 and `flag`, `list`, `hierarchical` for later versions) are correct. These tests don't need to cover each keyword; rather they need to sufficiently cover the various aspects of building the output structures by using whatever keywords are necessary to do so. +Structure tests verify that the structures of the various formats (i.e. `flag`, `basic`, `detailed`, `verbose` for 2019-09/2020-12 and `flag`, `list`, `hierarchical` for later versions) are correct. These tests don't need to cover each keyword; rather they need to sufficiently cover the various aspects of building the output structures by using whatever keywords are necessary to do so. In each release folder, you'll also find an _output-schema.json_ file that contains the schema from the specification repo that describes output for that release. This schema will need to be loaded as the tests reference it. ## Test Files -The content of a test file is the same as the validation tests in `tests/`, however an `output` property has been added to each test case. +The content of a test file is similar to the validation tests in `tests/`: for each test case, the `valid` property has been removed, and an `output` property has been added. The `output` property itself has a property for each of the output formats where the value is a schema that will successfully validate for compliant output. For the content tests, only `basic`/`list` needs to be present. diff --git a/src/test/suite/tests/draft-next/dependentSchemas.json b/src/test/suite/tests/draft-next/dependentSchemas.json index 67c797965..8a8477591 100644 --- a/src/test/suite/tests/draft-next/dependentSchemas.json +++ b/src/test/suite/tests/draft-next/dependentSchemas.json @@ -128,5 +128,43 @@ "valid": false } ] + }, + { + "description": "dependent subschema incompatible with root", + "schema": { + "properties": { + "foo": {} + }, + "dependentSchemas": { + "foo": { + "properties": { + "bar": {} + }, + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "matches root", + "data": {"foo": 1}, + "valid": false + }, + { + "description": "matches dependency", + "data": {"bar": 1}, + "valid": true + }, + { + "description": "matches both", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "no dependency", + "data": {"baz": 1}, + "valid": true + } + ] } ] diff --git a/src/test/suite/tests/draft-next/format.json b/src/test/suite/tests/draft-next/format.json index 43a8bd6ff..ec6c7f1dd 100644 --- a/src/test/suite/tests/draft-next/format.json +++ b/src/test/suite/tests/draft-next/format.json @@ -35,6 +35,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid email string is only an annotation by default", + "data": "2962", + "valid": true } ] }, @@ -74,6 +79,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid idn-email string is only an annotation by default", + "data": "2962", + "valid": true } ] }, @@ -113,6 +123,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid regex string is only an annotation by default", + "data": "^(abc]", + "valid": true } ] }, @@ -152,6 +167,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid ipv4 string is only an annotation by default", + "data": "127.0.0.0.1", + "valid": true } ] }, @@ -191,6 +211,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid ipv6 string is only an annotation by default", + "data": "12345::", + "valid": true } ] }, @@ -230,6 +255,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid idn-hostname string is only an annotation by default", + "data": "〮실례.테스트", + "valid": true } ] }, @@ -269,6 +299,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid hostname string is only an annotation by default", + "data": "-a-host-name-that-starts-with--", + "valid": true } ] }, @@ -308,6 +343,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid date string is only an annotation by default", + "data": "06/19/1963", + "valid": true } ] }, @@ -347,6 +387,11 @@ "description": "all string formats ignore nulls", "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 } ] }, @@ -386,6 +431,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid time string is only an annotation by default", + "data": "08:30:06 PST", + "valid": true } ] }, @@ -425,6 +475,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid json-pointer string is only an annotation by default", + "data": "/foo/bar~", + "valid": true } ] }, @@ -464,6 +519,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid relative-json-pointer string is only an annotation by default", + "data": "/foo/bar", + "valid": true } ] }, @@ -503,6 +563,11 @@ "description": "all string formats ignore nulls", "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 } ] }, @@ -542,6 +607,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid iri-reference string is only an annotation by default", + "data": "\\\\WINDOWS\\filëßåré", + "valid": true } ] }, @@ -581,6 +651,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid uri string is only an annotation by default", + "data": "//foo.bar/?baz=qux#quux", + "valid": true } ] }, @@ -620,6 +695,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid uri-reference string is only an annotation by default", + "data": "\\\\WINDOWS\\fileshare", + "valid": true } ] }, @@ -659,6 +739,11 @@ "description": "all string formats ignore nulls", "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 } ] }, @@ -698,6 +783,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid uuid string is only an annotation by default", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", + "valid": true } ] }, @@ -737,6 +827,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid duration string is only an annotation by default", + "data": "PT1D", + "valid": true } ] } diff --git a/src/test/suite/tests/draft-next/id.json b/src/test/suite/tests/draft-next/id.json index b6a3566f2..9b3a591f0 100644 --- a/src/test/suite/tests/draft-next/id.json +++ b/src/test/suite/tests/draft-next/id.json @@ -217,32 +217,32 @@ "id_in_enum": { "enum": [ { - "$id": "http://localhost:1234/draft-next/id/my_identifier.json", + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { - "$id": "http://localhost:1234/draft-next/id/my_identifier.json", + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { - "$id": "http://localhost:1234/draft-next/id/my_identifier.json", + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "http://localhost:1234/draft-next/id/my_identifier.json" } + { "$ref": "https://localhost:1234/draft-next/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { - "$id": "http://localhost:1234/draft-next/id/my_identifier.json", + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", "type": "null" }, "valid": true diff --git a/src/test/suite/tests/draft-next/ref.json b/src/test/suite/tests/draft-next/ref.json index 6457e8a23..1d5f25613 100644 --- a/src/test/suite/tests/draft-next/ref.json +++ b/src/test/suite/tests/draft-next/ref.json @@ -601,16 +601,16 @@ "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "$id must be evaluated before $ref to get the proper $ref destination", - "$id": "/draft/next/ref-and-id1/base.json", + "$id": "https://example.com/draft/next/ref-and-id1/base.json", "$ref": "int.json", "$defs": { "bigint": { - "$comment": "canonical uri: /ref-and-id1/int.json", + "$comment": "canonical uri: https://example.com/ref-and-id1/int.json", "$id": "int.json", "maximum": 10 }, "smallint": { - "$comment": "canonical uri: /ref-and-id1-int.json", + "$comment": "canonical uri: https://example.com/ref-and-id1-int.json", "$id": "/draft/next/ref-and-id1-int.json", "maximum": 2 } @@ -634,16 +634,16 @@ "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$comment": "$id must be evaluated before $ref to get the proper $ref destination", - "$id": "/draft/next/ref-and-id2/base.json", + "$id": "https://example.com/draft/next/ref-and-id2/base.json", "$ref": "#bigint", "$defs": { "bigint": { - "$comment": "canonical uri: /ref-and-id2/base.json#/$defs/bigint; another valid uri for this location: /ref-and-id2/base.json#bigint", + "$comment": "canonical uri: https://example.com/ref-and-id2/base.json#/$defs/bigint; another valid uri for this location: https://example.com/ref-and-id2/base.json#bigint", "$anchor": "bigint", "maximum": 10 }, "smallint": { - "$comment": "canonical uri: /ref-and-id2#/$defs/smallint; another valid uri for this location: /ref-and-id2/#bigint", + "$comment": "canonical uri: https://example.com/ref-and-id2#/$defs/smallint; another valid uri for this location: https://example.com/ref-and-id2/#bigint", "$id": "/draft/next/ref-and-id2/", "$anchor": "bigint", "maximum": 2 @@ -951,32 +951,109 @@ ] }, { - "description": "ref with absolute-path-reference", - "schema": { - "$id": "http://example.com/ref/absref.json", - "$defs": { - "a": { - "$id": "http://example.com/ref/absref/foobar.json", - "type": "number" - }, - "b": { - "$id": "http://example.com/absref/foobar.json", - "type": "string" - } - }, - "$ref": "/absref/foobar.json" - }, - "tests": [ - { - "description": "a string is valid", - "data": "foo", - "valid": true - }, - { - "description": "an integer is invalid", - "data": 12, - "valid": false - } - ] - } + "description": "ref with absolute-path-reference", + "schema": { + "$id": "http://example.com/ref/absref.json", + "$defs": { + "a": { + "$id": "http://example.com/ref/absref/foobar.json", + "type": "number" + }, + "b": { + "$id": "http://example.com/absref/foobar.json", + "type": "string" + } + }, + "$ref": "/absref/foobar.json" + }, + "tests": [ + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "an integer is invalid", + "data": 12, + "valid": false + } + ] + }, + { + "description": "$id with file URI still resolves pointers - *nix", + "schema": { + "$id": "file:///folder/file.json", + "$defs": { + "foo": { + "type": "number" + } + }, + "$ref": "#/$defs/foo" + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "$id with file URI still resolves pointers - windows", + "schema": { + "$id": "file:///c:/folder/file.json", + "$defs": { + "foo": { + "type": "number" + } + }, + "$ref": "#/$defs/foo" + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "empty tokens in $ref json-pointer", + "schema": { + "$defs": { + "": { + "$defs": { + "": { "type": "number" } + } + } + }, + "allOf": [ + { + "$ref": "#/$defs//$defs/" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + } ] diff --git a/src/test/suite/tests/draft-next/unevaluatedItems.json b/src/test/suite/tests/draft-next/unevaluatedItems.json index ce5d0438c..7379afb41 100644 --- a/src/test/suite/tests/draft-next/unevaluatedItems.json +++ b/src/test/suite/tests/draft-next/unevaluatedItems.json @@ -692,5 +692,28 @@ "valid": true } ] + }, + { + "description": "unevaluatedItems can see annotations from if without then and else", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "if": { + "prefixItems": [{"const": "a"}] + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "valid in case if is evaluated", + "data": [ "a" ], + "valid": true + }, + { + "description": "invalid in case if is evaluated", + "data": [ "b" ], + "valid": false + } + + ] } ] diff --git a/src/test/suite/tests/draft-next/unevaluatedProperties.json b/src/test/suite/tests/draft-next/unevaluatedProperties.json index f3d4012ce..69fe8a00c 100644 --- a/src/test/suite/tests/draft-next/unevaluatedProperties.json +++ b/src/test/suite/tests/draft-next/unevaluatedProperties.json @@ -1232,7 +1232,7 @@ ] }, { - "description": "dynamic evalation inside nested refs", + "description": "dynamic evaluation inside nested refs", "schema": { "$schema": "https://json-schema.org/draft/next/schema", "$defs": { @@ -1482,7 +1482,7 @@ }, "propertyDependencies": { "foo": { - "foo1": { + "foo1": { "properties": { "bar": true } @@ -1538,5 +1538,35 @@ "valid": false } ] + }, + { + "description": "unevaluatedProperties can see annotations from if without then and else", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "if": { + "patternProperties": { + "foo": { + "type": "string" + } + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "valid in case if is evaluated", + "data": { + "foo": "a" + }, + "valid": true + }, + { + "description": "invalid in case if is evaluated", + "data": { + "bar": "a" + }, + "valid": false + } + ] } ] diff --git a/src/test/suite/tests/draft-next/uniqueItems.json b/src/test/suite/tests/draft-next/uniqueItems.json index 610b257df..b16dd505b 100644 --- a/src/test/suite/tests/draft-next/uniqueItems.json +++ b/src/test/suite/tests/draft-next/uniqueItems.json @@ -56,6 +56,11 @@ "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, + { + "description": "property order of array of objects is ignored", + "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], + "valid": false + }, { "description": "unique array of nested objects is valid", "data": [ diff --git a/src/test/suite/tests/draft-next/unknownKeyword.json b/src/test/suite/tests/draft-next/unknownKeyword.json index c97ca3c03..055ff6b66 100644 --- a/src/test/suite/tests/draft-next/unknownKeyword.json +++ b/src/test/suite/tests/draft-next/unknownKeyword.json @@ -9,21 +9,21 @@ "not": { "array_of_schemas": [ { - "$id": "http://localhost:1234/draft-next/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft-next/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { - "$id": "http://localhost:1234/draft-next/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft-next/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { - "$id": "http://localhost:1234/draft-next/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft-next/unknownKeyword/my_identifier.json", "type": "integer" } } @@ -33,7 +33,7 @@ "anyOf": [ { "$ref": "#/$defs/id_in_unknown0" }, { "$ref": "#/$defs/id_in_unknown1" }, - { "$ref": "http://localhost:1234/draft-next/unknownKeyword/my_identifier.json" } + { "$ref": "https://localhost:1234/draft-next/unknownKeyword/my_identifier.json" } ] }, "tests": [ diff --git a/src/test/suite/tests/draft2019-09/dependentSchemas.json b/src/test/suite/tests/draft2019-09/dependentSchemas.json index b39758319..3577efdf4 100644 --- a/src/test/suite/tests/draft2019-09/dependentSchemas.json +++ b/src/test/suite/tests/draft2019-09/dependentSchemas.json @@ -128,5 +128,43 @@ "valid": false } ] + }, + { + "description": "dependent subschema incompatible with root", + "schema": { + "properties": { + "foo": {} + }, + "dependentSchemas": { + "foo": { + "properties": { + "bar": {} + }, + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "matches root", + "data": {"foo": 1}, + "valid": false + }, + { + "description": "matches dependency", + "data": {"bar": 1}, + "valid": true + }, + { + "description": "matches both", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "no dependency", + "data": {"baz": 1}, + "valid": true + } + ] } ] diff --git a/src/test/suite/tests/draft2019-09/id.json b/src/test/suite/tests/draft2019-09/id.json index a481db01a..e2e403f0b 100644 --- a/src/test/suite/tests/draft2019-09/id.json +++ b/src/test/suite/tests/draft2019-09/id.json @@ -217,32 +217,32 @@ "id_in_enum": { "enum": [ { - "$id": "http://localhost:1234/draft2019-09/id/my_identifier.json", + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { - "$id": "http://localhost:1234/draft2019-09/id/my_identifier.json", + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { - "$id": "http://localhost:1234/draft2019-09/id/my_identifier.json", + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "http://localhost:1234/draft2019-09/id/my_identifier.json" } + { "$ref": "https://localhost:1234/draft2019-09/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { - "$id": "http://localhost:1234/draft2019-09/id/my_identifier.json", + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", "type": "null" }, "valid": true diff --git a/src/test/suite/tests/draft2019-09/recursiveRef.json b/src/test/suite/tests/draft2019-09/recursiveRef.json index 1e713ffec..22b47e749 100644 --- a/src/test/suite/tests/draft2019-09/recursiveRef.json +++ b/src/test/suite/tests/draft2019-09/recursiveRef.json @@ -318,7 +318,7 @@ "description": "multiple dynamic paths to the $recursiveRef keyword", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "recursiveRef8_main.json", + "$id": "https://example.com/recursiveRef8_main.json", "$defs": { "inner": { "$id": "recursiveRef8_inner.json", @@ -365,7 +365,7 @@ "description": "dynamic $recursiveRef destination (not predictable at schema compile time)", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "main.json", + "$id": "https://example.com/main.json", "$defs": { "inner": { "$id": "inner.json", diff --git a/src/test/suite/tests/draft2019-09/ref.json b/src/test/suite/tests/draft2019-09/ref.json index d420bd98c..7d850414d 100644 --- a/src/test/suite/tests/draft2019-09/ref.json +++ b/src/test/suite/tests/draft2019-09/ref.json @@ -601,16 +601,16 @@ "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "$id must be evaluated before $ref to get the proper $ref destination", - "$id": "/draft2019-09/ref-and-id1/base.json", + "$id": "https://example.com/draft2019-09/ref-and-id1/base.json", "$ref": "int.json", "$defs": { "bigint": { - "$comment": "canonical uri: /draft2019-09/ref-and-id1/int.json", + "$comment": "canonical uri: https://example.com/draft2019-09/ref-and-id1/int.json", "$id": "int.json", "maximum": 10 }, "smallint": { - "$comment": "canonical uri: /draft2019-09/ref-and-id1-int.json", + "$comment": "canonical uri: https://example.com/draft2019-09/ref-and-id1-int.json", "$id": "/draft2019-09/ref-and-id1-int.json", "maximum": 2 } @@ -634,16 +634,16 @@ "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "$comment": "$id must be evaluated before $ref to get the proper $ref destination", - "$id": "/draft2019-09/ref-and-id2/base.json", + "$id": "https://example.com/draft2019-09/ref-and-id2/base.json", "$ref": "#bigint", "$defs": { "bigint": { - "$comment": "canonical uri: /draft2019-09/ref-and-id2/base.json#/$defs/bigint; another valid uri for this location: /ref-and-id2/base.json#bigint", + "$comment": "canonical uri: https://example.com/draft2019-09/ref-and-id2/base.json#/$defs/bigint; another valid uri for this location: https://example.com/ref-and-id2/base.json#bigint", "$anchor": "bigint", "maximum": 10 }, "smallint": { - "$comment": "canonical uri: /draft2019-09/ref-and-id2#/$defs/smallint; another valid uri for this location: /ref-and-id2/#bigint", + "$comment": "canonical uri: https://example.com/draft2019-09/ref-and-id2#/$defs/smallint; another valid uri for this location: https://example.com/ref-and-id2/#bigint", "$id": "/draft2019-09/ref-and-id2/", "$anchor": "bigint", "maximum": 2 @@ -978,5 +978,82 @@ "valid": false } ] + }, + { + "description": "$id with file URI still resolves pointers - *nix", + "schema": { + "$id": "file:///folder/file.json", + "$defs": { + "foo": { + "type": "number" + } + }, + "$ref": "#/$defs/foo" + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "$id with file URI still resolves pointers - windows", + "schema": { + "$id": "file:///c:/folder/file.json", + "$defs": { + "foo": { + "type": "number" + } + }, + "$ref": "#/$defs/foo" + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "empty tokens in $ref json-pointer", + "schema": { + "$defs": { + "": { + "$defs": { + "": { "type": "number" } + } + } + }, + "allOf": [ + { + "$ref": "#/$defs//$defs/" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] } ] diff --git a/src/test/suite/tests/draft2019-09/unevaluatedItems.json b/src/test/suite/tests/draft2019-09/unevaluatedItems.json index a0b1f3380..53565a0b9 100644 --- a/src/test/suite/tests/draft2019-09/unevaluatedItems.json +++ b/src/test/suite/tests/draft2019-09/unevaluatedItems.json @@ -600,5 +600,28 @@ "valid": true } ] + }, + { + "description": "unevaluatedItems can see annotations from if without then and else", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "if": { + "items": [{"const": "a"}] + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "valid in case if is evaluated", + "data": [ "a" ], + "valid": true + }, + { + "description": "invalid in case if is evaluated", + "data": [ "b" ], + "valid": false + } + + ] } ] diff --git a/src/test/suite/tests/draft2019-09/unevaluatedProperties.json b/src/test/suite/tests/draft2019-09/unevaluatedProperties.json index d089c770c..fbb7895c3 100644 --- a/src/test/suite/tests/draft2019-09/unevaluatedProperties.json +++ b/src/test/suite/tests/draft2019-09/unevaluatedProperties.json @@ -1443,5 +1443,35 @@ "valid": false } ] + }, + { + "description": "unevaluatedProperties can see annotations from if without then and else", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "if": { + "patternProperties": { + "foo": { + "type": "string" + } + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "valid in case if is evaluated", + "data": { + "foo": "a" + }, + "valid": true + }, + { + "description": "invalid in case if is evaluated", + "data": { + "bar": "a" + }, + "valid": false + } + ] } ] diff --git a/src/test/suite/tests/draft2019-09/uniqueItems.json b/src/test/suite/tests/draft2019-09/uniqueItems.json index 6da878be9..314b4b9cb 100644 --- a/src/test/suite/tests/draft2019-09/uniqueItems.json +++ b/src/test/suite/tests/draft2019-09/uniqueItems.json @@ -56,6 +56,11 @@ "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, + { + "description": "property order of array of objects is ignored", + "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], + "valid": false + }, { "description": "unique array of nested objects is valid", "data": [ diff --git a/src/test/suite/tests/draft2019-09/unknownKeyword.json b/src/test/suite/tests/draft2019-09/unknownKeyword.json index 9eff51a39..f98e87c54 100644 --- a/src/test/suite/tests/draft2019-09/unknownKeyword.json +++ b/src/test/suite/tests/draft2019-09/unknownKeyword.json @@ -9,21 +9,21 @@ "not": { "array_of_schemas": [ { - "$id": "http://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { - "$id": "http://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { - "$id": "http://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json", "type": "integer" } } @@ -33,7 +33,7 @@ "anyOf": [ { "$ref": "#/$defs/id_in_unknown0" }, { "$ref": "#/$defs/id_in_unknown1" }, - { "$ref": "http://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json" } + { "$ref": "https://localhost:1234/draft2019-09/unknownKeyword/my_identifier.json" } ] }, "tests": [ diff --git a/src/test/suite/tests/draft2020-12/dependentSchemas.json b/src/test/suite/tests/draft2020-12/dependentSchemas.json index bf7aa53a2..66ac0eb43 100644 --- a/src/test/suite/tests/draft2020-12/dependentSchemas.json +++ b/src/test/suite/tests/draft2020-12/dependentSchemas.json @@ -128,5 +128,43 @@ "valid": false } ] + }, + { + "description": "dependent subschema incompatible with root", + "schema": { + "properties": { + "foo": {} + }, + "dependentSchemas": { + "foo": { + "properties": { + "bar": {} + }, + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "matches root", + "data": {"foo": 1}, + "valid": false + }, + { + "description": "matches dependency", + "data": {"bar": 1}, + "valid": true + }, + { + "description": "matches both", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "no dependency", + "data": {"baz": 1}, + "valid": true + } + ] } ] diff --git a/src/test/suite/tests/draft2020-12/format.json b/src/test/suite/tests/draft2020-12/format.json index 6b7904ee6..e0f1fb459 100644 --- a/src/test/suite/tests/draft2020-12/format.json +++ b/src/test/suite/tests/draft2020-12/format.json @@ -35,6 +35,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid email string is only an annotation by default", + "data": "2962", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -74,6 +81,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid idn-email string is only an annotation by default", + "data": "2962", + "valid": true } ] }, @@ -113,6 +125,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid regex string is only an annotation by default", + "data": "^(abc]", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -152,6 +171,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid ipv4 string is only an annotation by default", + "data": "127.0.0.0.1", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -191,6 +217,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid ipv6 string is only an annotation by default", + "data": "12345::", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -230,6 +263,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid idn-hostname string is only an annotation by default", + "data": "〮실례.테스트", + "valid": true } ] }, @@ -269,6 +307,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid hostname string is only an annotation by default", + "data": "-a-host-name-that-starts-with--", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -308,6 +353,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid date string is only an annotation by default", + "data": "06/19/1963", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -347,6 +399,13 @@ "description": "all string formats ignore nulls", "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, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -386,6 +445,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid time string is only an annotation by default", + "data": "08:30:06 PST", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -425,6 +491,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid json-pointer string is only an annotation by default", + "data": "/foo/bar~", + "valid": true } ] }, @@ -464,6 +535,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid relative-json-pointer string is only an annotation by default", + "data": "/foo/bar", + "valid": true } ] }, @@ -503,6 +579,11 @@ "description": "all string formats ignore nulls", "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 } ] }, @@ -542,6 +623,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid iri-reference string is only an annotation by default", + "data": "\\\\WINDOWS\\filëßåré", + "valid": true } ] }, @@ -581,6 +667,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid uri string is only an annotation by default", + "data": "//foo.bar/?baz=qux#quux", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -620,6 +713,11 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid uri-reference string is only an annotation by default", + "data": "\\\\WINDOWS\\fileshare", + "valid": true } ] }, @@ -659,6 +757,11 @@ "description": "all string formats ignore nulls", "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 } ] }, @@ -698,6 +801,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid uuid string is only an annotation by default", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] }, @@ -737,6 +847,13 @@ "description": "all string formats ignore nulls", "data": null, "valid": true + }, + { + "description": "invalid duration string is only an annotation by default", + "data": "PT1D", + "valid": true, + "disabled": true, + "reason": "TODO: Only the Format-Assertion vocabulary is currently supported" } ] } diff --git a/src/test/suite/tests/draft2020-12/id.json b/src/test/suite/tests/draft2020-12/id.json index 67c31fc0c..0ae5fe68a 100644 --- a/src/test/suite/tests/draft2020-12/id.json +++ b/src/test/suite/tests/draft2020-12/id.json @@ -217,32 +217,32 @@ "id_in_enum": { "enum": [ { - "$id": "http://localhost:1234/draft2020-12/id/my_identifier.json", + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { - "$id": "http://localhost:1234/draft2020-12/id/my_identifier.json", + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { - "$id": "http://localhost:1234/draft2020-12/id/my_identifier.json", + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "http://localhost:1234/draft2020-12/id/my_identifier.json" } + { "$ref": "https://localhost:1234/draft2020-12/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { - "$id": "http://localhost:1234/draft2020-12/id/my_identifier.json", + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", "type": "null" }, "valid": true diff --git a/src/test/suite/tests/draft2020-12/ref.json b/src/test/suite/tests/draft2020-12/ref.json index 72c593a17..5f6be8c20 100644 --- a/src/test/suite/tests/draft2020-12/ref.json +++ b/src/test/suite/tests/draft2020-12/ref.json @@ -601,16 +601,16 @@ "schema": { "$comment": "$id must be evaluated before $ref to get the proper $ref destination", "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "/draft2020-12/ref-and-id1/base.json", + "$id": "https://example.com/draft2020-12/ref-and-id1/base.json", "$ref": "int.json", "$defs": { "bigint": { - "$comment": "canonical uri: /ref-and-id1/int.json", + "$comment": "canonical uri: https://example.com/ref-and-id1/int.json", "$id": "int.json", "maximum": 10 }, "smallint": { - "$comment": "canonical uri: /ref-and-id1-int.json", + "$comment": "canonical uri: https://example.com/ref-and-id1-int.json", "$id": "/draft2020-12/ref-and-id1-int.json", "maximum": 2 } @@ -634,7 +634,7 @@ "schema": { "$comment": "$id must be evaluated before $ref to get the proper $ref destination", "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "/draft2020-12/ref-and-id2/base.json", + "$id": "https://example.com/draft2020-12/ref-and-id2/base.json", "$ref": "#bigint", "$defs": { "bigint": { @@ -643,8 +643,8 @@ "maximum": 10 }, "smallint": { - "$comment": "canonical uri: /ref-and-id2#/$defs/smallint; another valid uri for this location: /ref-and-id2/#bigint", - "$id": "/draft2020-12/ref-and-id2/", + "$comment": "canonical uri: https://example.com/ref-and-id2#/$defs/smallint; another valid uri for this location: https://example.com/ref-and-id2/#bigint", + "$id": "https://example.com/draft2020-12/ref-and-id2/", "$anchor": "bigint", "maximum": 2 } @@ -978,5 +978,82 @@ "valid": false } ] + }, + { + "description": "$id with file URI still resolves pointers - *nix", + "schema": { + "$id": "file:///folder/file.json", + "$defs": { + "foo": { + "type": "number" + } + }, + "$ref": "#/$defs/foo" + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "$id with file URI still resolves pointers - windows", + "schema": { + "$id": "file:///c:/folder/file.json", + "$defs": { + "foo": { + "type": "number" + } + }, + "$ref": "#/$defs/foo" + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "empty tokens in $ref json-pointer", + "schema": { + "$defs": { + "": { + "$defs": { + "": { "type": "number" } + } + } + }, + "allOf": [ + { + "$ref": "#/$defs//$defs/" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] } ] diff --git a/src/test/suite/tests/draft2020-12/unevaluatedItems.json b/src/test/suite/tests/draft2020-12/unevaluatedItems.json index 2b816af94..2615c4c41 100644 --- a/src/test/suite/tests/draft2020-12/unevaluatedItems.json +++ b/src/test/suite/tests/draft2020-12/unevaluatedItems.json @@ -692,5 +692,28 @@ "valid": true } ] + }, + { + "description": "unevaluatedItems can see annotations from if without then and else", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "if": { + "prefixItems": [{"const": "a"}] + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "valid in case if is evaluated", + "data": [ "a" ], + "valid": true + }, + { + "description": "invalid in case if is evaluated", + "data": [ "b" ], + "valid": false + } + + ] } ] diff --git a/src/test/suite/tests/draft2020-12/unevaluatedProperties.json b/src/test/suite/tests/draft2020-12/unevaluatedProperties.json index dc075b1f2..415be39d4 100644 --- a/src/test/suite/tests/draft2020-12/unevaluatedProperties.json +++ b/src/test/suite/tests/draft2020-12/unevaluatedProperties.json @@ -1443,5 +1443,35 @@ "valid": false } ] + }, + { + "description": "unevaluatedProperties can see annotations from if without then and else", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "if": { + "patternProperties": { + "foo": { + "type": "string" + } + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "valid in case if is evaluated", + "data": { + "foo": "a" + }, + "valid": true + }, + { + "description": "invalid in case if is evaluated", + "data": { + "bar": "a" + }, + "valid": false + } + ] } ] diff --git a/src/test/suite/tests/draft2020-12/uniqueItems.json b/src/test/suite/tests/draft2020-12/uniqueItems.json index 707235c3a..4ea3bf985 100644 --- a/src/test/suite/tests/draft2020-12/uniqueItems.json +++ b/src/test/suite/tests/draft2020-12/uniqueItems.json @@ -56,6 +56,11 @@ "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, + { + "description": "property order of array of objects is ignored", + "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], + "valid": false + }, { "description": "unique array of nested objects is valid", "data": [ diff --git a/src/test/suite/tests/draft2020-12/unknownKeyword.json b/src/test/suite/tests/draft2020-12/unknownKeyword.json index ce12b31b0..28b0c4ce9 100644 --- a/src/test/suite/tests/draft2020-12/unknownKeyword.json +++ b/src/test/suite/tests/draft2020-12/unknownKeyword.json @@ -9,21 +9,21 @@ "not": { "array_of_schemas": [ { - "$id": "http://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { - "$id": "http://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { - "$id": "http://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json", "type": "integer" } } @@ -33,7 +33,7 @@ "anyOf": [ { "$ref": "#/$defs/id_in_unknown0" }, { "$ref": "#/$defs/id_in_unknown1" }, - { "$ref": "http://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json" } + { "$ref": "https://localhost:1234/draft2020-12/unknownKeyword/my_identifier.json" } ] }, "tests": [ diff --git a/src/test/suite/tests/draft4/dependencies.json b/src/test/suite/tests/draft4/dependencies.json index 51eeddf32..9045ddc25 100644 --- a/src/test/suite/tests/draft4/dependencies.json +++ b/src/test/suite/tests/draft4/dependencies.json @@ -190,5 +190,43 @@ "valid": false } ] + }, + { + "description": "dependent subschema incompatible with root", + "schema": { + "properties": { + "foo": {} + }, + "dependencies": { + "foo": { + "properties": { + "bar": {} + }, + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "matches root", + "data": {"foo": 1}, + "valid": false + }, + { + "description": "matches dependency", + "data": {"bar": 1}, + "valid": true + }, + { + "description": "matches both", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "no dependency", + "data": {"baz": 1}, + "valid": true + } + ] } ] diff --git a/src/test/suite/tests/draft4/id.json b/src/test/suite/tests/draft4/id.json index c6c6fb542..d49133f74 100644 --- a/src/test/suite/tests/draft4/id.json +++ b/src/test/suite/tests/draft4/id.json @@ -7,32 +7,32 @@ "id_in_enum": { "enum": [ { - "id": "http://localhost:1234/id/my_identifier.json", + "id": "https://localhost:1234/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { - "id": "http://localhost:1234/id/my_identifier.json", + "id": "https://localhost:1234/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { - "id": "http://localhost:1234/id/my_identifier.json", + "id": "https://localhost:1234/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/definitions/id_in_enum" }, - { "$ref": "http://localhost:1234/id/my_identifier.json" } + { "$ref": "https://localhost:1234/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { - "id": "http://localhost:1234/id/my_identifier.json", + "id": "https://localhost:1234/my_identifier.json", "type": "null" }, "valid": true @@ -40,12 +40,16 @@ { "description": "match $ref to id", "data": "a string to match #/definitions/id_in_enum", - "valid": true + "valid": true, + "disabled": true, + "reason": "TODO: Dereferencing an id is conditional on the contxt" }, { "description": "no match on enum or $ref to id", "data": 1, - "valid": false + "valid": false, + "disabled": true, + "reason": "TODO: Dereferencing an id is conditional on the contxt" } ] } diff --git a/src/test/suite/tests/draft4/ref.json b/src/test/suite/tests/draft4/ref.json index b714fb0a1..b53bd2abe 100644 --- a/src/test/suite/tests/draft4/ref.json +++ b/src/test/suite/tests/draft4/ref.json @@ -503,5 +503,90 @@ "valid": false } ] + }, + { + "description": "id with file URI still resolves pointers - *nix", + "schema": { + "id": "file:///folder/file.json", + "definitions": { + "foo": { + "type": "number" + } + }, + "allOf": [ + { + "$ref": "#/definitions/foo" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "id with file URI still resolves pointers - windows", + "schema": { + "id": "file:///c:/folder/file.json", + "definitions": { + "foo": { + "type": "number" + } + }, + "allOf": [ + { + "$ref": "#/definitions/foo" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "empty tokens in $ref json-pointer", + "schema": { + "definitions": { + "": { + "definitions": { + "": { "type": "number" } + } + } + }, + "allOf": [ + { + "$ref": "#/definitions//definitions/" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] } ] diff --git a/src/test/suite/tests/draft4/uniqueItems.json b/src/test/suite/tests/draft4/uniqueItems.json index 2ccf666d7..d2730c60c 100644 --- a/src/test/suite/tests/draft4/uniqueItems.json +++ b/src/test/suite/tests/draft4/uniqueItems.json @@ -53,6 +53,11 @@ "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, + { + "description": "property order of array of objects is ignored", + "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], + "valid": false + }, { "description": "unique array of nested objects is valid", "data": [ diff --git a/src/test/suite/tests/draft6/dependencies.json b/src/test/suite/tests/draft6/dependencies.json index a5e54282c..c0bd809f6 100644 --- a/src/test/suite/tests/draft6/dependencies.json +++ b/src/test/suite/tests/draft6/dependencies.json @@ -244,5 +244,43 @@ "valid": false } ] + }, + { + "description": "dependent subschema incompatible with root", + "schema": { + "properties": { + "foo": {} + }, + "dependencies": { + "foo": { + "properties": { + "bar": {} + }, + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "matches root", + "data": {"foo": 1}, + "valid": false + }, + { + "description": "matches dependency", + "data": {"bar": 1}, + "valid": true + }, + { + "description": "matches both", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "no dependency", + "data": {"baz": 1}, + "valid": true + } + ] } ] diff --git a/src/test/suite/tests/draft6/id.json b/src/test/suite/tests/draft6/id.json index f40bb84d0..03d30fcb4 100644 --- a/src/test/suite/tests/draft6/id.json +++ b/src/test/suite/tests/draft6/id.json @@ -7,32 +7,32 @@ "id_in_enum": { "enum": [ { - "$id": "http://localhost:1234/id/my_identifier.json", + "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { - "$id": "http://localhost:1234/id/my_identifier.json", + "$id": "https://localhost:1234/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { - "$id": "http://localhost:1234/id/my_identifier.json", + "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/definitions/id_in_enum" }, - { "$ref": "http://localhost:1234/id/my_identifier.json" } + { "$ref": "https://localhost:1234/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { - "$id": "http://localhost:1234/id/my_identifier.json", + "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" }, "valid": true diff --git a/src/test/suite/tests/draft6/ref.json b/src/test/suite/tests/draft6/ref.json index 8a3659395..8a8908a44 100644 --- a/src/test/suite/tests/draft6/ref.json +++ b/src/test/suite/tests/draft6/ref.json @@ -813,5 +813,90 @@ "valid": false } ] + }, + { + "description": "$id with file URI still resolves pointers - *nix", + "schema": { + "$id": "file:///folder/file.json", + "definitions": { + "foo": { + "type": "number" + } + }, + "allOf": [ + { + "$ref": "#/definitions/foo" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "$id with file URI still resolves pointers - windows", + "schema": { + "$id": "file:///c:/folder/file.json", + "definitions": { + "foo": { + "type": "number" + } + }, + "allOf": [ + { + "$ref": "#/definitions/foo" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "empty tokens in $ref json-pointer", + "schema": { + "definitions": { + "": { + "definitions": { + "": { "type": "number" } + } + } + }, + "allOf": [ + { + "$ref": "#/definitions//definitions/" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] } ] diff --git a/src/test/suite/tests/draft6/uniqueItems.json b/src/test/suite/tests/draft6/uniqueItems.json index 2ccf666d7..d2730c60c 100644 --- a/src/test/suite/tests/draft6/uniqueItems.json +++ b/src/test/suite/tests/draft6/uniqueItems.json @@ -53,6 +53,11 @@ "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, + { + "description": "property order of array of objects is ignored", + "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], + "valid": false + }, { "description": "unique array of nested objects is valid", "data": [ diff --git a/src/test/suite/tests/draft6/unknownKeyword.json b/src/test/suite/tests/draft6/unknownKeyword.json index 71f12a172..1f58d97e3 100644 --- a/src/test/suite/tests/draft6/unknownKeyword.json +++ b/src/test/suite/tests/draft6/unknownKeyword.json @@ -8,21 +8,21 @@ "not": { "array_of_schemas": [ { - "$id": "http://localhost:1234/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { - "$id": "http://localhost:1234/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { - "$id": "http://localhost:1234/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "integer" } } @@ -32,7 +32,7 @@ "anyOf": [ { "$ref": "#/definitions/id_in_unknown0" }, { "$ref": "#/definitions/id_in_unknown1" }, - { "$ref": "http://localhost:1234/unknownKeyword/my_identifier.json" } + { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } ] }, "tests": [ diff --git a/src/test/suite/tests/draft7/dependencies.json b/src/test/suite/tests/draft7/dependencies.json index a5e54282c..c0bd809f6 100644 --- a/src/test/suite/tests/draft7/dependencies.json +++ b/src/test/suite/tests/draft7/dependencies.json @@ -244,5 +244,43 @@ "valid": false } ] + }, + { + "description": "dependent subschema incompatible with root", + "schema": { + "properties": { + "foo": {} + }, + "dependencies": { + "foo": { + "properties": { + "bar": {} + }, + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "matches root", + "data": {"foo": 1}, + "valid": false + }, + { + "description": "matches dependency", + "data": {"bar": 1}, + "valid": true + }, + { + "description": "matches both", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "no dependency", + "data": {"baz": 1}, + "valid": true + } + ] } ] diff --git a/src/test/suite/tests/draft7/id.json b/src/test/suite/tests/draft7/id.json index 5568d2376..6be81b8da 100644 --- a/src/test/suite/tests/draft7/id.json +++ b/src/test/suite/tests/draft7/id.json @@ -7,32 +7,32 @@ "id_in_enum": { "enum": [ { - "$id": "http://localhost:1234/id/my_identifier.json", + "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" } ] }, "real_id_in_schema": { - "$id": "http://localhost:1234/id/my_identifier.json", + "$id": "https://localhost:1234/id/my_identifier.json", "type": "string" }, "zzz_id_in_const": { "const": { - "$id": "http://localhost:1234/id/my_identifier.json", + "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" } } }, "anyOf": [ { "$ref": "#/definitions/id_in_enum" }, - { "$ref": "http://localhost:1234/id/my_identifier.json" } + { "$ref": "https://localhost:1234/id/my_identifier.json" } ] }, "tests": [ { "description": "exact match to enum, and type matches", "data": { - "$id": "http://localhost:1234/id/my_identifier.json", + "$id": "https://localhost:1234/id/my_identifier.json", "type": "null" }, "valid": true diff --git a/src/test/suite/tests/draft7/ref.json b/src/test/suite/tests/draft7/ref.json index 2bee83e3e..82631726e 100644 --- a/src/test/suite/tests/draft7/ref.json +++ b/src/test/suite/tests/draft7/ref.json @@ -927,5 +927,90 @@ "valid": false } ] + }, + { + "description": "$id with file URI still resolves pointers - *nix", + "schema": { + "$id": "file:///folder/file.json", + "definitions": { + "foo": { + "type": "number" + } + }, + "allOf": [ + { + "$ref": "#/definitions/foo" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "$id with file URI still resolves pointers - windows", + "schema": { + "$id": "file:///c:/folder/file.json", + "definitions": { + "foo": { + "type": "number" + } + }, + "allOf": [ + { + "$ref": "#/definitions/foo" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "empty tokens in $ref json-pointer", + "schema": { + "definitions": { + "": { + "definitions": { + "": { "type": "number" } + } + } + }, + "allOf": [ + { + "$ref": "#/definitions//definitions/" + } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "non-number is invalid", + "data": "a", + "valid": false + } + ] } ] diff --git a/src/test/suite/tests/draft7/uniqueItems.json b/src/test/suite/tests/draft7/uniqueItems.json index 2ccf666d7..d2730c60c 100644 --- a/src/test/suite/tests/draft7/uniqueItems.json +++ b/src/test/suite/tests/draft7/uniqueItems.json @@ -53,6 +53,11 @@ "data": [{"foo": "bar"}, {"foo": "bar"}], "valid": false }, + { + "description": "property order of array of objects is ignored", + "data": [{"foo": "bar", "bar": "foo"}, {"bar": "foo", "foo": "bar"}], + "valid": false + }, { "description": "unique array of nested objects is valid", "data": [ diff --git a/src/test/suite/tests/draft7/unknownKeyword.json b/src/test/suite/tests/draft7/unknownKeyword.json index 71f12a172..1f58d97e3 100644 --- a/src/test/suite/tests/draft7/unknownKeyword.json +++ b/src/test/suite/tests/draft7/unknownKeyword.json @@ -8,21 +8,21 @@ "not": { "array_of_schemas": [ { - "$id": "http://localhost:1234/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "null" } ] } }, "real_id_in_schema": { - "$id": "http://localhost:1234/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "string" }, "id_in_unknown1": { "not": { "object_of_schemas": { "foo": { - "$id": "http://localhost:1234/unknownKeyword/my_identifier.json", + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", "type": "integer" } } @@ -32,7 +32,7 @@ "anyOf": [ { "$ref": "#/definitions/id_in_unknown0" }, { "$ref": "#/definitions/id_in_unknown1" }, - { "$ref": "http://localhost:1234/unknownKeyword/my_identifier.json" } + { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } ] }, "tests": [ diff --git a/src/test/suite/tox.ini b/src/test/suite/tox.ini index 7ca9de988..dcc0dce6d 100644 --- a/src/test/suite/tox.ini +++ b/src/test/suite/tox.ini @@ -5,5 +5,5 @@ skipsdist = True [testenv:sanity] # used just for validating the structure of the test case files themselves -deps = jsonschema==4.17.3 +deps = jsonschema==4.18.0a4 commands = {envpython} bin/jsonschema_suite check