[
    {
        "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
            }
        ]
    }
]
