xref: /aosp_15_r20/external/json-schema-validator/src/test/suite/tests/draft7/ref.json (revision 78c4dd6aa35290980cdcd1623a7e337e8d021c7c)
1[
2    {
3        "description": "root pointer ref",
4        "schema": {
5            "properties": {
6                "foo": {"$ref": "#"}
7            },
8            "additionalProperties": false
9        },
10        "tests": [
11            {
12                "description": "match",
13                "data": {"foo": false},
14                "valid": true
15            },
16            {
17                "description": "recursive match",
18                "data": {"foo": {"foo": false}},
19                "valid": true
20            },
21            {
22                "description": "mismatch",
23                "data": {"bar": false},
24                "valid": false
25            },
26            {
27                "description": "recursive mismatch",
28                "data": {"foo": {"bar": false}},
29                "valid": false
30            }
31        ]
32    },
33    {
34        "description": "relative pointer ref to object",
35        "schema": {
36            "properties": {
37                "foo": {"type": "integer"},
38                "bar": {"$ref": "#/properties/foo"}
39            }
40        },
41        "tests": [
42            {
43                "description": "match",
44                "data": {"bar": 3},
45                "valid": true
46            },
47            {
48                "description": "mismatch",
49                "data": {"bar": true},
50                "valid": false
51            }
52        ]
53    },
54    {
55        "description": "relative pointer ref to array",
56        "schema": {
57            "items": [
58                {"type": "integer"},
59                {"$ref": "#/items/0"}
60            ]
61        },
62        "tests": [
63            {
64                "description": "match array",
65                "data": [1, 2],
66                "valid": true
67            },
68            {
69                "description": "mismatch array",
70                "data": [1, "foo"],
71                "valid": false
72            }
73        ]
74    },
75    {
76        "description": "escaped pointer ref",
77        "schema": {
78            "definitions": {
79                "tilde~field": {"type": "integer"},
80                "slash/field": {"type": "integer"},
81                "percent%field": {"type": "integer"}
82            },
83            "properties": {
84                "tilde": {"$ref": "#/definitions/tilde~0field"},
85                "slash": {"$ref": "#/definitions/slash~1field"},
86                "percent": {"$ref": "#/definitions/percent%25field"}
87            }
88        },
89        "tests": [
90            {
91                "description": "slash invalid",
92                "data": {"slash": "aoeu"},
93                "valid": false
94            },
95            {
96                "description": "tilde invalid",
97                "data": {"tilde": "aoeu"},
98                "valid": false
99            },
100            {
101                "description": "percent invalid",
102                "data": {"percent": "aoeu"},
103                "valid": false
104            },
105            {
106                "description": "slash valid",
107                "data": {"slash": 123},
108                "valid": true
109            },
110            {
111                "description": "tilde valid",
112                "data": {"tilde": 123},
113                "valid": true
114            },
115            {
116                "description": "percent valid",
117                "data": {"percent": 123},
118                "valid": true
119            }
120        ]
121    },
122    {
123        "description": "nested refs",
124        "schema": {
125            "definitions": {
126                "a": {"type": "integer"},
127                "b": {"$ref": "#/definitions/a"},
128                "c": {"$ref": "#/definitions/b"}
129            },
130            "allOf": [{ "$ref": "#/definitions/c" }]
131        },
132        "tests": [
133            {
134                "description": "nested ref valid",
135                "data": 5,
136                "valid": true
137            },
138            {
139                "description": "nested ref invalid",
140                "data": "a",
141                "valid": false
142            }
143        ]
144    },
145    {
146        "description": "ref overrides any sibling keywords",
147        "schema": {
148            "definitions": {
149                "reffed": {
150                    "type": "array"
151                }
152            },
153            "properties": {
154                "foo": {
155                    "$ref": "#/definitions/reffed",
156                    "maxItems": 2
157                }
158            }
159        },
160        "tests": [
161            {
162                "description": "ref valid",
163                "data": { "foo": [] },
164                "valid": true
165            },
166            {
167                "description": "ref valid, maxItems ignored",
168                "data": { "foo": [ 1, 2, 3] },
169                "valid": true
170            },
171            {
172                "description": "ref invalid",
173                "data": { "foo": "string" },
174                "valid": false
175            }
176        ]
177    },
178    {
179        "description": "$ref prevents a sibling $id from changing the base uri",
180        "schema": {
181            "$id": "http://localhost:1234/sibling_id/base/",
182            "definitions": {
183                "foo": {
184                    "$id": "http://localhost:1234/sibling_id/foo.json",
185                    "type": "string"
186                },
187                "base_foo": {
188                    "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json",
189                    "$id": "foo.json",
190                    "type": "number"
191                }
192            },
193            "allOf": [
194                {
195                    "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json",
196                    "$id": "http://localhost:1234/sibling_id/",
197                    "$ref": "foo.json"
198                }
199            ]
200        },
201        "tests": [
202            {
203                "description": "$ref resolves to /definitions/base_foo, data does not validate",
204                "data": "a",
205                "valid": false
206            },
207            {
208                "description": "$ref resolves to /definitions/base_foo, data validates",
209                "data": 1,
210                "valid": true
211            }
212        ]
213    },
214    {
215        "description": "remote ref, containing refs itself",
216        "schema": {"$ref": "http://json-schema.org/draft-07/schema#"},
217        "tests": [
218            {
219                "description": "remote ref valid",
220                "data": {"minLength": 1},
221                "valid": true
222            },
223            {
224                "description": "remote ref invalid",
225                "data": {"minLength": -1},
226                "valid": false
227            }
228        ]
229    },
230    {
231        "description": "property named $ref that is not a reference",
232        "schema": {
233            "properties": {
234                "$ref": {"type": "string"}
235            }
236        },
237        "tests": [
238            {
239                "description": "property named $ref valid",
240                "data": {"$ref": "a"},
241                "valid": true
242            },
243            {
244                "description": "property named $ref invalid",
245                "data": {"$ref": 2},
246                "valid": false
247            }
248        ]
249    },
250    {
251        "description": "property named $ref, containing an actual $ref",
252        "schema": {
253            "properties": {
254                "$ref": {"$ref": "#/definitions/is-string"}
255            },
256            "definitions": {
257                "is-string": {
258                    "type": "string"
259                }
260            }
261        },
262        "tests": [
263            {
264                "description": "property named $ref valid",
265                "data": {"$ref": "a"},
266                "valid": true
267            },
268            {
269                "description": "property named $ref invalid",
270                "data": {"$ref": 2},
271                "valid": false
272            }
273        ]
274    },
275    {
276        "description": "$ref to boolean schema true",
277        "schema": {
278            "allOf": [{ "$ref": "#/definitions/bool" }],
279            "definitions": {
280                "bool": true
281            }
282        },
283        "tests": [
284            {
285                "description": "any value is valid",
286                "data": "foo",
287                "valid": true
288            }
289        ]
290    },
291    {
292        "description": "$ref to boolean schema false",
293        "schema": {
294            "allOf": [{ "$ref": "#/definitions/bool" }],
295            "definitions": {
296                "bool": false
297            }
298        },
299        "tests": [
300            {
301                "description": "any value is invalid",
302                "data": "foo",
303                "valid": false
304            }
305        ]
306    },
307    {
308        "description": "Recursive references between schemas",
309        "schema": {
310            "$id": "http://localhost:1234/tree",
311            "description": "tree of nodes",
312            "type": "object",
313            "properties": {
314                "meta": {"type": "string"},
315                "nodes": {
316                    "type": "array",
317                    "items": {"$ref": "node"}
318                }
319            },
320            "required": ["meta", "nodes"],
321            "definitions": {
322                "node": {
323                    "$id": "http://localhost:1234/node",
324                    "description": "node",
325                    "type": "object",
326                    "properties": {
327                        "value": {"type": "number"},
328                        "subtree": {"$ref": "tree"}
329                    },
330                    "required": ["value"]
331                }
332            }
333        },
334        "tests": [
335            {
336                "description": "valid tree",
337                "data": {
338                    "meta": "root",
339                    "nodes": [
340                        {
341                            "value": 1,
342                            "subtree": {
343                                "meta": "child",
344                                "nodes": [
345                                    {"value": 1.1},
346                                    {"value": 1.2}
347                                ]
348                            }
349                        },
350                        {
351                            "value": 2,
352                            "subtree": {
353                                "meta": "child",
354                                "nodes": [
355                                    {"value": 2.1},
356                                    {"value": 2.2}
357                                ]
358                            }
359                        }
360                    ]
361                },
362                "valid": true
363            },
364            {
365                "description": "invalid tree",
366                "data": {
367                    "meta": "root",
368                    "nodes": [
369                        {
370                            "value": 1,
371                            "subtree": {
372                                "meta": "child",
373                                "nodes": [
374                                    {"value": "string is invalid"},
375                                    {"value": 1.2}
376                                ]
377                            }
378                        },
379                        {
380                            "value": 2,
381                            "subtree": {
382                                "meta": "child",
383                                "nodes": [
384                                    {"value": 2.1},
385                                    {"value": 2.2}
386                                ]
387                            }
388                        }
389                    ]
390                },
391                "valid": false
392            }
393        ]
394    },
395    {
396        "description": "refs with quote",
397        "schema": {
398            "properties": {
399                "foo\"bar": {"$ref": "#/definitions/foo%22bar"}
400            },
401            "definitions": {
402                "foo\"bar": {"type": "number"}
403            }
404        },
405        "tests": [
406            {
407                "description": "object with numbers is valid",
408                "data": {
409                    "foo\"bar": 1
410                },
411                "valid": true
412            },
413            {
414                "description": "object with strings is invalid",
415                "data": {
416                    "foo\"bar": "1"
417                },
418                "valid": false
419            }
420        ]
421    },
422    {
423        "description": "Location-independent identifier",
424        "schema": {
425            "allOf": [{
426                "$ref": "#foo"
427            }],
428            "definitions": {
429                "A": {
430                    "$id": "#foo",
431                    "type": "integer"
432                }
433            }
434        },
435        "tests": [
436            {
437                "data": 1,
438                "description": "match",
439                "valid": true
440            },
441            {
442                "data": "a",
443                "description": "mismatch",
444                "valid": false
445            }
446        ]
447    },
448    {
449        "description": "Reference an anchor with a non-relative URI",
450        "schema": {
451            "$id": "https://example.com/schema-with-anchor",
452            "allOf": [{
453                "$ref": "https://example.com/schema-with-anchor#foo"
454            }],
455            "definitions": {
456                "A": {
457                    "$id": "#foo",
458                    "type": "integer"
459                }
460            }
461        },
462        "tests": [
463            {
464                "data": 1,
465                "description": "match",
466                "valid": true
467            },
468            {
469                "data": "a",
470                "description": "mismatch",
471                "valid": false
472            }
473        ]
474    },
475    {
476        "description": "Location-independent identifier with base URI change in subschema",
477        "schema": {
478            "$id": "http://localhost:1234/root",
479            "allOf": [{
480                "$ref": "http://localhost:1234/nested.json#foo"
481            }],
482            "definitions": {
483                "A": {
484                    "$id": "nested.json",
485                    "definitions": {
486                        "B": {
487                            "$id": "#foo",
488                            "type": "integer"
489                        }
490                    }
491                }
492            }
493        },
494        "tests": [
495            {
496                "data": 1,
497                "description": "match",
498                "valid": true
499            },
500            {
501                "data": "a",
502                "description": "mismatch",
503                "valid": false
504            }
505        ]
506    },
507    {
508        "description": "naive replacement of $ref with its destination is not correct",
509        "schema": {
510            "definitions": {
511                "a_string": { "type": "string" }
512            },
513            "enum": [
514                { "$ref": "#/definitions/a_string" }
515            ]
516        },
517        "tests": [
518            {
519                "description": "do not evaluate the $ref inside the enum, matching any string",
520                "data": "this is a string",
521                "valid": false
522            },
523            {
524                "description": "do not evaluate the $ref inside the enum, definition exact match",
525                "data": { "type": "string" },
526                "valid": false
527            },
528            {
529                "description": "match the enum exactly",
530                "data": { "$ref": "#/definitions/a_string" },
531                "valid": true
532            }
533        ]
534    },
535    {
536        "description": "refs with relative uris and defs",
537        "schema": {
538            "$id": "http://example.com/schema-relative-uri-defs1.json",
539            "properties": {
540                "foo": {
541                    "$id": "schema-relative-uri-defs2.json",
542                    "definitions": {
543                        "inner": {
544                            "properties": {
545                                "bar": { "type": "string" }
546                            }
547                        }
548                    },
549                    "allOf": [ { "$ref": "#/definitions/inner" } ]
550                }
551            },
552            "allOf": [ { "$ref": "schema-relative-uri-defs2.json" } ]
553        },
554        "tests": [
555            {
556                "description": "invalid on inner field",
557                "data": {
558                    "foo": {
559                        "bar": 1
560                    },
561                    "bar": "a"
562                },
563                "valid": false
564            },
565            {
566                "description": "invalid on outer field",
567                "data": {
568                    "foo": {
569                        "bar": "a"
570                    },
571                    "bar": 1
572                },
573                "valid": false
574            },
575            {
576                "description": "valid on both fields",
577                "data": {
578                    "foo": {
579                        "bar": "a"
580                    },
581                    "bar": "a"
582                },
583                "valid": true
584            }
585        ]
586    },
587    {
588        "description": "relative refs with absolute uris and defs",
589        "schema": {
590            "$id": "http://example.com/schema-refs-absolute-uris-defs1.json",
591            "properties": {
592                "foo": {
593                    "$id": "http://example.com/schema-refs-absolute-uris-defs2.json",
594                    "definitions": {
595                        "inner": {
596                            "properties": {
597                                "bar": { "type": "string" }
598                            }
599                        }
600                    },
601                    "allOf": [ { "$ref": "#/definitions/inner" } ]
602                }
603            },
604            "allOf": [ { "$ref": "schema-refs-absolute-uris-defs2.json" } ]
605        },
606        "tests": [
607            {
608                "description": "invalid on inner field",
609                "data": {
610                    "foo": {
611                        "bar": 1
612                    },
613                    "bar": "a"
614                },
615                "valid": false
616            },
617            {
618                "description": "invalid on outer field",
619                "data": {
620                    "foo": {
621                        "bar": "a"
622                    },
623                    "bar": 1
624                },
625                "valid": false
626            },
627            {
628                "description": "valid on both fields",
629                "data": {
630                    "foo": {
631                        "bar": "a"
632                    },
633                    "bar": "a"
634                },
635                "valid": true
636            }
637        ]
638    },
639    {
640        "description": "$id must be resolved against nearest parent, not just immediate parent",
641        "schema": {
642            "$id": "http://example.com/a.json",
643            "definitions": {
644                "x": {
645                    "$id": "http://example.com/b/c.json",
646                    "not": {
647                        "definitions": {
648                            "y": {
649                                "$id": "d.json",
650                                "type": "number"
651                            }
652                        }
653                    }
654                }
655            },
656            "allOf": [
657                {
658                    "$ref": "http://example.com/b/d.json"
659                }
660            ]
661        },
662        "tests": [
663            {
664                "description": "number is valid",
665                "data": 1,
666                "valid": true
667            },
668            {
669                "description": "non-number is invalid",
670                "data": "a",
671                "valid": false
672            }
673        ]
674    },
675    {
676        "description": "simple URN base URI with $ref via the URN",
677        "schema": {
678            "$comment": "URIs do not have to have HTTP(s) schemes",
679            "$id": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed",
680            "minimum": 30,
681            "properties": {
682                "foo": {"$ref": "urn:uuid:deadbeef-1234-ffff-ffff-4321feebdaed"}
683            }
684        },
685        "tests": [
686            {
687                "description": "valid under the URN IDed schema",
688                "data": {"foo": 37},
689                "valid": true
690            },
691            {
692                "description": "invalid under the URN IDed schema",
693                "data": {"foo": 12},
694                "valid": false
695            }
696        ]
697    },
698    {
699        "description": "simple URN base URI with JSON pointer",
700        "schema": {
701            "$comment": "URIs do not have to have HTTP(s) schemes",
702            "$id": "urn:uuid:deadbeef-1234-00ff-ff00-4321feebdaed",
703            "properties": {
704                "foo": {"$ref": "#/definitions/bar"}
705            },
706            "definitions": {
707                "bar": {"type": "string"}
708            }
709        },
710        "tests": [
711            {
712                "description": "a string is valid",
713                "data": {"foo": "bar"},
714                "valid": true
715            },
716            {
717                "description": "a non-string is invalid",
718                "data": {"foo": 12},
719                "valid": false
720            }
721        ]
722    },
723    {
724        "description": "URN base URI with NSS",
725        "schema": {
726            "$comment": "RFC 8141 §2.2",
727            "$id": "urn:example:1/406/47452/2",
728            "properties": {
729                "foo": {"$ref": "#/definitions/bar"}
730            },
731            "definitions": {
732                "bar": {"type": "string"}
733            }
734        },
735        "tests": [
736            {
737                "description": "a string is valid",
738                "data": {"foo": "bar"},
739                "valid": true
740            },
741            {
742                "description": "a non-string is invalid",
743                "data": {"foo": 12},
744                "valid": false
745            }
746        ]
747    },
748    {
749        "description": "URN base URI with r-component",
750        "schema": {
751            "$comment": "RFC 8141 §2.3.1",
752            "$id": "urn:example:foo-bar-baz-qux?+CCResolve:cc=uk",
753            "properties": {
754                "foo": {"$ref": "#/definitions/bar"}
755            },
756            "definitions": {
757                "bar": {"type": "string"}
758            }
759        },
760        "tests": [
761            {
762                "description": "a string is valid",
763                "data": {"foo": "bar"},
764                "valid": true
765            },
766            {
767                "description": "a non-string is invalid",
768                "data": {"foo": 12},
769                "valid": false
770            }
771        ]
772    },
773    {
774        "description": "URN base URI with q-component",
775        "schema": {
776            "$comment": "RFC 8141 §2.3.2",
777            "$id": "urn:example:weather?=op=map&lat=39.56&lon=-104.85&datetime=1969-07-21T02:56:15Z",
778            "properties": {
779                "foo": {"$ref": "#/definitions/bar"}
780            },
781            "definitions": {
782                "bar": {"type": "string"}
783            }
784        },
785        "tests": [
786            {
787                "description": "a string is valid",
788                "data": {"foo": "bar"},
789                "valid": true
790            },
791            {
792                "description": "a non-string is invalid",
793                "data": {"foo": 12},
794                "valid": false
795            }
796        ]
797    },
798    {
799        "description": "URN base URI with URN and JSON pointer ref",
800        "schema": {
801            "$id": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed",
802            "properties": {
803                "foo": {"$ref": "urn:uuid:deadbeef-1234-0000-0000-4321feebdaed#/definitions/bar"}
804            },
805            "definitions": {
806                "bar": {"type": "string"}
807            }
808        },
809        "tests": [
810            {
811                "description": "a string is valid",
812                "data": {"foo": "bar"},
813                "valid": true
814            },
815            {
816                "description": "a non-string is invalid",
817                "data": {"foo": 12},
818                "valid": false
819            }
820        ]
821    },
822    {
823        "description": "URN base URI with URN and anchor ref",
824        "schema": {
825            "$id": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed",
826            "properties": {
827                "foo": {"$ref": "urn:uuid:deadbeef-1234-ff00-00ff-4321feebdaed#something"}
828            },
829            "definitions": {
830                "bar": {
831                    "$id": "#something",
832                    "type": "string"
833                }
834            }
835        },
836        "tests": [
837            {
838                "description": "a string is valid",
839                "data": {"foo": "bar"},
840                "valid": true
841            },
842            {
843                "description": "a non-string is invalid",
844                "data": {"foo": 12},
845                "valid": false
846            }
847        ]
848    },
849    {
850        "description": "ref to if",
851        "schema": {
852            "allOf": [
853                {"$ref": "http://example.com/ref/if"},
854                {
855                    "if": {
856                        "$id": "http://example.com/ref/if",
857                        "type": "integer"
858                    }
859                }
860            ]
861        },
862        "tests": [
863            {
864                "description": "a non-integer is invalid due to the $ref",
865                "data": "foo",
866                "valid": false
867            },
868            {
869                "description": "an integer is valid",
870                "data": 12,
871                "valid": true
872            }
873        ]
874    },
875    {
876        "description": "ref to then",
877        "schema": {
878            "allOf": [
879                {"$ref": "http://example.com/ref/then"},
880                {
881                    "then": {
882                        "$id": "http://example.com/ref/then",
883                        "type": "integer"
884                    }
885                }
886            ]
887        },
888        "tests": [
889            {
890                "description": "a non-integer is invalid due to the $ref",
891                "data": "foo",
892                "valid": false
893            },
894            {
895                "description": "an integer is valid",
896                "data": 12,
897                "valid": true
898            }
899        ]
900    },
901    {
902        "description": "ref to else",
903        "schema": {
904            "allOf": [
905                {"$ref": "http://example.com/ref/else"},
906                {
907                    "else": {
908                        "$id": "http://example.com/ref/else",
909                        "type": "integer"
910                    }
911                }
912            ]
913        },
914        "tests": [
915            {
916                "description": "a non-integer is invalid due to the $ref",
917                "data": "foo",
918                "valid": false
919            },
920            {
921                "description": "an integer is valid",
922                "data": 12,
923                "valid": true
924            }
925        ]
926    },
927    {
928        "description": "ref with absolute-path-reference",
929        "schema": {
930            "$id": "http://example.com/ref/absref.json",
931            "definitions": {
932                "a": {
933                    "$id": "http://example.com/ref/absref/foobar.json",
934                    "type": "number"
935                 },
936                 "b": {
937                     "$id": "http://example.com/absref/foobar.json",
938                     "type": "string"
939                 }
940            },
941            "allOf": [
942                { "$ref": "/absref/foobar.json" }
943            ]
944        },
945        "tests": [
946            {
947                "description": "a string is valid",
948                "data": "foo",
949                "valid": true
950            },
951            {
952                "description": "an integer is invalid",
953                "data": 12,
954                "valid": false
955            }
956        ]
957    },
958    {
959        "description": "$id with file URI still resolves pointers - *nix",
960        "schema": {
961            "$id": "file:///folder/file.json",
962            "definitions": {
963                "foo": {
964                    "type": "number"
965                }
966            },
967            "allOf": [
968                {
969                    "$ref": "#/definitions/foo"
970                }
971            ]
972        },
973        "tests": [
974            {
975                "description": "number is valid",
976                "data": 1,
977                "valid": true
978            },
979            {
980                "description": "non-number is invalid",
981                "data": "a",
982                "valid": false
983            }
984        ]
985    },
986    {
987        "description": "$id with file URI still resolves pointers - windows",
988        "schema": {
989            "$id": "file:///c:/folder/file.json",
990            "definitions": {
991                "foo": {
992                    "type": "number"
993                }
994            },
995            "allOf": [
996                {
997                    "$ref": "#/definitions/foo"
998                }
999            ]
1000        },
1001        "tests": [
1002            {
1003                "description": "number is valid",
1004                "data": 1,
1005                "valid": true
1006            },
1007            {
1008                "description": "non-number is invalid",
1009                "data": "a",
1010                "valid": false
1011            }
1012        ]
1013    },
1014    {
1015        "description": "empty tokens in $ref json-pointer",
1016        "schema": {
1017            "definitions": {
1018                "": {
1019                    "definitions": {
1020                        "": { "type": "number" }
1021                    }
1022                }
1023            },
1024            "allOf": [
1025                {
1026                    "$ref": "#/definitions//definitions/"
1027                }
1028            ]
1029        },
1030        "tests": [
1031            {
1032                "description": "number is valid",
1033                "data": 1,
1034                "valid": true
1035            },
1036            {
1037                "description": "non-number is invalid",
1038                "data": "a",
1039                "valid": false
1040            }
1041        ]
1042    }
1043]
1044