blob: 22b47e749d894a9197cd12081d14d3c09f133f1a [file] [log] [blame] [edit]
[
{
"description": "$recursiveRef without $recursiveAnchor works like $ref",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"properties": {
"foo": { "$recursiveRef": "#" }
},
"additionalProperties": false
},
"tests": [
{
"description": "match",
"data": {"foo": false},
"valid": true
},
{
"description": "recursive match",
"data": { "foo": { "foo": false } },
"valid": true
},
{
"description": "mismatch",
"data": { "bar": false },
"valid": false
},
{
"description": "recursive mismatch",
"data": { "foo": { "bar": false } },
"valid": false
}
]
},
{
"description": "$recursiveRef without using nesting",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "http://localhost:4242/draft2019-09/recursiveRef2/schema.json",
"$defs": {
"myobject": {
"$id": "myobject.json",
"$recursiveAnchor": true,
"anyOf": [
{ "type": "string" },
{
"type": "object",
"additionalProperties": { "$recursiveRef": "#" }
}
]
}
},
"anyOf": [
{ "type": "integer" },
{ "$ref": "#/$defs/myobject" }
]
},
"tests": [
{
"description": "integer matches at the outer level",
"data": 1,
"valid": true
},
{
"description": "single level match",
"data": { "foo": "hi" },
"valid": true
},
{
"description": "integer does not match as a property value",
"data": { "foo": 1 },
"valid": false
},
{
"description": "two levels, properties match with inner definition",
"data": { "foo": { "bar": "hi" } },
"valid": true
},
{
"description": "two levels, no match",
"data": { "foo": { "bar": 1 } },
"valid": false
}
]
},
{
"description": "$recursiveRef with nesting",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "http://localhost:4242/draft2019-09/recursiveRef3/schema.json",
"$recursiveAnchor": true,
"$defs": {
"myobject": {
"$id": "myobject.json",
"$recursiveAnchor": true,
"anyOf": [
{ "type": "string" },
{
"type": "object",
"additionalProperties": { "$recursiveRef": "#" }
}
]
}
},
"anyOf": [
{ "type": "integer" },
{ "$ref": "#/$defs/myobject" }
]
},
"tests": [
{
"description": "integer matches at the outer level",
"data": 1,
"valid": true
},
{
"description": "single level match",
"data": { "foo": "hi" },
"valid": true
},
{
"description": "integer now matches as a property value",
"data": { "foo": 1 },
"valid": true
},
{
"description": "two levels, properties match with inner definition",
"data": { "foo": { "bar": "hi" } },
"valid": true
},
{
"description": "two levels, properties match with $recursiveRef",
"data": { "foo": { "bar": 1 } },
"valid": true
}
]
},
{
"description": "$recursiveRef with $recursiveAnchor: false works like $ref",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "http://localhost:4242/draft2019-09/recursiveRef4/schema.json",
"$recursiveAnchor": false,
"$defs": {
"myobject": {
"$id": "myobject.json",
"$recursiveAnchor": false,
"anyOf": [
{ "type": "string" },
{
"type": "object",
"additionalProperties": { "$recursiveRef": "#" }
}
]
}
},
"anyOf": [
{ "type": "integer" },
{ "$ref": "#/$defs/myobject" }
]
},
"tests": [
{
"description": "integer matches at the outer level",
"data": 1,
"valid": true
},
{
"description": "single level match",
"data": { "foo": "hi" },
"valid": true
},
{
"description": "integer does not match as a property value",
"data": { "foo": 1 },
"valid": false
},
{
"description": "two levels, properties match with inner definition",
"data": { "foo": { "bar": "hi" } },
"valid": true
},
{
"description": "two levels, integer does not match as a property value",
"data": { "foo": { "bar": 1 } },
"valid": false
}
]
},
{
"description": "$recursiveRef with no $recursiveAnchor works like $ref",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "http://localhost:4242/draft2019-09/recursiveRef5/schema.json",
"$defs": {
"myobject": {
"$id": "myobject.json",
"$recursiveAnchor": false,
"anyOf": [
{ "type": "string" },
{
"type": "object",
"additionalProperties": { "$recursiveRef": "#" }
}
]
}
},
"anyOf": [
{ "type": "integer" },
{ "$ref": "#/$defs/myobject" }
]
},
"tests": [
{
"description": "integer matches at the outer level",
"data": 1,
"valid": true
},
{
"description": "single level match",
"data": { "foo": "hi" },
"valid": true
},
{
"description": "integer does not match as a property value",
"data": { "foo": 1 },
"valid": false
},
{
"description": "two levels, properties match with inner definition",
"data": { "foo": { "bar": "hi" } },
"valid": true
},
{
"description": "two levels, integer does not match as a property value",
"data": { "foo": { "bar": 1 } },
"valid": false
}
]
},
{
"description": "$recursiveRef with no $recursiveAnchor in the initial target schema resource",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "http://localhost:4242/draft2019-09/recursiveRef6/base.json",
"$recursiveAnchor": true,
"anyOf": [
{ "type": "boolean" },
{
"type": "object",
"additionalProperties": {
"$id": "http://localhost:4242/draft2019-09/recursiveRef6/inner.json",
"$comment": "there is no $recursiveAnchor: true here, so we do NOT recurse to the base",
"anyOf": [
{ "type": "integer" },
{ "type": "object", "additionalProperties": { "$recursiveRef": "#" } }
]
}
}
]
},
"tests": [
{
"description": "leaf node does not match; no recursion",
"data": { "foo": true },
"valid": false
},
{
"description": "leaf node matches: recursion uses the inner schema",
"data": { "foo": { "bar": 1 } },
"valid": true
},
{
"description": "leaf node does not match: recursion uses the inner schema",
"data": { "foo": { "bar": true } },
"valid": false
}
]
},
{
"description": "$recursiveRef with no $recursiveAnchor in the outer schema resource",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "http://localhost:4242/draft2019-09/recursiveRef7/base.json",
"anyOf": [
{ "type": "boolean" },
{
"type": "object",
"additionalProperties": {
"$id": "http://localhost:4242/draft2019-09/recursiveRef7/inner.json",
"$recursiveAnchor": true,
"anyOf": [
{ "type": "integer" },
{ "type": "object", "additionalProperties": { "$recursiveRef": "#" } }
]
}
}
]
},
"tests": [
{
"description": "leaf node does not match; no recursion",
"data": { "foo": true },
"valid": false
},
{
"description": "leaf node matches: recursion only uses inner schema",
"data": { "foo": { "bar": 1 } },
"valid": true
},
{
"description": "leaf node does not match: recursion only uses inner schema",
"data": { "foo": { "bar": true } },
"valid": false
}
]
},
{
"description": "multiple dynamic paths to the $recursiveRef keyword",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "https://example.com/recursiveRef8_main.json",
"$defs": {
"inner": {
"$id": "recursiveRef8_inner.json",
"$recursiveAnchor": true,
"title": "inner",
"additionalProperties": {
"$recursiveRef": "#"
}
}
},
"if": {
"propertyNames": {
"pattern": "^[a-m]"
}
},
"then": {
"title": "any type of node",
"$id": "recursiveRef8_anyLeafNode.json",
"$recursiveAnchor": true,
"$ref": "recursiveRef8_inner.json"
},
"else": {
"title": "integer node",
"$id": "recursiveRef8_integerNode.json",
"$recursiveAnchor": true,
"type": [ "object", "integer" ],
"$ref": "recursiveRef8_inner.json"
}
},
"tests": [
{
"description": "recurse to anyLeafNode - floats are allowed",
"data": { "alpha": 1.1 },
"valid": true
},
{
"description": "recurse to integerNode - floats are not allowed",
"data": { "november": 1.1 },
"valid": false
}
]
},
{
"description": "dynamic $recursiveRef destination (not predictable at schema compile time)",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "https://example.com/main.json",
"$defs": {
"inner": {
"$id": "inner.json",
"$recursiveAnchor": true,
"title": "inner",
"additionalProperties": {
"$recursiveRef": "#"
}
}
},
"if": { "propertyNames": { "pattern": "^[a-m]" } },
"then": {
"title": "any type of node",
"$id": "anyLeafNode.json",
"$recursiveAnchor": true,
"$ref": "main.json#/$defs/inner"
},
"else": {
"title": "integer node",
"$id": "integerNode.json",
"$recursiveAnchor": true,
"type": [ "object", "integer" ],
"$ref": "main.json#/$defs/inner"
}
},
"tests": [
{
"description": "numeric node",
"data": { "alpha": 1.1 },
"valid": true
},
{
"description": "integer node",
"data": { "november": 1.1 },
"valid": false
}
]
}
]