xref: /aosp_15_r20/external/json-schema-validator/src/test/suite/tests/draft2020-12/dynamicRef.json (revision 78c4dd6aa35290980cdcd1623a7e337e8d021c7c)
1[
2    {
3        "description": "A $dynamicRef to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor",
4        "schema": {
5            "$schema": "https://json-schema.org/draft/2020-12/schema",
6            "$id": "https://test.json-schema.org/dynamicRef-dynamicAnchor-same-schema/root",
7            "type": "array",
8            "items": { "$dynamicRef": "#items" },
9            "$defs": {
10                "foo": {
11                    "$dynamicAnchor": "items",
12                    "type": "string"
13                }
14            }
15        },
16        "tests": [
17            {
18                "description": "An array of strings is valid",
19                "data": ["foo", "bar"],
20                "valid": true
21            },
22            {
23                "description": "An array containing non-strings is invalid",
24                "data": ["foo", 42],
25                "valid": false
26            }
27        ]
28    },
29    {
30        "description": "A $dynamicRef to an $anchor in the same schema resource behaves like a normal $ref to an $anchor",
31        "schema": {
32            "$schema": "https://json-schema.org/draft/2020-12/schema",
33            "$id": "https://test.json-schema.org/dynamicRef-anchor-same-schema/root",
34            "type": "array",
35            "items": { "$dynamicRef": "#items" },
36            "$defs": {
37                "foo": {
38                    "$anchor": "items",
39                    "type": "string"
40                }
41            }
42        },
43        "tests": [
44            {
45                "description": "An array of strings is valid",
46                "data": ["foo", "bar"],
47                "valid": true
48            },
49            {
50                "description": "An array containing non-strings is invalid",
51                "data": ["foo", 42],
52                "valid": false
53            }
54        ]
55    },
56    {
57        "description": "A $ref to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor",
58        "schema": {
59            "$schema": "https://json-schema.org/draft/2020-12/schema",
60            "$id": "https://test.json-schema.org/ref-dynamicAnchor-same-schema/root",
61            "type": "array",
62            "items": { "$ref": "#items" },
63            "$defs": {
64                "foo": {
65                    "$dynamicAnchor": "items",
66                    "type": "string"
67                }
68            }
69        },
70        "tests": [
71            {
72                "description": "An array of strings is valid",
73                "data": ["foo", "bar"],
74                "valid": true
75            },
76            {
77                "description": "An array containing non-strings is invalid",
78                "data": ["foo", 42],
79                "valid": false
80            }
81        ]
82    },
83    {
84        "description": "A $dynamicRef resolves to the first $dynamicAnchor still in scope that is encountered when the schema is evaluated",
85        "schema": {
86            "$schema": "https://json-schema.org/draft/2020-12/schema",
87            "$id": "https://test.json-schema.org/typical-dynamic-resolution/root",
88            "$ref": "list",
89            "$defs": {
90                "foo": {
91                    "$dynamicAnchor": "items",
92                    "type": "string"
93                },
94                "list": {
95                    "$id": "list",
96                    "type": "array",
97                    "items": { "$dynamicRef": "#items" },
98                    "$defs": {
99                      "items": {
100                          "$comment": "This is only needed to satisfy the bookending requirement",
101                          "$dynamicAnchor": "items"
102                      }
103                    }
104                }
105            }
106        },
107        "tests": [
108            {
109                "description": "An array of strings is valid",
110                "data": ["foo", "bar"],
111                "valid": true
112            },
113            {
114                "description": "An array containing non-strings is invalid",
115                "data": ["foo", 42],
116                "valid": false
117            }
118        ]
119    },
120    {
121        "description": "A $dynamicRef without anchor in fragment behaves identical to $ref",
122        "schema": {
123            "$schema": "https://json-schema.org/draft/2020-12/schema",
124            "$id": "https://test.json-schema.org/dynamicRef-without-anchor/root",
125            "$ref": "list",
126            "$defs": {
127                "foo": {
128                    "$dynamicAnchor": "items",
129                    "type": "string"
130                },
131                "list": {
132                    "$id": "list",
133                    "type": "array",
134                    "items": { "$dynamicRef": "#/$defs/items" },
135                    "$defs": {
136                      "items": {
137                          "$comment": "This is only needed to satisfy the bookending requirement",
138                          "$dynamicAnchor": "items",
139                          "type": "number"
140                      }
141                    }
142                }
143            }
144        },
145        "tests": [
146            {
147                "description": "An array of strings is invalid",
148                "data": ["foo", "bar"],
149                "valid": false
150            },
151            {
152                "description": "An array of numbers is valid",
153                "data": [24, 42],
154                "valid": true
155            }
156        ]
157    },
158    {
159        "description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor does not affect dynamic scope resolution",
160        "schema": {
161            "$schema": "https://json-schema.org/draft/2020-12/schema",
162            "$id": "https://test.json-schema.org/dynamic-resolution-with-intermediate-scopes/root",
163            "$ref": "intermediate-scope",
164            "$defs": {
165                "foo": {
166                    "$dynamicAnchor": "items",
167                    "type": "string"
168                },
169                "intermediate-scope": {
170                    "$id": "intermediate-scope",
171                    "$ref": "list"
172                },
173                "list": {
174                    "$id": "list",
175                    "type": "array",
176                    "items": { "$dynamicRef": "#items" },
177                    "$defs": {
178                      "items": {
179                          "$comment": "This is only needed to satisfy the bookending requirement",
180                          "$dynamicAnchor": "items"
181                      }
182                    }
183                }
184            }
185        },
186        "tests": [
187            {
188                "description": "An array of strings is valid",
189                "data": ["foo", "bar"],
190                "valid": true
191            },
192            {
193                "description": "An array containing non-strings is invalid",
194                "data": ["foo", 42],
195                "valid": false
196            }
197        ]
198    },
199    {
200        "description": "An $anchor with the same name as a $dynamicAnchor is not used for dynamic scope resolution",
201        "schema": {
202            "$schema": "https://json-schema.org/draft/2020-12/schema",
203            "$id": "https://test.json-schema.org/dynamic-resolution-ignores-anchors/root",
204            "$ref": "list",
205            "$defs": {
206                "foo": {
207                    "$anchor": "items",
208                    "type": "string"
209                },
210                "list": {
211                    "$id": "list",
212                    "type": "array",
213                    "items": { "$dynamicRef": "#items" },
214                    "$defs": {
215                      "items": {
216                          "$comment": "This is only needed to satisfy the bookending requirement",
217                          "$dynamicAnchor": "items"
218                      }
219                    }
220                }
221            }
222        },
223        "tests": [
224            {
225                "description": "Any array is valid",
226                "data": ["foo", 42],
227                "valid": true
228            }
229        ]
230    },
231    {
232        "description": "A $dynamicRef without a matching $dynamicAnchor in the same schema resource behaves like a normal $ref to $anchor",
233        "schema": {
234            "$schema": "https://json-schema.org/draft/2020-12/schema",
235            "$id": "https://test.json-schema.org/dynamic-resolution-without-bookend/root",
236            "$ref": "list",
237            "$defs": {
238                "foo": {
239                    "$dynamicAnchor": "items",
240                    "type": "string"
241                },
242                "list": {
243                    "$id": "list",
244                    "type": "array",
245                    "items": { "$dynamicRef": "#items" },
246                    "$defs": {
247                        "items": {
248                            "$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref",
249                            "$anchor": "items"
250                        }
251                    }
252                }
253            }
254        },
255        "tests": [
256            {
257                "description": "Any array is valid",
258                "data": ["foo", 42],
259                "valid": true
260            }
261        ]
262    },
263    {
264        "description": "A $dynamicRef with a non-matching $dynamicAnchor in the same schema resource behaves like a normal $ref to $anchor",
265        "schema": {
266            "$schema": "https://json-schema.org/draft/2020-12/schema",
267            "$id": "https://test.json-schema.org/unmatched-dynamic-anchor/root",
268            "$ref": "list",
269            "$defs": {
270                "foo": {
271                    "$dynamicAnchor": "items",
272                    "type": "string"
273                },
274                "list": {
275                    "$id": "list",
276                    "type": "array",
277                    "items": { "$dynamicRef": "#items" },
278                    "$defs": {
279                        "items": {
280                            "$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref",
281                            "$anchor": "items",
282                            "$dynamicAnchor": "foo"
283                        }
284                    }
285                }
286            }
287        },
288        "tests": [
289            {
290                "description": "Any array is valid",
291                "data": ["foo", 42],
292                "valid": true
293            }
294        ]
295    },
296    {
297        "description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor resolves to the first $dynamicAnchor in the dynamic scope",
298        "schema": {
299            "$schema": "https://json-schema.org/draft/2020-12/schema",
300            "$id": "https://test.json-schema.org/relative-dynamic-reference/root",
301            "$dynamicAnchor": "meta",
302            "type": "object",
303            "properties": {
304                "foo": { "const": "pass" }
305            },
306            "$ref": "extended",
307            "$defs": {
308                "extended": {
309                    "$id": "extended",
310                    "$dynamicAnchor": "meta",
311                    "type": "object",
312                    "properties": {
313                        "bar": { "$ref": "bar" }
314                    }
315                },
316                "bar": {
317                    "$id": "bar",
318                    "type": "object",
319                    "properties": {
320                        "baz": { "$dynamicRef": "extended#meta" }
321                    }
322                }
323            }
324        },
325        "tests": [
326            {
327                "description": "The recursive part is valid against the root",
328                "data": {
329                    "foo": "pass",
330                    "bar": {
331                        "baz": { "foo": "pass" }
332                    }
333                },
334                "valid": true
335            },
336            {
337                "description": "The recursive part is not valid against the root",
338                "data": {
339                    "foo": "pass",
340                    "bar": {
341                        "baz": { "foo": "fail" }
342                    }
343                },
344                "valid": false
345            }
346        ]
347    },
348    {
349        "description": "A $dynamicRef that initially resolves to a schema without a matching $dynamicAnchor behaves like a normal $ref to $anchor",
350        "schema": {
351            "$schema": "https://json-schema.org/draft/2020-12/schema",
352            "$id": "https://test.json-schema.org/relative-dynamic-reference-without-bookend/root",
353            "$dynamicAnchor": "meta",
354            "type": "object",
355            "properties": {
356                "foo": { "const": "pass" }
357            },
358            "$ref": "extended",
359            "$defs": {
360                "extended": {
361                    "$id": "extended",
362                    "$anchor": "meta",
363                    "type": "object",
364                    "properties": {
365                        "bar": { "$ref": "bar" }
366                    }
367                },
368                "bar": {
369                    "$id": "bar",
370                    "type": "object",
371                    "properties": {
372                        "baz": { "$dynamicRef": "extended#meta" }
373                    }
374                }
375            }
376        },
377        "tests": [
378            {
379                "description": "The recursive part doesn't need to validate against the root",
380                "data": {
381                    "foo": "pass",
382                    "bar": {
383                        "baz": { "foo": "fail" }
384                    }
385                },
386                "valid": true
387            }
388        ]
389    },
390    {
391        "description": "multiple dynamic paths to the $dynamicRef keyword",
392        "schema": {
393            "$schema": "https://json-schema.org/draft/2020-12/schema",
394            "$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main",
395            "if": {
396                "properties": {
397                    "kindOfList": { "const": "numbers" }
398                },
399                "required": ["kindOfList"]
400            },
401            "then": { "$ref": "numberList" },
402            "else": { "$ref": "stringList" },
403
404            "$defs": {
405                "genericList": {
406                    "$id": "genericList",
407                    "properties": {
408                        "list": {
409                            "items": { "$dynamicRef": "#itemType" }
410                        }
411                    },
412                    "$defs": {
413                        "defaultItemType": {
414                            "$comment": "Only needed to satisfy bookending requirement",
415                            "$dynamicAnchor": "itemType"
416                        }
417                    }
418                },
419                "numberList": {
420                    "$id": "numberList",
421                    "$defs": {
422                        "itemType": {
423                            "$dynamicAnchor": "itemType",
424                            "type": "number"
425                        }
426                    },
427                    "$ref": "genericList"
428                },
429                "stringList": {
430                    "$id": "stringList",
431                    "$defs": {
432                        "itemType": {
433                            "$dynamicAnchor": "itemType",
434                            "type": "string"
435                        }
436                    },
437                    "$ref": "genericList"
438                }
439            }
440        },
441        "tests": [
442            {
443                "description": "number list with number values",
444                "data": {
445                    "kindOfList": "numbers",
446                    "list": [1.1]
447                },
448                "valid": true
449            },
450            {
451                "description": "number list with string values",
452                "data": {
453                    "kindOfList": "numbers",
454                    "list": ["foo"]
455                },
456                "valid": false
457            },
458            {
459                "description": "string list with number values",
460                "data": {
461                    "kindOfList": "strings",
462                    "list": [1.1]
463                },
464                "valid": false
465            },
466            {
467                "description": "string list with string values",
468                "data": {
469                    "kindOfList": "strings",
470                    "list": ["foo"]
471                },
472                "valid": true
473            }
474        ]
475    },
476    {
477        "description": "after leaving a dynamic scope, it is not used by a $dynamicRef",
478        "schema": {
479            "$schema": "https://json-schema.org/draft/2020-12/schema",
480            "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main",
481            "if": {
482                "$id": "first_scope",
483                "$defs": {
484                    "thingy": {
485                        "$comment": "this is first_scope#thingy",
486                        "$dynamicAnchor": "thingy",
487                        "type": "number"
488                    }
489                }
490            },
491            "then": {
492                "$id": "second_scope",
493                "$ref": "start",
494                "$defs": {
495                    "thingy": {
496                        "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef",
497                        "$dynamicAnchor": "thingy",
498                        "type": "null"
499                    }
500                }
501            },
502            "$defs": {
503                "start": {
504                    "$comment": "this is the landing spot from $ref",
505                    "$id": "start",
506                    "$dynamicRef": "inner_scope#thingy"
507                },
508                "thingy": {
509                    "$comment": "this is the first stop for the $dynamicRef",
510                    "$id": "inner_scope",
511                    "$dynamicAnchor": "thingy",
512                    "type": "string"
513                }
514            }
515        },
516        "tests": [
517            {
518                "description": "string matches /$defs/thingy, but the $dynamicRef does not stop here",
519                "data": "a string",
520                "valid": false
521            },
522            {
523                "description": "first_scope is not in dynamic scope for the $dynamicRef",
524                "data": 42,
525                "valid": false
526            },
527            {
528                "description": "/then/$defs/thingy is the final stop for the $dynamicRef",
529                "data": null,
530                "valid": true
531            }
532        ]
533    },
534    {
535        "description": "strict-tree schema, guards against misspelled properties",
536        "schema": {
537            "$schema": "https://json-schema.org/draft/2020-12/schema",
538            "$id": "http://localhost:1234/draft2020-12/strict-tree.json",
539            "$dynamicAnchor": "node",
540
541            "$ref": "tree.json",
542            "unevaluatedProperties": false
543        },
544        "tests": [
545            {
546                "description": "instance with misspelled field",
547                "data": {
548                    "children": [{
549                            "daat": 1
550                        }]
551                },
552                "valid": false
553            },
554            {
555                "description": "instance with correct field",
556                "data": {
557                    "children": [{
558                            "data": 1
559                        }]
560                },
561                "valid": true
562            }
563        ]
564    },
565    {
566        "description": "tests for implementation dynamic anchor and reference link",
567        "schema": {
568            "$schema": "https://json-schema.org/draft/2020-12/schema",
569            "$id": "http://localhost:1234/draft2020-12/strict-extendible.json",
570            "$ref": "extendible-dynamic-ref.json",
571            "$defs": {
572                "elements": {
573                    "$dynamicAnchor": "elements",
574                    "properties": {
575                        "a": true
576                    },
577                    "required": ["a"],
578                    "additionalProperties": false
579                }
580            }
581        },
582        "tests": [
583            {
584                "description": "incorrect parent schema",
585                "data": {
586                    "a": true
587                },
588                "valid": false
589            },
590            {
591                "description": "incorrect extended schema",
592                "data": {
593                    "elements": [
594                        { "b": 1 }
595                    ]
596                },
597                "valid": false
598            },
599            {
600                "description": "correct extended schema",
601                "data": {
602                    "elements": [
603                        { "a": 1 }
604                    ]
605                },
606                "valid": true
607            }
608        ]
609    },
610    {
611        "description": "$ref and $dynamicAnchor are independent of order - $defs first",
612        "schema": {
613            "$schema": "https://json-schema.org/draft/2020-12/schema",
614            "$id": "http://localhost:1234/draft2020-12/strict-extendible-allof-defs-first.json",
615            "allOf": [
616                {
617                    "$ref": "extendible-dynamic-ref.json"
618                },
619                {
620                    "$defs": {
621                        "elements": {
622                            "$dynamicAnchor": "elements",
623                            "properties": {
624                                "a": true
625                            },
626                            "required": ["a"],
627                            "additionalProperties": false
628                        }
629                    }
630                }
631            ]
632        },
633        "tests": [
634            {
635                "description": "incorrect parent schema",
636                "data": {
637                    "a": true
638                },
639                "valid": false
640            },
641            {
642                "description": "incorrect extended schema",
643                "data": {
644                    "elements": [
645                        { "b": 1 }
646                    ]
647                },
648                "valid": false
649            },
650            {
651                "description": "correct extended schema",
652                "data": {
653                    "elements": [
654                        { "a": 1 }
655                    ]
656                },
657                "valid": true
658            }
659        ]
660    },
661    {
662        "description": "$ref and $dynamicAnchor are independent of order - $ref first",
663        "schema": {
664            "$schema": "https://json-schema.org/draft/2020-12/schema",
665            "$id": "http://localhost:1234/draft2020-12/strict-extendible-allof-ref-first.json",
666            "allOf": [
667                {
668                    "$defs": {
669                        "elements": {
670                            "$dynamicAnchor": "elements",
671                            "properties": {
672                                "a": true
673                            },
674                            "required": ["a"],
675                            "additionalProperties": false
676                        }
677                    }
678                },
679                {
680                    "$ref": "extendible-dynamic-ref.json"
681                }
682            ]
683        },
684        "tests": [
685            {
686                "description": "incorrect parent schema",
687                "data": {
688                    "a": true
689                },
690                "valid": false
691            },
692            {
693                "description": "incorrect extended schema",
694                "data": {
695                    "elements": [
696                        { "b": 1 }
697                    ]
698                },
699                "valid": false
700            },
701            {
702                "description": "correct extended schema",
703                "data": {
704                    "elements": [
705                        { "a": 1 }
706                    ]
707                },
708                "valid": true
709            }
710        ]
711    },
712    {
713        "description": "$ref to $dynamicRef finds detached $dynamicAnchor",
714        "schema": {
715            "$ref": "http://localhost:1234/draft2020-12/detached-dynamicref.json#/$defs/foo"
716        },
717        "tests": [
718            {
719                "description": "number is valid",
720                "data": 1,
721                "valid": true
722            },
723            {
724                "description": "non-number is invalid",
725                "data": "a",
726                "valid": false
727            }
728        ]
729    },
730    {
731        "description": "$dynamicRef points to a boolean schema",
732        "schema": {
733            "$schema": "https://json-schema.org/draft/2020-12/schema",
734            "$defs": {
735                "true": true,
736                "false": false
737            },
738            "properties": {
739                "true": {
740                    "$dynamicRef": "#/$defs/true"
741                },
742                "false": {
743                    "$dynamicRef": "#/$defs/false"
744                }
745            }
746        },
747        "tests": [
748            {
749                "description": "follow $dynamicRef to a true schema",
750                "data": { "true": 1 },
751                "valid": true
752            },
753            {
754                "description": "follow $dynamicRef to a false schema",
755                "data": { "false": 1 },
756                "valid": false
757            }
758        ]
759    }
760]
761