xref: /aosp_15_r20/external/json-schema-validator/src/test/suite/tests/draft2019-09/recursiveRef.json (revision 78c4dd6aa35290980cdcd1623a7e337e8d021c7c)
1[
2    {
3        "description": "$recursiveRef without $recursiveAnchor works like $ref",
4        "schema": {
5            "$schema": "https://json-schema.org/draft/2019-09/schema",
6            "properties": {
7                "foo": { "$recursiveRef": "#" }
8            },
9            "additionalProperties": false
10        },
11        "tests": [
12            {
13                "description": "match",
14                "data": {"foo": false},
15                "valid": true
16            },
17            {
18                "description": "recursive match",
19                "data": { "foo": { "foo": false } },
20                "valid": true
21            },
22            {
23                "description": "mismatch",
24                "data": { "bar": false },
25                "valid": false
26            },
27            {
28                "description": "recursive mismatch",
29                "data": { "foo": { "bar": false } },
30                "valid": false
31            }
32        ]
33    },
34    {
35        "description": "$recursiveRef without using nesting",
36        "schema": {
37            "$schema": "https://json-schema.org/draft/2019-09/schema",
38            "$id": "http://localhost:4242/draft2019-09/recursiveRef2/schema.json",
39            "$defs": {
40                "myobject": {
41                    "$id": "myobject.json",
42                    "$recursiveAnchor": true,
43                    "anyOf": [
44                        { "type": "string" },
45                        {
46                            "type": "object",
47                            "additionalProperties": { "$recursiveRef": "#" }
48                        }
49                    ]
50                }
51            },
52            "anyOf": [
53                { "type": "integer" },
54                { "$ref": "#/$defs/myobject" }
55            ]
56        },
57        "tests": [
58            {
59                "description": "integer matches at the outer level",
60                "data": 1,
61                "valid": true
62            },
63            {
64                "description": "single level match",
65                "data": { "foo": "hi" },
66                "valid": true
67            },
68            {
69                "description": "integer does not match as a property value",
70                "data": { "foo": 1 },
71                "valid": false
72            },
73            {
74                "description": "two levels, properties match with inner definition",
75                "data": { "foo": { "bar": "hi" } },
76                "valid": true
77            },
78            {
79                "description": "two levels, no match",
80                "data": { "foo": { "bar": 1 } },
81                "valid": false
82            }
83        ]
84    },
85    {
86        "description": "$recursiveRef with nesting",
87        "schema": {
88            "$schema": "https://json-schema.org/draft/2019-09/schema",
89            "$id": "http://localhost:4242/draft2019-09/recursiveRef3/schema.json",
90            "$recursiveAnchor": true,
91            "$defs": {
92                "myobject": {
93                    "$id": "myobject.json",
94                    "$recursiveAnchor": true,
95                    "anyOf": [
96                        { "type": "string" },
97                        {
98                            "type": "object",
99                            "additionalProperties": { "$recursiveRef": "#" }
100                        }
101                    ]
102                }
103            },
104            "anyOf": [
105                { "type": "integer" },
106                { "$ref": "#/$defs/myobject" }
107            ]
108        },
109        "tests": [
110            {
111                "description": "integer matches at the outer level",
112                "data": 1,
113                "valid": true
114            },
115            {
116                "description": "single level match",
117                "data": { "foo": "hi" },
118                "valid": true
119            },
120            {
121                "description": "integer now matches as a property value",
122                "data": { "foo": 1 },
123                "valid": true
124            },
125            {
126                "description": "two levels, properties match with inner definition",
127                "data": { "foo": { "bar": "hi" } },
128                "valid": true
129            },
130            {
131                "description": "two levels, properties match with $recursiveRef",
132                "data": { "foo": { "bar": 1 } },
133                "valid": true
134            }
135        ]
136    },
137    {
138        "description": "$recursiveRef with $recursiveAnchor: false works like $ref",
139        "schema": {
140            "$schema": "https://json-schema.org/draft/2019-09/schema",
141            "$id": "http://localhost:4242/draft2019-09/recursiveRef4/schema.json",
142            "$recursiveAnchor": false,
143            "$defs": {
144                "myobject": {
145                    "$id": "myobject.json",
146                    "$recursiveAnchor": false,
147                    "anyOf": [
148                        { "type": "string" },
149                        {
150                            "type": "object",
151                            "additionalProperties": { "$recursiveRef": "#" }
152                        }
153                    ]
154                }
155            },
156            "anyOf": [
157                { "type": "integer" },
158                { "$ref": "#/$defs/myobject" }
159            ]
160        },
161        "tests": [
162            {
163                "description": "integer matches at the outer level",
164                "data": 1,
165                "valid": true
166            },
167            {
168                "description": "single level match",
169                "data": { "foo": "hi" },
170                "valid": true
171            },
172            {
173                "description": "integer does not match as a property value",
174                "data": { "foo": 1 },
175                "valid": false
176            },
177            {
178                "description": "two levels, properties match with inner definition",
179                "data": { "foo": { "bar": "hi" } },
180                "valid": true
181            },
182            {
183                "description": "two levels, integer does not match as a property value",
184                "data": { "foo": { "bar": 1 } },
185                "valid": false
186            }
187        ]
188    },
189    {
190        "description": "$recursiveRef with no $recursiveAnchor works like $ref",
191        "schema": {
192            "$schema": "https://json-schema.org/draft/2019-09/schema",
193            "$id": "http://localhost:4242/draft2019-09/recursiveRef5/schema.json",
194            "$defs": {
195                "myobject": {
196                    "$id": "myobject.json",
197                    "$recursiveAnchor": false,
198                    "anyOf": [
199                        { "type": "string" },
200                        {
201                            "type": "object",
202                            "additionalProperties": { "$recursiveRef": "#" }
203                        }
204                    ]
205                }
206            },
207            "anyOf": [
208                { "type": "integer" },
209                { "$ref": "#/$defs/myobject" }
210            ]
211        },
212        "tests": [
213            {
214                "description": "integer matches at the outer level",
215                "data": 1,
216                "valid": true
217            },
218            {
219                "description": "single level match",
220                "data": { "foo": "hi" },
221                "valid": true
222            },
223            {
224                "description": "integer does not match as a property value",
225                "data": { "foo": 1 },
226                "valid": false
227            },
228            {
229                "description": "two levels, properties match with inner definition",
230                "data": { "foo": { "bar": "hi" } },
231                "valid": true
232            },
233            {
234                "description": "two levels, integer does not match as a property value",
235                "data": { "foo": { "bar": 1 } },
236                "valid": false
237            }
238        ]
239    },
240    {
241        "description": "$recursiveRef with no $recursiveAnchor in the initial target schema resource",
242        "schema": {
243            "$schema": "https://json-schema.org/draft/2019-09/schema",
244            "$id": "http://localhost:4242/draft2019-09/recursiveRef6/base.json",
245            "$recursiveAnchor": true,
246            "anyOf": [
247                { "type": "boolean" },
248                {
249                    "type": "object",
250                    "additionalProperties": {
251                        "$id": "http://localhost:4242/draft2019-09/recursiveRef6/inner.json",
252                        "$comment": "there is no $recursiveAnchor: true here, so we do NOT recurse to the base",
253                        "anyOf": [
254                            { "type": "integer" },
255                            { "type": "object", "additionalProperties": { "$recursiveRef": "#" } }
256                        ]
257                    }
258                }
259            ]
260        },
261        "tests": [
262            {
263                "description": "leaf node does not match; no recursion",
264                "data": { "foo": true },
265                "valid": false
266            },
267            {
268                "description": "leaf node matches: recursion uses the inner schema",
269                "data": { "foo": { "bar": 1 } },
270                "valid": true
271            },
272            {
273                "description": "leaf node does not match: recursion uses the inner schema",
274                "data": { "foo": { "bar": true } },
275                "valid": false
276            }
277        ]
278    },
279    {
280        "description": "$recursiveRef with no $recursiveAnchor in the outer schema resource",
281        "schema": {
282            "$schema": "https://json-schema.org/draft/2019-09/schema",
283            "$id": "http://localhost:4242/draft2019-09/recursiveRef7/base.json",
284            "anyOf": [
285                { "type": "boolean" },
286                {
287                    "type": "object",
288                    "additionalProperties": {
289                        "$id": "http://localhost:4242/draft2019-09/recursiveRef7/inner.json",
290                        "$recursiveAnchor": true,
291                        "anyOf": [
292                            { "type": "integer" },
293                            { "type": "object", "additionalProperties": { "$recursiveRef": "#" } }
294                        ]
295                    }
296                }
297            ]
298        },
299        "tests": [
300            {
301                "description": "leaf node does not match; no recursion",
302                "data": { "foo": true },
303                "valid": false
304            },
305            {
306                "description": "leaf node matches: recursion only uses inner schema",
307                "data": { "foo": { "bar": 1 } },
308                "valid": true
309            },
310            {
311                "description": "leaf node does not match: recursion only uses inner schema",
312                "data": { "foo": { "bar": true } },
313                "valid": false
314            }
315        ]
316    },
317    {
318        "description": "multiple dynamic paths to the $recursiveRef keyword",
319        "schema": {
320            "$schema": "https://json-schema.org/draft/2019-09/schema",
321            "$id": "https://example.com/recursiveRef8_main.json",
322            "$defs": {
323                "inner": {
324                    "$id": "recursiveRef8_inner.json",
325                    "$recursiveAnchor": true,
326                    "title": "inner",
327                    "additionalProperties": {
328                        "$recursiveRef": "#"
329                    }
330                }
331            },
332            "if": {
333                "propertyNames": {
334                    "pattern": "^[a-m]"
335                }
336            },
337            "then": {
338                "title": "any type of node",
339                "$id": "recursiveRef8_anyLeafNode.json",
340                "$recursiveAnchor": true,
341                "$ref": "recursiveRef8_inner.json"
342            },
343            "else": {
344                "title": "integer node",
345                "$id": "recursiveRef8_integerNode.json",
346                "$recursiveAnchor": true,
347                "type": [ "object", "integer" ],
348                "$ref": "recursiveRef8_inner.json"
349            }
350        },
351        "tests": [
352            {
353                "description": "recurse to anyLeafNode - floats are allowed",
354                "data": { "alpha": 1.1 },
355                "valid": true
356            },
357            {
358                "description": "recurse to integerNode - floats are not allowed",
359                "data": { "november": 1.1 },
360                "valid": false
361            }
362        ]
363    },
364    {
365        "description": "dynamic $recursiveRef destination (not predictable at schema compile time)",
366        "schema": {
367            "$schema": "https://json-schema.org/draft/2019-09/schema",
368            "$id": "https://example.com/main.json",
369            "$defs": {
370                "inner": {
371                    "$id": "inner.json",
372                    "$recursiveAnchor": true,
373                    "title": "inner",
374                    "additionalProperties": {
375                        "$recursiveRef": "#"
376                    }
377                }
378
379            },
380            "if": { "propertyNames": { "pattern": "^[a-m]" } },
381            "then": {
382                "title": "any type of node",
383                "$id": "anyLeafNode.json",
384                "$recursiveAnchor": true,
385                "$ref": "main.json#/$defs/inner"
386            },
387            "else": {
388                "title": "integer node",
389                "$id": "integerNode.json",
390                "$recursiveAnchor": true,
391                "type": [ "object", "integer" ],
392                "$ref": "main.json#/$defs/inner"
393            }
394        },
395        "tests": [
396            {
397                "description": "numeric node",
398                "data": { "alpha": 1.1 },
399                "valid": true
400            },
401            {
402                "description": "integer node",
403                "data": { "november": 1.1 },
404                "valid": false
405            }
406        ]
407    }
408]
409