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