summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Berman <Julian@GrayVines.com>2023-03-14 17:22:00 -0400
committerJulian Berman <Julian@GrayVines.com>2023-03-14 17:22:00 -0400
commitf953e977ed555f3d0db1092d06def688a3db2b16 (patch)
tree484446b2e15b44c199ea9b636e0e8bddd504a6b6
parent1c286a15d01bc31fa42e1d09fcd850ceda6d6129 (diff)
parent5e16d74500493ef164b595daec622c4ba199644e (diff)
downloadjsonschema-f953e977ed555f3d0db1092d06def688a3db2b16.tar.gz
Merge commit '5e16d74500493ef164b595daec622c4ba199644e'
* commit '5e16d74500493ef164b595daec622c4ba199644e': Squashed 'json/' changes from f57d3e0cc..19947eaa1
-rw-r--r--json/README.md2
-rw-r--r--json/remotes/draft-next/metaschema-optional-vocabulary.json13
-rw-r--r--json/remotes/draft2019-09/metaschema-optional-vocabulary.json13
-rw-r--r--json/remotes/draft2020-12/metaschema-optional-vocabulary.json13
-rw-r--r--json/tests/draft-next/multipleOf.json14
-rw-r--r--json/tests/draft-next/not.json28
-rw-r--r--json/tests/draft-next/optional/format/time.json20
-rw-r--r--json/tests/draft-next/ref.json31
-rw-r--r--json/tests/draft-next/refRemote.json19
-rw-r--r--json/tests/draft-next/unevaluatedItems.json23
-rw-r--r--json/tests/draft-next/unevaluatedProperties.json22
-rw-r--r--json/tests/draft-next/vocabulary.json21
-rw-r--r--json/tests/draft2019-09/additionalItems.json24
-rw-r--r--json/tests/draft2019-09/multipleOf.json14
-rw-r--r--json/tests/draft2019-09/not.json28
-rw-r--r--json/tests/draft2019-09/optional/format/time.json20
-rw-r--r--json/tests/draft2019-09/ref.json31
-rw-r--r--json/tests/draft2019-09/refRemote.json19
-rw-r--r--json/tests/draft2019-09/unevaluatedItems.json44
-rw-r--r--json/tests/draft2019-09/unevaluatedProperties.json22
-rw-r--r--json/tests/draft2019-09/vocabulary.json21
-rw-r--r--json/tests/draft2020-12/dynamicRef.json38
-rw-r--r--json/tests/draft2020-12/multipleOf.json14
-rw-r--r--json/tests/draft2020-12/not.json28
-rw-r--r--json/tests/draft2020-12/optional/format/time.json20
-rw-r--r--json/tests/draft2020-12/ref.json29
-rw-r--r--json/tests/draft2020-12/refRemote.json19
-rw-r--r--json/tests/draft2020-12/unevaluatedItems.json23
-rw-r--r--json/tests/draft2020-12/unevaluatedProperties.json22
-rw-r--r--json/tests/draft2020-12/vocabulary.json19
-rw-r--r--json/tests/draft4/multipleOf.json11
-rw-r--r--json/tests/draft6/additionalItems.json23
-rw-r--r--json/tests/draft6/multipleOf.json11
-rw-r--r--json/tests/draft6/ref.json33
-rw-r--r--json/tests/draft7/additionalItems.json23
-rw-r--r--json/tests/draft7/multipleOf.json11
-rw-r--r--json/tests/draft7/optional/format/time.json20
-rw-r--r--json/tests/draft7/ref.json73
38 files changed, 833 insertions, 26 deletions
diff --git a/json/README.md b/json/README.md
index a0ccf11..36dda74 100644
--- a/json/README.md
+++ b/json/README.md
@@ -20,6 +20,8 @@ Drafts 04 and 03 are considered "frozen" in that less effort is put in to backpo
Additional coverage is always welcome, particularly for bugs encountered in real-world implementations.
If you see anything missing or incorrect, please feel free to [file an issue](https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues) or [submit a PR](https://github.com/json-schema-org/JSON-Schema-Test-Suite).
+@gregsdennis has also started a separate [test suite](https://github.com/gregsdennis/json-schema-vocab-test-suites) that is modelled after this suite to cover third-party vocabularies.
+
## Introduction to the Test Suite Structure
The tests in this suite are contained in the `tests` directory at the root of this repository.
diff --git a/json/remotes/draft-next/metaschema-optional-vocabulary.json b/json/remotes/draft-next/metaschema-optional-vocabulary.json
new file mode 100644
index 0000000..e78e531
--- /dev/null
+++ b/json/remotes/draft-next/metaschema-optional-vocabulary.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "https://json-schema.org/draft/next/schema",
+ "$id": "http://localhost:1234/draft-next/metaschema-optional-vocabulary.json",
+ "$vocabulary": {
+ "https://json-schema.org/draft/next/vocab/validation": true,
+ "https://json-schema.org/draft/next/vocab/core": true,
+ "http://localhost:1234/draft/next/vocab/custom": false
+ },
+ "allOf": [
+ { "$ref": "https://json-schema.org/draft/next/meta/validation" },
+ { "$ref": "https://json-schema.org/draft/next/meta/core" }
+ ]
+}
diff --git a/json/remotes/draft2019-09/metaschema-optional-vocabulary.json b/json/remotes/draft2019-09/metaschema-optional-vocabulary.json
new file mode 100644
index 0000000..968597c
--- /dev/null
+++ b/json/remotes/draft2019-09/metaschema-optional-vocabulary.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "$id": "http://localhost:1234/draft2019-09/metaschema-optional-vocabulary.json",
+ "$vocabulary": {
+ "https://json-schema.org/draft/2019-09/vocab/validation": true,
+ "https://json-schema.org/draft/2019-09/vocab/core": true,
+ "http://localhost:1234/draft/2019-09/vocab/custom": false
+ },
+ "allOf": [
+ { "$ref": "https://json-schema.org/draft/2019-09/meta/validation" },
+ { "$ref": "https://json-schema.org/draft/2019-09/meta/core" }
+ ]
+}
diff --git a/json/remotes/draft2020-12/metaschema-optional-vocabulary.json b/json/remotes/draft2020-12/metaschema-optional-vocabulary.json
new file mode 100644
index 0000000..f38ec28
--- /dev/null
+++ b/json/remotes/draft2020-12/metaschema-optional-vocabulary.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "http://localhost:1234/draft2020-12/metaschema-optional-vocabulary.json",
+ "$vocabulary": {
+ "https://json-schema.org/draft/2020-12/vocab/validation": true,
+ "https://json-schema.org/draft/2020-12/vocab/core": true,
+ "http://localhost:1234/draft/2020-12/vocab/custom": false
+ },
+ "allOf": [
+ { "$ref": "https://json-schema.org/draft/2020-12/meta/validation" },
+ { "$ref": "https://json-schema.org/draft/2020-12/meta/core" }
+ ]
+}
diff --git a/json/tests/draft-next/multipleOf.json b/json/tests/draft-next/multipleOf.json
index d640b3b..f153454 100644
--- a/json/tests/draft-next/multipleOf.json
+++ b/json/tests/draft-next/multipleOf.json
@@ -80,5 +80,19 @@
"valid": false
}
]
+ },
+ {
+ "description": "small multiple of large integer",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/next/schema",
+ "type": "integer", "multipleOf": 1e-8
+ },
+ "tests": [
+ {
+ "description": "any integer is a multiple of 1e-8",
+ "data": 12391239123,
+ "valid": true
+ }
+ ]
}
]
diff --git a/json/tests/draft-next/not.json b/json/tests/draft-next/not.json
index 9c9c3f2..b225104 100644
--- a/json/tests/draft-next/not.json
+++ b/json/tests/draft-next/not.json
@@ -123,5 +123,31 @@
"valid": true
}
]
- }
+ },
+ {
+ "description": "collect annotations inside a 'not', even if collection is disabled",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/next/schema",
+ "not": {
+ "$comment": "this subschema must still produce annotations internally, even though the 'not' will ultimately discard them",
+ "anyOf": [
+ true,
+ { "properties": { "foo": true } }
+ ],
+ "unevaluatedProperties": false
+ }
+ },
+ "tests": [
+ {
+ "description": "unevaluated property",
+ "data": { "bar": 1 },
+ "valid": true
+ },
+ {
+ "description": "annotations are still collected inside a 'not'",
+ "data": { "foo": 1 },
+ "valid": false
+ }
+ ]
+ }
]
diff --git a/json/tests/draft-next/optional/format/time.json b/json/tests/draft-next/optional/format/time.json
index bb58091..0a000a4 100644
--- a/json/tests/draft-next/optional/format/time.json
+++ b/json/tests/draft-next/optional/format/time.json
@@ -42,6 +42,21 @@
"valid": true
},
{
+ "description": "invalid time string with extra leading zeros",
+ "data": "008:030:006Z",
+ "valid": false
+ },
+ {
+ "description": "invalid time string with no leading zero for single digit",
+ "data": "8:3:6Z",
+ "valid": false
+ },
+ {
+ "description": "hour, minute, second must be two digits",
+ "data": "8:0030:6Z",
+ "valid": false
+ },
+ {
"description": "a valid time string with leap second, Zulu",
"data": "23:59:60Z",
"valid": true
@@ -132,6 +147,11 @@
"valid": true
},
{
+ "description": "hour, minute in time-offset must be two digits",
+ "data": "08:30:06-8:000",
+ "valid": false
+ },
+ {
"description": "a valid time string with case-insensitive Z",
"data": "08:30:06z",
"valid": true
diff --git a/json/tests/draft-next/ref.json b/json/tests/draft-next/ref.json
index 948e2b9..6457e8a 100644
--- a/json/tests/draft-next/ref.json
+++ b/json/tests/draft-next/ref.json
@@ -949,5 +949,34 @@
"valid": true
}
]
- }
+ },
+ {
+ "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
+ }
+ ]
+ }
]
diff --git a/json/tests/draft-next/refRemote.json b/json/tests/draft-next/refRemote.json
index ca5b8c4..3768b53 100644
--- a/json/tests/draft-next/refRemote.json
+++ b/json/tests/draft-next/refRemote.json
@@ -38,6 +38,25 @@
]
},
{
+ "description": "anchor within remote ref",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/next/schema",
+ "$ref": "http://localhost:1234/draft-next/locationIndependentIdentifier.json#foo"
+ },
+ "tests": [
+ {
+ "description": "remote anchor valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "remote anchor invalid",
+ "data": "a",
+ "valid": false
+ }
+ ]
+ },
+ {
"description": "ref within remote ref",
"schema": {
"$schema": "https://json-schema.org/draft/next/schema",
diff --git a/json/tests/draft-next/unevaluatedItems.json b/json/tests/draft-next/unevaluatedItems.json
index 9e0faef..ce5d043 100644
--- a/json/tests/draft-next/unevaluatedItems.json
+++ b/json/tests/draft-next/unevaluatedItems.json
@@ -99,7 +99,7 @@
]
},
{
- "description": "unevaluatedItems with items",
+ "description": "unevaluatedItems with items and prefixItems",
"schema": {
"$schema": "https://json-schema.org/draft/next/schema",
"prefixItems": [
@@ -117,6 +117,27 @@
]
},
{
+ "description": "unevaluatedItems with items",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/next/schema",
+ "items": {"type": "number"},
+ "unevaluatedItems": {"type": "string"}
+ },
+ "tests": [
+ {
+ "description": "valid under items",
+ "comment": "no elements are considered by unevaluatedItems",
+ "data": [5, 6, 7, 8],
+ "valid": true
+ },
+ {
+ "description": "invalid under items",
+ "data": ["foo", "bar", "baz"],
+ "valid": false
+ }
+ ]
+ },
+ {
"description": "unevaluatedItems with nested tuple",
"schema": {
"$schema": "https://json-schema.org/draft/next/schema",
diff --git a/json/tests/draft-next/unevaluatedProperties.json b/json/tests/draft-next/unevaluatedProperties.json
index 59c0e4e..f3d4012 100644
--- a/json/tests/draft-next/unevaluatedProperties.json
+++ b/json/tests/draft-next/unevaluatedProperties.json
@@ -1516,5 +1516,27 @@
"valid": false
}
]
+ },
+ {
+ "description": "unevaluatedProperties not affected by propertyNames",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/next/schema",
+ "propertyNames": {"maxLength": 1},
+ "unevaluatedProperties": {
+ "type": "number"
+ }
+ },
+ "tests": [
+ {
+ "description": "allows only number properties",
+ "data": {"a": 1},
+ "valid": true
+ },
+ {
+ "description": "string property is invalid",
+ "data": {"a": "b"},
+ "valid": false
+ }
+ ]
}
]
diff --git a/json/tests/draft-next/vocabulary.json b/json/tests/draft-next/vocabulary.json
index 65b81ea..f25b9e1 100644
--- a/json/tests/draft-next/vocabulary.json
+++ b/json/tests/draft-next/vocabulary.json
@@ -34,5 +34,24 @@
"valid": true
}
]
- }
+ },
+ {
+ "description": "ignore unrecognized optional vocabulary",
+ "schema": {
+ "$schema": "http://localhost:1234/draft-next/metaschema-optional-vocabulary.json",
+ "type": "number"
+ },
+ "tests": [
+ {
+ "description": "string value",
+ "data": "foobar",
+ "valid": false
+ },
+ {
+ "description": "number value",
+ "data": 20,
+ "valid": true
+ }
+ ]
+ }
]
diff --git a/json/tests/draft2019-09/additionalItems.json b/json/tests/draft2019-09/additionalItems.json
index ca91c0c..aa44bcb 100644
--- a/json/tests/draft2019-09/additionalItems.json
+++ b/json/tests/draft2019-09/additionalItems.json
@@ -22,6 +22,30 @@
{
"description": "when items is schema, additionalItems does nothing",
"schema": {
+ "$schema":"https://json-schema.org/draft/2019-09/schema",
+ "items": {
+ "type": "integer"
+ },
+ "additionalItems": {
+ "type": "string"
+ }
+ },
+ "tests": [
+ {
+ "description": "valid with a array of type integers",
+ "data": [1,2,3],
+ "valid": true
+ },
+ {
+ "description": "invalid with a array of mixed types",
+ "data": [1,"2","3"],
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "when items is schema, boolean additionalItems does nothing",
+ "schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"items": {},
"additionalItems": false
diff --git a/json/tests/draft2019-09/multipleOf.json b/json/tests/draft2019-09/multipleOf.json
index 94af169..760a434 100644
--- a/json/tests/draft2019-09/multipleOf.json
+++ b/json/tests/draft2019-09/multipleOf.json
@@ -79,5 +79,19 @@
"valid": false
}
]
+ },
+ {
+ "description": "small multiple of large integer",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "type": "integer", "multipleOf": 1e-8
+ },
+ "tests": [
+ {
+ "description": "any integer is a multiple of 1e-8",
+ "data": 12391239123,
+ "valid": true
+ }
+ ]
}
]
diff --git a/json/tests/draft2019-09/not.json b/json/tests/draft2019-09/not.json
index f76f763..62c9af9 100644
--- a/json/tests/draft2019-09/not.json
+++ b/json/tests/draft2019-09/not.json
@@ -123,5 +123,31 @@
"valid": true
}
]
- }
+ },
+ {
+ "description": "collect annotations inside a 'not', even if collection is disabled",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "not": {
+ "$comment": "this subschema must still produce annotations internally, even though the 'not' will ultimately discard them",
+ "anyOf": [
+ true,
+ { "properties": { "foo": true } }
+ ],
+ "unevaluatedProperties": false
+ }
+ },
+ "tests": [
+ {
+ "description": "unevaluated property",
+ "data": { "bar": 1 },
+ "valid": true
+ },
+ {
+ "description": "annotations are still collected inside a 'not'",
+ "data": { "foo": 1 },
+ "valid": false
+ }
+ ]
+ }
]
diff --git a/json/tests/draft2019-09/optional/format/time.json b/json/tests/draft2019-09/optional/format/time.json
index 3056376..dadaae6 100644
--- a/json/tests/draft2019-09/optional/format/time.json
+++ b/json/tests/draft2019-09/optional/format/time.json
@@ -42,6 +42,21 @@
"valid": true
},
{
+ "description": "invalid time string with extra leading zeros",
+ "data": "008:030:006Z",
+ "valid": false
+ },
+ {
+ "description": "invalid time string with no leading zero for single digit",
+ "data": "8:3:6Z",
+ "valid": false
+ },
+ {
+ "description": "hour, minute, second must be two digits",
+ "data": "8:0030:6Z",
+ "valid": false
+ },
+ {
"description": "a valid time string with leap second, Zulu",
"data": "23:59:60Z",
"valid": true
@@ -132,6 +147,11 @@
"valid": true
},
{
+ "description": "hour, minute in time-offset must be two digits",
+ "data": "08:30:06-8:000",
+ "valid": false
+ },
+ {
"description": "a valid time string with case-insensitive Z",
"data": "08:30:06z",
"valid": true
diff --git a/json/tests/draft2019-09/ref.json b/json/tests/draft2019-09/ref.json
index ac651ad..d420bd9 100644
--- a/json/tests/draft2019-09/ref.json
+++ b/json/tests/draft2019-09/ref.json
@@ -949,5 +949,34 @@
"valid": true
}
]
- }
+ },
+ {
+ "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
+ }
+ ]
+ }
]
diff --git a/json/tests/draft2019-09/refRemote.json b/json/tests/draft2019-09/refRemote.json
index 7f45b0b..79107f9 100644
--- a/json/tests/draft2019-09/refRemote.json
+++ b/json/tests/draft2019-09/refRemote.json
@@ -38,6 +38,25 @@
]
},
{
+ "description": "anchor within remote ref",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "$ref": "http://localhost:1234/draft2019-09/locationIndependentIdentifier.json#foo"
+ },
+ "tests": [
+ {
+ "description": "remote anchor valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "remote anchor invalid",
+ "data": "a",
+ "valid": false
+ }
+ ]
+ },
+ {
"description": "ref within remote ref",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
diff --git a/json/tests/draft2019-09/unevaluatedItems.json b/json/tests/draft2019-09/unevaluatedItems.json
index 55d33e2..a0b1f33 100644
--- a/json/tests/draft2019-09/unevaluatedItems.json
+++ b/json/tests/draft2019-09/unevaluatedItems.json
@@ -99,7 +99,7 @@
]
},
{
- "description": "unevaluatedItems with additionalItems",
+ "description": "unevaluatedItems with items and additionalItems",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"items": [
@@ -117,6 +117,48 @@
]
},
{
+ "description": "unevaluatedItems with ignored additionalItems",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "additionalItems": {"type": "number"},
+ "unevaluatedItems": {"type": "string"}
+ },
+ "tests": [
+ {
+ "description": "invalid under unevaluatedItems",
+ "comment": "additionalItems is entirely ignored when items isn't present, so all elements need to be valid against the unevaluatedItems schema",
+ "data": ["foo", 1],
+ "valid": false
+ },
+ {
+ "description": "all valid under unevaluatedItems",
+ "data": ["foo", "bar", "baz"],
+ "valid": true
+ }
+ ]
+ },
+ {
+ "description": "unevaluatedItems with ignored applicator additionalItems",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "allOf": [ { "additionalItems": { "type": "number" } } ],
+ "unevaluatedItems": {"type": "string"}
+ },
+ "tests": [
+ {
+ "description": "invalid under unevaluatedItems",
+ "comment": "additionalItems is entirely ignored when items isn't present, so all elements need to be valid against the unevaluatedItems schema",
+ "data": ["foo", 1],
+ "valid": false
+ },
+ {
+ "description": "all valid under unevaluatedItems",
+ "data": ["foo", "bar", "baz"],
+ "valid": true
+ }
+ ]
+ },
+ {
"description": "unevaluatedItems with nested tuple",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
diff --git a/json/tests/draft2019-09/unevaluatedProperties.json b/json/tests/draft2019-09/unevaluatedProperties.json
index 62960ea..fdb4ac9 100644
--- a/json/tests/draft2019-09/unevaluatedProperties.json
+++ b/json/tests/draft2019-09/unevaluatedProperties.json
@@ -1419,5 +1419,27 @@
"valid": true
}
]
+ },
+ {
+ "description": "unevaluatedProperties not affected by propertyNames",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2019-09/schema",
+ "propertyNames": {"maxLength": 1},
+ "unevaluatedProperties": {
+ "type": "number"
+ }
+ },
+ "tests": [
+ {
+ "description": "allows only number properties",
+ "data": {"a": 1},
+ "valid": true
+ },
+ {
+ "description": "string property is invalid",
+ "data": {"a": "b"},
+ "valid": false
+ }
+ ]
}
]
diff --git a/json/tests/draft2019-09/vocabulary.json b/json/tests/draft2019-09/vocabulary.json
index 982e673..98482b2 100644
--- a/json/tests/draft2019-09/vocabulary.json
+++ b/json/tests/draft2019-09/vocabulary.json
@@ -34,5 +34,24 @@
"valid": true
}
]
- }
+ },
+ {
+ "description": "ignore unrecognized optional vocabulary",
+ "schema": {
+ "$schema": "http://localhost:1234/draft2019-09/metaschema-optional-vocabulary.json",
+ "type": "number"
+ },
+ "tests": [
+ {
+ "description": "string value",
+ "data": "foobar",
+ "valid": false
+ },
+ {
+ "description": "number value",
+ "data": 20,
+ "valid": true
+ }
+ ]
+ }
]
diff --git a/json/tests/draft2020-12/dynamicRef.json b/json/tests/draft2020-12/dynamicRef.json
index 90d863c..0f6ed48 100644
--- a/json/tests/draft2020-12/dynamicRef.json
+++ b/json/tests/draft2020-12/dynamicRef.json
@@ -118,6 +118,44 @@
]
},
{
+ "description": "A $dynamicRef without anchor in fragment behaves identical to $ref",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://test.json-schema.org/dynamicRef-without-anchor/root",
+ "$ref": "list",
+ "$defs": {
+ "foo": {
+ "$dynamicAnchor": "items",
+ "type": "string"
+ },
+ "list": {
+ "$id": "list",
+ "type": "array",
+ "items": { "$dynamicRef": "#/$defs/items" },
+ "$defs": {
+ "items": {
+ "$comment": "This is only needed to satisfy the bookending requirement",
+ "$dynamicAnchor": "items",
+ "type": "number"
+ }
+ }
+ }
+ }
+ },
+ "tests": [
+ {
+ "description": "An array of strings is invalid",
+ "data": ["foo", "bar"],
+ "valid": false
+ },
+ {
+ "description": "An array of numbers is valid",
+ "data": [24, 42],
+ "valid": true
+ }
+ ]
+ },
+ {
"description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor does not affect dynamic scope resolution",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
diff --git a/json/tests/draft2020-12/multipleOf.json b/json/tests/draft2020-12/multipleOf.json
index e075558..92d6979 100644
--- a/json/tests/draft2020-12/multipleOf.json
+++ b/json/tests/draft2020-12/multipleOf.json
@@ -79,5 +79,19 @@
"valid": false
}
]
+ },
+ {
+ "description": "small multiple of large integer",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "type": "integer", "multipleOf": 1e-8
+ },
+ "tests": [
+ {
+ "description": "any integer is a multiple of 1e-8",
+ "data": 12391239123,
+ "valid": true
+ }
+ ]
}
]
diff --git a/json/tests/draft2020-12/not.json b/json/tests/draft2020-12/not.json
index 42a8218..57e45ba 100644
--- a/json/tests/draft2020-12/not.json
+++ b/json/tests/draft2020-12/not.json
@@ -123,5 +123,31 @@
"valid": true
}
]
- }
+ },
+ {
+ "description": "collect annotations inside a 'not', even if collection is disabled",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "not": {
+ "$comment": "this subschema must still produce annotations internally, even though the 'not' will ultimately discard them",
+ "anyOf": [
+ true,
+ { "properties": { "foo": true } }
+ ],
+ "unevaluatedProperties": false
+ }
+ },
+ "tests": [
+ {
+ "description": "unevaluated property",
+ "data": { "bar": 1 },
+ "valid": true
+ },
+ {
+ "description": "annotations are still collected inside a 'not'",
+ "data": { "foo": 1 },
+ "valid": false
+ }
+ ]
+ }
]
diff --git a/json/tests/draft2020-12/optional/format/time.json b/json/tests/draft2020-12/optional/format/time.json
index ae31d2c..8967932 100644
--- a/json/tests/draft2020-12/optional/format/time.json
+++ b/json/tests/draft2020-12/optional/format/time.json
@@ -42,6 +42,21 @@
"valid": true
},
{
+ "description": "invalid time string with extra leading zeros",
+ "data": "008:030:006Z",
+ "valid": false
+ },
+ {
+ "description": "invalid time string with no leading zero for single digit",
+ "data": "8:3:6Z",
+ "valid": false
+ },
+ {
+ "description": "hour, minute, second must be two digits",
+ "data": "8:0030:6Z",
+ "valid": false
+ },
+ {
"description": "a valid time string with leap second, Zulu",
"data": "23:59:60Z",
"valid": true
@@ -132,6 +147,11 @@
"valid": true
},
{
+ "description": "hour, minute in time-offset must be two digits",
+ "data": "08:30:06-8:000",
+ "valid": false
+ },
+ {
"description": "a valid time string with case-insensitive Z",
"data": "08:30:06z",
"valid": true
diff --git a/json/tests/draft2020-12/ref.json b/json/tests/draft2020-12/ref.json
index eb8bf96..72c593a 100644
--- a/json/tests/draft2020-12/ref.json
+++ b/json/tests/draft2020-12/ref.json
@@ -949,5 +949,34 @@
"valid": true
}
]
+ },
+ {
+ "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
+ }
+ ]
}
]
diff --git a/json/tests/draft2020-12/refRemote.json b/json/tests/draft2020-12/refRemote.json
index d3cc401..2d4f99e 100644
--- a/json/tests/draft2020-12/refRemote.json
+++ b/json/tests/draft2020-12/refRemote.json
@@ -38,6 +38,25 @@
]
},
{
+ "description": "anchor within remote ref",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$ref": "http://localhost:1234/draft2020-12/locationIndependentIdentifier.json#foo"
+ },
+ "tests": [
+ {
+ "description": "remote anchor valid",
+ "data": 1,
+ "valid": true
+ },
+ {
+ "description": "remote anchor invalid",
+ "data": "a",
+ "valid": false
+ }
+ ]
+ },
+ {
"description": "ref within remote ref",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
diff --git a/json/tests/draft2020-12/unevaluatedItems.json b/json/tests/draft2020-12/unevaluatedItems.json
index 4e9dc72..2b816af 100644
--- a/json/tests/draft2020-12/unevaluatedItems.json
+++ b/json/tests/draft2020-12/unevaluatedItems.json
@@ -99,7 +99,7 @@
]
},
{
- "description": "unevaluatedItems with items",
+ "description": "unevaluatedItems with items and prefixItems",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"prefixItems": [
@@ -117,6 +117,27 @@
]
},
{
+ "description": "unevaluatedItems with items",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "items": {"type": "number"},
+ "unevaluatedItems": {"type": "string"}
+ },
+ "tests": [
+ {
+ "description": "valid under items",
+ "comment": "no elements are considered by unevaluatedItems",
+ "data": [5, 6, 7, 8],
+ "valid": true
+ },
+ {
+ "description": "invalid under items",
+ "data": ["foo", "bar", "baz"],
+ "valid": false
+ }
+ ]
+ },
+ {
"description": "unevaluatedItems with nested tuple",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
diff --git a/json/tests/draft2020-12/unevaluatedProperties.json b/json/tests/draft2020-12/unevaluatedProperties.json
index 31bb691..00cb36c 100644
--- a/json/tests/draft2020-12/unevaluatedProperties.json
+++ b/json/tests/draft2020-12/unevaluatedProperties.json
@@ -1419,5 +1419,27 @@
"valid": true
}
]
+ },
+ {
+ "description": "unevaluatedProperties not affected by propertyNames",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "propertyNames": {"maxLength": 1},
+ "unevaluatedProperties": {
+ "type": "number"
+ }
+ },
+ "tests": [
+ {
+ "description": "allows only number properties",
+ "data": {"a": 1},
+ "valid": true
+ },
+ {
+ "description": "string property is invalid",
+ "data": {"a": "b"},
+ "valid": false
+ }
+ ]
}
]
diff --git a/json/tests/draft2020-12/vocabulary.json b/json/tests/draft2020-12/vocabulary.json
index d84f8f1..1acb96a 100644
--- a/json/tests/draft2020-12/vocabulary.json
+++ b/json/tests/draft2020-12/vocabulary.json
@@ -34,5 +34,24 @@
"valid": true
}
]
+ },
+ {
+ "description": "ignore unrecognized optional vocabulary",
+ "schema": {
+ "$schema": "http://localhost:1234/draft2020-12/metaschema-optional-vocabulary.json",
+ "type": "number"
+ },
+ "tests": [
+ {
+ "description": "string value",
+ "data": "foobar",
+ "valid": false
+ },
+ {
+ "description": "number value",
+ "data": 20,
+ "valid": true
+ }
+ ]
}
]
diff --git a/json/tests/draft4/multipleOf.json b/json/tests/draft4/multipleOf.json
index 9abeb97..ed2df4a 100644
--- a/json/tests/draft4/multipleOf.json
+++ b/json/tests/draft4/multipleOf.json
@@ -67,5 +67,16 @@
"valid": false
}
]
+ },
+ {
+ "description": "small multiple of large integer",
+ "schema": {"type": "integer", "multipleOf": 1e-8},
+ "tests": [
+ {
+ "description": "any integer is a multiple of 1e-8",
+ "data": 12391239123,
+ "valid": true
+ }
+ ]
}
]
diff --git a/json/tests/draft6/additionalItems.json b/json/tests/draft6/additionalItems.json
index deb44fd..cae7236 100644
--- a/json/tests/draft6/additionalItems.json
+++ b/json/tests/draft6/additionalItems.json
@@ -21,6 +21,29 @@
{
"description": "when items is schema, additionalItems does nothing",
"schema": {
+ "items": {
+ "type": "integer"
+ },
+ "additionalItems": {
+ "type": "string"
+ }
+ },
+ "tests": [
+ {
+ "description": "valid with a array of type integers",
+ "data": [1,2,3],
+ "valid": true
+ },
+ {
+ "description": "invalid with a array of mixed types",
+ "data": [1,"2","3"],
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "when items is schema, boolean additionalItems does nothing",
+ "schema": {
"items": {},
"additionalItems": false
},
diff --git a/json/tests/draft6/multipleOf.json b/json/tests/draft6/multipleOf.json
index 25c25a9..e606979 100644
--- a/json/tests/draft6/multipleOf.json
+++ b/json/tests/draft6/multipleOf.json
@@ -67,5 +67,16 @@
"valid": false
}
]
+ },
+ {
+ "description": "small multiple of large integer",
+ "schema": {"type": "integer", "multipleOf": 1e-8},
+ "tests": [
+ {
+ "description": "any integer is a multiple of 1e-8",
+ "data": 12391239123,
+ "valid": true
+ }
+ ]
}
]
diff --git a/json/tests/draft6/ref.json b/json/tests/draft6/ref.json
index 1724f81..8a36593 100644
--- a/json/tests/draft6/ref.json
+++ b/json/tests/draft6/ref.json
@@ -782,5 +782,36 @@
"valid": false
}
]
- }
+ },
+ {
+ "description": "ref with absolute-path-reference",
+ "schema": {
+ "$id": "http://example.com/ref/absref.json",
+ "definitions": {
+ "a": {
+ "$id": "http://example.com/ref/absref/foobar.json",
+ "type": "number"
+ },
+ "b": {
+ "$id": "http://example.com/absref/foobar.json",
+ "type": "string"
+ }
+ },
+ "allOf": [
+ { "$ref": "/absref/foobar.json" }
+ ]
+ },
+ "tests": [
+ {
+ "description": "a string is valid",
+ "data": "foo",
+ "valid": true
+ },
+ {
+ "description": "an integer is invalid",
+ "data": 12,
+ "valid": false
+ }
+ ]
+ }
]
diff --git a/json/tests/draft7/additionalItems.json b/json/tests/draft7/additionalItems.json
index deb44fd..cae7236 100644
--- a/json/tests/draft7/additionalItems.json
+++ b/json/tests/draft7/additionalItems.json
@@ -21,6 +21,29 @@
{
"description": "when items is schema, additionalItems does nothing",
"schema": {
+ "items": {
+ "type": "integer"
+ },
+ "additionalItems": {
+ "type": "string"
+ }
+ },
+ "tests": [
+ {
+ "description": "valid with a array of type integers",
+ "data": [1,2,3],
+ "valid": true
+ },
+ {
+ "description": "invalid with a array of mixed types",
+ "data": [1,"2","3"],
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "when items is schema, boolean additionalItems does nothing",
+ "schema": {
"items": {},
"additionalItems": false
},
diff --git a/json/tests/draft7/multipleOf.json b/json/tests/draft7/multipleOf.json
index 25c25a9..e606979 100644
--- a/json/tests/draft7/multipleOf.json
+++ b/json/tests/draft7/multipleOf.json
@@ -67,5 +67,16 @@
"valid": false
}
]
+ },
+ {
+ "description": "small multiple of large integer",
+ "schema": {"type": "integer", "multipleOf": 1e-8},
+ "tests": [
+ {
+ "description": "any integer is a multiple of 1e-8",
+ "data": 12391239123,
+ "valid": true
+ }
+ ]
}
]
diff --git a/json/tests/draft7/optional/format/time.json b/json/tests/draft7/optional/format/time.json
index 920db61..014ecd8 100644
--- a/json/tests/draft7/optional/format/time.json
+++ b/json/tests/draft7/optional/format/time.json
@@ -39,6 +39,21 @@
"valid": true
},
{
+ "description": "invalid time string with extra leading zeros",
+ "data": "008:030:006Z",
+ "valid": false
+ },
+ {
+ "description": "invalid time string with no leading zero for single digit",
+ "data": "8:3:6Z",
+ "valid": false
+ },
+ {
+ "description": "hour, minute, second must be two digits",
+ "data": "8:0030:6Z",
+ "valid": false
+ },
+ {
"description": "a valid time string with leap second, Zulu",
"data": "23:59:60Z",
"valid": true
@@ -129,6 +144,11 @@
"valid": true
},
{
+ "description": "hour, minute in time-offset must be two digits",
+ "data": "08:30:06-8:000",
+ "valid": false
+ },
+ {
"description": "a valid time string with case-insensitive Z",
"data": "08:30:06z",
"valid": true
diff --git a/json/tests/draft7/ref.json b/json/tests/draft7/ref.json
index c9daf8f..2bee83e 100644
--- a/json/tests/draft7/ref.json
+++ b/json/tests/draft7/ref.json
@@ -822,11 +822,15 @@
{
"description": "ref to if",
"schema": {
- "$ref": "http://example.com/ref/if",
- "if": {
- "$id": "http://example.com/ref/if",
- "type": "integer"
- }
+ "allOf": [
+ {"$ref": "http://example.com/ref/if"},
+ {
+ "if": {
+ "$id": "http://example.com/ref/if",
+ "type": "integer"
+ }
+ }
+ ]
},
"tests": [
{
@@ -844,11 +848,15 @@
{
"description": "ref to then",
"schema": {
- "$ref": "http://example.com/ref/then",
- "then": {
- "$id": "http://example.com/ref/then",
- "type": "integer"
- }
+ "allOf": [
+ {"$ref": "http://example.com/ref/then"},
+ {
+ "then": {
+ "$id": "http://example.com/ref/then",
+ "type": "integer"
+ }
+ }
+ ]
},
"tests": [
{
@@ -866,11 +874,15 @@
{
"description": "ref to else",
"schema": {
- "$ref": "http://example.com/ref/else",
- "else": {
- "$id": "http://example.com/ref/else",
- "type": "integer"
- }
+ "allOf": [
+ {"$ref": "http://example.com/ref/else"},
+ {
+ "else": {
+ "$id": "http://example.com/ref/else",
+ "type": "integer"
+ }
+ }
+ ]
},
"tests": [
{
@@ -884,5 +896,36 @@
"valid": true
}
]
+ },
+ {
+ "description": "ref with absolute-path-reference",
+ "schema": {
+ "$id": "http://example.com/ref/absref.json",
+ "definitions": {
+ "a": {
+ "$id": "http://example.com/ref/absref/foobar.json",
+ "type": "number"
+ },
+ "b": {
+ "$id": "http://example.com/absref/foobar.json",
+ "type": "string"
+ }
+ },
+ "allOf": [
+ { "$ref": "/absref/foobar.json" }
+ ]
+ },
+ "tests": [
+ {
+ "description": "a string is valid",
+ "data": "foo",
+ "valid": true
+ },
+ {
+ "description": "an integer is invalid",
+ "data": 12,
+ "valid": false
+ }
+ ]
}
]