xref: /aosp_15_r20/external/json-schema-validator/src/test/suite/tests/draft-next/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/next/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 $ref to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor",
31        "schema": {
32            "$schema": "https://json-schema.org/draft/next/schema",
33            "$id": "https://test.json-schema.org/ref-dynamicAnchor-same-schema/root",
34            "type": "array",
35            "items": { "$ref": "#items" },
36            "$defs": {
37                "foo": {
38                    "$dynamicAnchor": "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 $dynamicRef resolves to the first $dynamicAnchor still in scope that is encountered when the schema is evaluated",
58        "schema": {
59            "$schema": "https://json-schema.org/draft/next/schema",
60            "$id": "https://test.json-schema.org/typical-dynamic-resolution/root",
61            "$ref": "list",
62            "$defs": {
63                "foo": {
64                    "$dynamicAnchor": "items",
65                    "type": "string"
66                },
67                "list": {
68                    "$id": "list",
69                    "type": "array",
70                    "items": { "$dynamicRef": "#items" }
71                }
72            }
73        },
74        "tests": [
75            {
76                "description": "An array of strings is valid",
77                "data": ["foo", "bar"],
78                "valid": true
79            },
80            {
81                "description": "An array containing non-strings is invalid",
82                "data": ["foo", 42],
83                "valid": false
84            }
85        ]
86    },
87    {
88        "description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor does not affect dynamic scope resolution",
89        "schema": {
90            "$schema": "https://json-schema.org/draft/next/schema",
91            "$id": "https://test.json-schema.org/dynamic-resolution-with-intermediate-scopes/root",
92            "$ref": "intermediate-scope",
93            "$defs": {
94                "foo": {
95                    "$dynamicAnchor": "items",
96                    "type": "string"
97                },
98                "intermediate-scope": {
99                    "$id": "intermediate-scope",
100                    "$ref": "list"
101                },
102                "list": {
103                    "$id": "list",
104                    "type": "array",
105                    "items": { "$dynamicRef": "#items" }
106                }
107            }
108        },
109        "tests": [
110            {
111                "description": "An array of strings is valid",
112                "data": ["foo", "bar"],
113                "valid": true
114            },
115            {
116                "description": "An array containing non-strings is invalid",
117                "data": ["foo", 42],
118                "valid": false
119            }
120        ]
121    },
122    {
123        "description": "An $anchor with the same name as a $dynamicAnchor is not used for dynamic scope resolution",
124        "schema": {
125            "$schema": "https://json-schema.org/draft/next/schema",
126            "$id": "https://test.json-schema.org/dynamic-resolution-ignores-anchors/root",
127            "$ref": "list",
128            "$defs": {
129                "foo": {
130                    "$anchor": "items",
131                    "type": "string"
132                },
133                "list": {
134                    "$id": "list",
135                    "type": "array",
136                    "items": { "$dynamicRef": "#items" },
137                    "$defs": {
138                      "items": {
139                          "$dynamicAnchor": "items"
140                      }
141                    }
142                }
143            }
144        },
145        "tests": [
146            {
147                "description": "Any array is valid",
148                "data": ["foo", 42],
149                "valid": true
150            }
151        ]
152    },
153    {
154        "description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor resolves to the first $dynamicAnchor in the dynamic scope",
155        "schema": {
156            "$schema": "https://json-schema.org/draft/next/schema",
157            "$id": "https://test.json-schema.org/relative-dynamic-reference/root",
158            "$dynamicAnchor": "meta",
159            "type": "object",
160            "properties": {
161                "foo": { "const": "pass" }
162            },
163            "$ref": "extended",
164            "$defs": {
165                "extended": {
166                    "$id": "extended",
167                    "$dynamicAnchor": "meta",
168                    "type": "object",
169                    "properties": {
170                        "bar": { "$ref": "bar" }
171                    }
172                },
173                "bar": {
174                    "$id": "bar",
175                    "type": "object",
176                    "properties": {
177                        "baz": { "$dynamicRef": "extended#meta" }
178                    }
179                }
180            }
181        },
182        "tests": [
183            {
184                "description": "The recursive part is valid against the root",
185                "data": {
186                    "foo": "pass",
187                    "bar": {
188                        "baz": { "foo": "pass" }
189                    }
190                },
191                "valid": true
192            },
193            {
194                "description": "The recursive part is not valid against the root",
195                "data": {
196                    "foo": "pass",
197                    "bar": {
198                        "baz": { "foo": "fail" }
199                    }
200                },
201                "valid": false
202            }
203        ]
204    },
205    {
206        "description": "multiple dynamic paths to the $dynamicRef keyword",
207        "schema": {
208            "$schema": "https://json-schema.org/draft/next/schema",
209            "$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main",
210            "propertyDependencies": {
211                "kindOfList": {
212                    "numbers": { "$ref": "numberList" },
213                    "strings": { "$ref": "stringList" }
214                }
215            },
216            "$defs": {
217                "genericList": {
218                    "$id": "genericList",
219                    "properties": {
220                        "list": {
221                            "items": { "$dynamicRef": "#itemType" }
222                        }
223                    }
224                },
225                "numberList": {
226                    "$id": "numberList",
227                    "$defs": {
228                        "itemType": {
229                            "$dynamicAnchor": "itemType",
230                            "type": "number"
231                        }
232                    },
233                    "$ref": "genericList"
234                },
235                "stringList": {
236                    "$id": "stringList",
237                    "$defs": {
238                        "itemType": {
239                            "$dynamicAnchor": "itemType",
240                            "type": "string"
241                        }
242                    },
243                    "$ref": "genericList"
244                }
245            }
246        },
247        "tests": [
248            {
249                "description": "number list with number values",
250                "data": {
251                    "kindOfList": "numbers",
252                    "list": [1.1]
253                },
254                "valid": true
255            },
256            {
257                "description": "number list with string values",
258                "data": {
259                    "kindOfList": "numbers",
260                    "list": ["foo"]
261                },
262                "valid": false
263            },
264            {
265                "description": "string list with number values",
266                "data": {
267                    "kindOfList": "strings",
268                    "list": [1.1]
269                },
270                "valid": false
271            },
272            {
273                "description": "string list with string values",
274                "data": {
275                    "kindOfList": "strings",
276                    "list": ["foo"]
277                },
278                "valid": true
279            }
280        ]
281    },
282    {
283        "description": "after leaving a dynamic scope, it is not used by a $dynamicRef",
284        "schema": {
285            "$schema": "https://json-schema.org/draft/next/schema",
286            "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main",
287            "if": {
288                "$id": "first_scope",
289                "$defs": {
290                    "thingy": {
291                        "$comment": "this is first_scope#thingy",
292                        "$dynamicAnchor": "thingy",
293                        "type": "number"
294                    }
295                }
296            },
297            "then": {
298                "$id": "second_scope",
299                "$ref": "start",
300                "$defs": {
301                    "thingy": {
302                        "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef",
303                        "$dynamicAnchor": "thingy",
304                        "type": "null"
305                    }
306                }
307            },
308            "$defs": {
309                "start": {
310                    "$comment": "this is the landing spot from $ref",
311                    "$id": "start",
312                    "$dynamicRef": "inner_scope#thingy"
313                },
314                "thingy": {
315                    "$comment": "this is the first stop for the $dynamicRef",
316                    "$id": "inner_scope",
317                    "$dynamicAnchor": "thingy",
318                    "type": "string"
319                }
320            }
321        },
322        "tests": [
323            {
324                "description": "string matches /$defs/thingy, but the $dynamicRef does not stop here",
325                "data": "a string",
326                "valid": false
327            },
328            {
329                "description": "first_scope is not in dynamic scope for the $dynamicRef",
330                "data": 42,
331                "valid": false
332            },
333            {
334                "description": "/then/$defs/thingy is the final stop for the $dynamicRef",
335                "data": null,
336                "valid": true
337            }
338        ]
339    },
340    {
341        "description": "strict-tree schema, guards against misspelled properties",
342        "schema": {
343            "$schema": "https://json-schema.org/draft/next/schema",
344            "$id": "http://localhost:1234/draft-next/strict-tree.json",
345            "$dynamicAnchor": "node",
346
347            "$ref": "tree.json",
348            "unevaluatedProperties": false
349        },
350        "tests": [
351            {
352                "description": "instance with misspelled field",
353                "data": {
354                    "children": [{
355                            "daat": 1
356                        }]
357                },
358                "valid": false
359            },
360            {
361                "description": "instance with correct field",
362                "data": {
363                    "children": [{
364                            "data": 1
365                        }]
366                },
367                "valid": true
368            }
369        ]
370    },
371    {
372        "description": "tests for implementation dynamic anchor and reference link",
373        "schema": {
374            "$schema": "https://json-schema.org/draft/next/schema",
375            "$id": "http://localhost:1234/draft-next/strict-extendible.json",
376            "$ref": "extendible-dynamic-ref.json",
377            "$defs": {
378                "elements": {
379                    "$dynamicAnchor": "elements",
380                    "properties": {
381                        "a": true
382                    },
383                    "required": ["a"],
384                    "additionalProperties": false
385                }
386            }
387        },
388        "tests": [
389            {
390                "description": "incorrect parent schema",
391                "data": {
392                    "a": true
393                },
394                "valid": false
395            },
396            {
397                "description": "incorrect extended schema",
398                "data": {
399                    "elements": [
400                        { "b": 1 }
401                    ]
402                },
403                "valid": false
404            },
405            {
406                "description": "correct extended schema",
407                "data": {
408                    "elements": [
409                        { "a": 1 }
410                    ]
411                },
412                "valid": true
413            }
414        ]
415    },
416    {
417        "description": "$ref and $dynamicAnchor are independent of order - $defs first",
418        "schema": {
419            "$schema": "https://json-schema.org/draft/next/schema",
420            "$id": "http://localhost:1234/draft-next/strict-extendible-allof-defs-first.json",
421            "allOf": [
422                {
423                    "$ref": "extendible-dynamic-ref.json"
424                },
425                {
426                    "$defs": {
427                        "elements": {
428                            "$dynamicAnchor": "elements",
429                            "properties": {
430                                "a": true
431                            },
432                            "required": ["a"],
433                            "additionalProperties": false
434                        }
435                    }
436                }
437            ]
438        },
439        "tests": [
440            {
441                "description": "incorrect parent schema",
442                "data": {
443                    "a": true
444                },
445                "valid": false
446            },
447            {
448                "description": "incorrect extended schema",
449                "data": {
450                    "elements": [
451                        { "b": 1 }
452                    ]
453                },
454                "valid": false
455            },
456            {
457                "description": "correct extended schema",
458                "data": {
459                    "elements": [
460                        { "a": 1 }
461                    ]
462                },
463                "valid": true
464            }
465        ]
466    },
467    {
468        "description": "$ref and $dynamicAnchor are independent of order - $ref first",
469        "schema": {
470            "$schema": "https://json-schema.org/draft/next/schema",
471            "$id": "http://localhost:1234/draft-next/strict-extendible-allof-ref-first.json",
472            "allOf": [
473                {
474                    "$defs": {
475                        "elements": {
476                            "$dynamicAnchor": "elements",
477                            "properties": {
478                                "a": true
479                            },
480                            "required": ["a"],
481                            "additionalProperties": false
482                        }
483                    }
484                },
485                {
486                    "$ref": "extendible-dynamic-ref.json"
487                }
488            ]
489        },
490        "tests": [
491            {
492                "description": "incorrect parent schema",
493                "data": {
494                    "a": true
495                },
496                "valid": false
497            },
498            {
499                "description": "incorrect extended schema",
500                "data": {
501                    "elements": [
502                        { "b": 1 }
503                    ]
504                },
505                "valid": false
506            },
507            {
508                "description": "correct extended schema",
509                "data": {
510                    "elements": [
511                        { "a": 1 }
512                    ]
513                },
514                "valid": true
515            }
516        ]
517    },
518    {
519        "description": "$dynamicAnchor inside propertyDependencies",
520        "schema": {
521            "$schema": "https://json-schema.org/draft/next/schema",
522            "$id": "http://localhost:1234/draft-next/dynamicanchor-in-propertydependencies.json",
523            "$defs": {
524                "inner": {
525                    "$id": "inner",
526                    "$dynamicAnchor": "foo",
527                    "type": "object",
528                    "properties": {
529                        "expectedTypes": {
530                            "type": "string"
531                        }
532                    },
533                    "additionalProperties": {
534                        "$dynamicRef": "#foo"
535                    }
536                }
537            },
538            "propertyDependencies": {
539                "expectedTypes": {
540                    "strings": {
541                        "$id": "east",
542                        "$ref": "inner",
543                        "$defs": {
544                            "foo": {
545                                "$dynamicAnchor": "foo",
546                                "type": "string"
547                            }
548                        }
549                    },
550                    "integers": {
551                        "$id": "west",
552                        "$ref": "inner",
553                        "$defs": {
554                            "foo": {
555                                "$dynamicAnchor": "foo",
556                                "type": "integer"
557                            }
558                        }
559                    }
560                }
561            }
562        },
563        "tests": [
564            {
565                "description": "expected strings - additional property as string is valid",
566                "data": {
567                    "expectedTypes": "strings",
568                    "anotherProperty": "also a string"
569                },
570                "valid": true
571            },
572            {
573                "description": "expected strings - additional property as not string is invalid",
574                "data": {
575                    "expectedTypes": "strings",
576                    "anotherProperty": 42
577                },
578                "valid": false
579            },
580            {
581                "description": "expected integers - additional property as integer is valid",
582                "data": {
583                    "expectedTypes": "integers",
584                    "anotherProperty": 42
585                },
586                "valid": true
587            },
588            {
589                "description": "expected integers - additional property as not integer is invalid",
590                "data": {
591                    "expectedTypes": "integers",
592                    "anotherProperty": "a string"
593                },
594                "valid": false
595            }
596        ]
597    },
598    {
599        "description": "$ref to $dynamicRef finds detached $dynamicAnchor",
600        "schema": {
601            "$ref": "http://localhost:1234/draft-next/detached-dynamicref.json#/$defs/foo"
602        },
603        "tests": [
604            {
605                "description": "number is valid",
606                "data": 1,
607                "valid": true
608            },
609            {
610                "description": "non-number is invalid",
611                "data": "a",
612                "valid": false
613            }
614        ]
615    },
616    {
617        "description": "$dynamicRef points to a boolean schema",
618        "schema": {
619            "$schema": "https://json-schema.org/draft/next/schema",
620            "$defs": {
621                "true": true,
622                "false": false
623            },
624            "properties": {
625                "true": {
626                    "$dynamicRef": "#/$defs/true"
627                },
628                "false": {
629                    "$dynamicRef": "#/$defs/false"
630                }
631            }
632        },
633        "tests": [
634            {
635                "description": "follow $dynamicRef to a true schema",
636                "data": { "true": 1 },
637                "valid": true
638            },
639            {
640                "description": "follow $dynamicRef to a false schema",
641                "data": { "false": 1 },
642                "valid": false
643            }
644        ]
645    }
646]
647