test_dictionary.py (20105B)
1 import WebIDL 2 3 4 def WebIDLTest(parser, harness): 5 parser.parse( 6 """ 7 dictionary Dict2 : Dict1 { 8 long child = 5; 9 Dict1 aaandAnother; 10 }; 11 dictionary Dict1 { 12 long parent; 13 double otherParent; 14 }; 15 """ 16 ) 17 results = parser.finish() 18 19 dict1 = results[1] 20 dict2 = results[0] 21 22 harness.check(len(dict1.members), 2, "Dict1 has two members") 23 harness.check(len(dict2.members), 2, "Dict2 has four members") 24 25 harness.check( 26 dict1.members[0].identifier.name, "otherParent", "'o' comes before 'p'" 27 ) 28 harness.check( 29 dict1.members[1].identifier.name, "parent", "'o' really comes before 'p'" 30 ) 31 harness.check( 32 dict2.members[0].identifier.name, "aaandAnother", "'a' comes before 'c'" 33 ) 34 harness.check( 35 dict2.members[1].identifier.name, "child", "'a' really comes before 'c'" 36 ) 37 38 # Test partial dictionary. 39 parser = parser.reset() 40 parser.parse( 41 """ 42 dictionary A { 43 long c; 44 long g; 45 }; 46 partial dictionary A { 47 long h; 48 long d; 49 }; 50 """ 51 ) 52 results = parser.finish() 53 54 dict1 = results[0] 55 harness.check(len(dict1.members), 4, "Dict1 has four members") 56 harness.check(dict1.members[0].identifier.name, "c", "c should be first") 57 harness.check(dict1.members[1].identifier.name, "d", "d should come after c") 58 harness.check(dict1.members[2].identifier.name, "g", "g should come after d") 59 harness.check(dict1.members[3].identifier.name, "h", "h should be last") 60 61 # Now reset our parser 62 parser = parser.reset() 63 threw = False 64 try: 65 parser.parse( 66 """ 67 dictionary Dict { 68 long prop = 5; 69 long prop; 70 }; 71 """ 72 ) 73 parser.finish() 74 except WebIDL.WebIDLError: 75 threw = True 76 77 harness.ok(threw, "Should not allow name duplication in a dictionary") 78 79 # Test no name duplication across normal and partial dictionary. 80 parser = parser.reset() 81 threw = False 82 try: 83 parser.parse( 84 """ 85 dictionary A { 86 long prop = 5; 87 }; 88 partial dictionary A { 89 long prop; 90 }; 91 """ 92 ) 93 parser.finish() 94 except WebIDL.WebIDLError: 95 threw = True 96 97 harness.ok( 98 threw, "Should not allow name duplication across normal and partial dictionary" 99 ) 100 101 # Now reset our parser again 102 parser = parser.reset() 103 threw = False 104 try: 105 parser.parse( 106 """ 107 dictionary Dict1 : Dict2 { 108 long prop = 5; 109 }; 110 dictionary Dict2 : Dict3 { 111 long prop2; 112 }; 113 dictionary Dict3 { 114 double prop; 115 }; 116 """ 117 ) 118 parser.finish() 119 except WebIDL.WebIDLError: 120 threw = True 121 122 harness.ok( 123 threw, "Should not allow name duplication in a dictionary and its ancestor" 124 ) 125 126 # More reset 127 parser = parser.reset() 128 threw = False 129 try: 130 parser.parse( 131 """ 132 interface Iface {}; 133 dictionary Dict : Iface { 134 long prop; 135 }; 136 """ 137 ) 138 parser.finish() 139 except WebIDL.WebIDLError: 140 threw = True 141 142 harness.ok(threw, "Should not allow non-dictionary parents for dictionaries") 143 144 # Even more reset 145 parser = parser.reset() 146 threw = False 147 try: 148 parser.parse( 149 """ 150 dictionary A : B {}; 151 dictionary B : A {}; 152 """ 153 ) 154 parser.finish() 155 except WebIDL.WebIDLError: 156 threw = True 157 158 harness.ok(threw, "Should not allow cycles in dictionary inheritance chains") 159 160 parser = parser.reset() 161 threw = False 162 try: 163 parser.parse( 164 """ 165 dictionary A { 166 [LegacyNullToEmptyString] DOMString foo; 167 }; 168 """ 169 ) 170 parser.finish() 171 except WebIDL.WebIDLError: 172 threw = True 173 174 harness.ok( 175 threw, "Should not allow [LegacyNullToEmptyString] on dictionary members" 176 ) 177 178 parser = parser.reset() 179 threw = False 180 try: 181 parser.parse( 182 """ 183 dictionary A { 184 }; 185 interface X { 186 undefined doFoo(A arg); 187 }; 188 """ 189 ) 190 parser.finish() 191 except WebIDL.WebIDLError: 192 threw = True 193 194 harness.ok(threw, "Trailing dictionary arg must be optional") 195 196 parser = parser.reset() 197 threw = False 198 try: 199 parser.parse( 200 """ 201 dictionary A { 202 }; 203 interface X { 204 undefined doFoo(optional A arg); 205 }; 206 """ 207 ) 208 parser.finish() 209 except WebIDL.WebIDLError: 210 threw = True 211 212 harness.ok(threw, "Trailing dictionary arg must have a default value") 213 214 parser = parser.reset() 215 threw = False 216 try: 217 parser.parse( 218 """ 219 dictionary A { 220 }; 221 interface X { 222 undefined doFoo((A or DOMString) arg); 223 }; 224 """ 225 ) 226 parser.finish() 227 except WebIDL.WebIDLError: 228 threw = True 229 230 harness.ok(threw, "Trailing union arg containing a dictionary must be optional") 231 232 parser = parser.reset() 233 threw = False 234 try: 235 parser.parse( 236 """ 237 dictionary A { 238 }; 239 interface X { 240 undefined doFoo(optional (A or DOMString) arg); 241 }; 242 """ 243 ) 244 parser.finish() 245 except WebIDL.WebIDLError: 246 threw = True 247 248 harness.ok( 249 threw, "Trailing union arg containing a dictionary must have a default value" 250 ) 251 252 parser = parser.reset() 253 threw = False 254 try: 255 parser.parse( 256 """ 257 dictionary A { 258 }; 259 interface X { 260 undefined doFoo(A arg1, optional long arg2); 261 }; 262 """ 263 ) 264 parser.finish() 265 except WebIDL.WebIDLError: 266 threw = True 267 268 harness.ok(threw, "Dictionary arg followed by optional arg must be optional") 269 270 parser = parser.reset() 271 threw = False 272 try: 273 parser.parse( 274 """ 275 dictionary A { 276 }; 277 interface X { 278 undefined doFoo(optional A arg1, optional long arg2); 279 }; 280 """ 281 ) 282 parser.finish() 283 except WebIDL.WebIDLError: 284 threw = True 285 286 harness.ok(threw, "Dictionary arg followed by optional arg must have default value") 287 288 parser = parser.reset() 289 threw = False 290 try: 291 parser.parse( 292 """ 293 dictionary A { 294 }; 295 interface X { 296 undefined doFoo(A arg1, optional long arg2, long arg3); 297 }; 298 """ 299 ) 300 parser.finish() 301 except WebIDL.WebIDLError: 302 threw = True 303 304 harness.ok( 305 not threw, 306 "Dictionary arg followed by non-optional arg doesn't have to be optional", 307 ) 308 309 parser = parser.reset() 310 threw = False 311 try: 312 parser.parse( 313 """ 314 dictionary A { 315 }; 316 interface X { 317 undefined doFoo((A or DOMString) arg1, optional long arg2); 318 }; 319 """ 320 ) 321 parser.finish() 322 except WebIDL.WebIDLError: 323 threw = True 324 325 harness.ok( 326 threw, 327 "Union arg containing dictionary followed by optional arg must be optional", 328 ) 329 330 parser = parser.reset() 331 threw = False 332 try: 333 parser.parse( 334 """ 335 dictionary A { 336 }; 337 interface X { 338 undefined doFoo(optional (A or DOMString) arg1, optional long arg2); 339 }; 340 """ 341 ) 342 parser.finish() 343 except WebIDL.WebIDLError: 344 threw = True 345 346 harness.ok( 347 threw, 348 "Union arg containing dictionary followed by optional arg must " 349 "have a default value", 350 ) 351 352 parser = parser.reset() 353 parser.parse( 354 """ 355 dictionary A { 356 }; 357 interface X { 358 undefined doFoo(A arg1, long arg2); 359 }; 360 """ 361 ) 362 parser.finish() 363 harness.ok(True, "Dictionary arg followed by required arg can be required") 364 365 parser = parser.reset() 366 threw = False 367 try: 368 parser.parse( 369 """ 370 dictionary A { 371 }; 372 interface X { 373 undefined doFoo(optional A? arg1 = {}); 374 }; 375 """ 376 ) 377 parser.finish() 378 except Exception as x: 379 threw = x 380 381 harness.ok(threw, "Optional dictionary arg must not be nullable") 382 harness.ok( 383 "nullable" in str(threw), 384 "Must have the expected exception for optional nullable dictionary arg", 385 ) 386 387 parser = parser.reset() 388 threw = False 389 try: 390 parser.parse( 391 """ 392 dictionary A { 393 required long x; 394 }; 395 interface X { 396 undefined doFoo(A? arg1); 397 }; 398 """ 399 ) 400 parser.finish() 401 except Exception as x: 402 threw = x 403 404 harness.ok(threw, "Required dictionary arg must not be nullable") 405 harness.ok( 406 "nullable" in str(threw), 407 "Must have the expected exception for required nullable dictionary arg", 408 ) 409 410 parser = parser.reset() 411 threw = False 412 try: 413 parser.parse( 414 """ 415 dictionary A { 416 }; 417 interface X { 418 undefined doFoo(optional (A or long)? arg1 = {}); 419 }; 420 """ 421 ) 422 parser.finish() 423 except Exception as x: 424 threw = x 425 426 harness.ok(threw, "Dictionary arg must not be in an optional nullable union") 427 harness.ok( 428 "nullable" in str(threw), 429 "Must have the expected exception for optional nullable union " 430 "arg containing dictionary", 431 ) 432 433 parser = parser.reset() 434 threw = False 435 try: 436 parser.parse( 437 """ 438 dictionary A { 439 required long x; 440 }; 441 interface X { 442 undefined doFoo((A or long)? arg1); 443 }; 444 """ 445 ) 446 parser.finish() 447 except Exception as x: 448 threw = x 449 450 harness.ok(threw, "Dictionary arg must not be in a required nullable union") 451 harness.ok( 452 "nullable" in str(threw), 453 "Must have the expected exception for required nullable union " 454 "arg containing dictionary", 455 ) 456 457 parser = parser.reset() 458 threw = False 459 try: 460 parser.parse( 461 """ 462 dictionary A { 463 }; 464 interface X { 465 undefined doFoo(sequence<A?> arg1); 466 }; 467 """ 468 ) 469 parser.finish() 470 except WebIDL.WebIDLError: 471 threw = True 472 473 harness.ok(not threw, "Nullable union should be allowed in a sequence argument") 474 475 parser = parser.reset() 476 threw = False 477 try: 478 parser.parse( 479 """ 480 dictionary A { 481 }; 482 interface X { 483 undefined doFoo(optional (A or long?) arg1); 484 }; 485 """ 486 ) 487 parser.finish() 488 except WebIDL.WebIDLError: 489 threw = True 490 harness.ok(threw, "Dictionary must not be in a union with a nullable type") 491 492 parser = parser.reset() 493 threw = False 494 try: 495 parser.parse( 496 """ 497 dictionary A { 498 }; 499 interface X { 500 undefined doFoo(optional (long? or A) arg1); 501 }; 502 """ 503 ) 504 parser.finish() 505 except WebIDL.WebIDLError: 506 threw = True 507 harness.ok(threw, "A nullable type must not be in a union with a dictionary") 508 509 parser = parser.reset() 510 parser.parse( 511 """ 512 dictionary A { 513 }; 514 interface X { 515 A? doFoo(); 516 }; 517 """ 518 ) 519 parser.finish() 520 harness.ok(True, "Dictionary return value can be nullable") 521 522 parser = parser.reset() 523 parser.parse( 524 """ 525 dictionary A { 526 }; 527 interface X { 528 undefined doFoo(optional A arg = {}); 529 }; 530 """ 531 ) 532 parser.finish() 533 harness.ok(True, "Dictionary arg should actually parse") 534 535 parser = parser.reset() 536 parser.parse( 537 """ 538 dictionary A { 539 }; 540 interface X { 541 undefined doFoo(optional (A or DOMString) arg = {}); 542 }; 543 """ 544 ) 545 parser.finish() 546 harness.ok(True, "Union arg containing a dictionary should actually parse") 547 548 parser = parser.reset() 549 parser.parse( 550 """ 551 dictionary A { 552 }; 553 interface X { 554 undefined doFoo(optional (A or DOMString) arg = "abc"); 555 }; 556 """ 557 ) 558 parser.finish() 559 harness.ok( 560 True, 561 "Union arg containing a dictionary with string default should actually parse", 562 ) 563 564 parser = parser.reset() 565 threw = False 566 try: 567 parser.parse( 568 """ 569 dictionary Foo { 570 Foo foo; 571 }; 572 """ 573 ) 574 parser.finish() 575 except WebIDL.WebIDLError: 576 threw = True 577 578 harness.ok(threw, "Member type must not be its Dictionary.") 579 580 parser = parser.reset() 581 threw = False 582 try: 583 parser.parse( 584 """ 585 dictionary Foo3 : Foo { 586 short d; 587 }; 588 589 dictionary Foo2 : Foo3 { 590 boolean c; 591 }; 592 593 dictionary Foo1 : Foo2 { 594 long a; 595 }; 596 597 dictionary Foo { 598 Foo1 b; 599 }; 600 """ 601 ) 602 parser.finish() 603 except WebIDL.WebIDLError: 604 threw = True 605 606 harness.ok( 607 threw, 608 "Member type must not be a Dictionary that inherits from its Dictionary.", 609 ) 610 611 parser = parser.reset() 612 threw = False 613 try: 614 parser.parse( 615 """ 616 dictionary Foo { 617 (Foo or DOMString)[]? b; 618 }; 619 """ 620 ) 621 parser.finish() 622 except WebIDL.WebIDLError: 623 threw = True 624 625 harness.ok( 626 threw, 627 "Member type must not be a Nullable type " 628 "whose inner type includes its Dictionary.", 629 ) 630 631 parser = parser.reset() 632 threw = False 633 try: 634 parser.parse( 635 """ 636 dictionary Foo { 637 (DOMString or Foo) b; 638 }; 639 """ 640 ) 641 parser.finish() 642 except WebIDL.WebIDLError: 643 threw = True 644 645 harness.ok( 646 threw, 647 "Member type must not be a Union type, one of " 648 "whose member types includes its Dictionary.", 649 ) 650 651 parser = parser.reset() 652 threw = False 653 try: 654 parser.parse( 655 """ 656 dictionary Foo { 657 sequence<sequence<sequence<Foo>>> c; 658 }; 659 """ 660 ) 661 parser.finish() 662 except WebIDL.WebIDLError: 663 threw = True 664 665 harness.ok( 666 threw, 667 "Member type must not be a Sequence type " 668 "whose element type includes its Dictionary.", 669 ) 670 671 parser = parser.reset() 672 threw = False 673 try: 674 parser.parse( 675 """ 676 dictionary Foo { 677 (DOMString or Foo)[] d; 678 }; 679 """ 680 ) 681 parser.finish() 682 except WebIDL.WebIDLError: 683 threw = True 684 685 harness.ok( 686 threw, 687 "Member type must not be an Array type " 688 "whose element type includes its Dictionary.", 689 ) 690 691 parser = parser.reset() 692 threw = False 693 try: 694 parser.parse( 695 """ 696 dictionary Foo { 697 Foo1 b; 698 }; 699 700 dictionary Foo3 { 701 Foo d; 702 }; 703 704 dictionary Foo2 : Foo3 { 705 short c; 706 }; 707 708 dictionary Foo1 : Foo2 { 709 long a; 710 }; 711 """ 712 ) 713 parser.finish() 714 except WebIDL.WebIDLError: 715 threw = True 716 717 harness.ok( 718 threw, 719 "Member type must not be a Dictionary, one of whose " 720 "members or inherited members has a type that includes " 721 "its Dictionary.", 722 ) 723 724 parser = parser.reset() 725 threw = False 726 try: 727 parser.parse( 728 """ 729 dictionary Foo { 730 }; 731 732 dictionary Bar { 733 Foo? d; 734 }; 735 """ 736 ) 737 parser.finish() 738 except WebIDL.WebIDLError: 739 threw = True 740 741 harness.ok(threw, "Member type must not be a nullable dictionary") 742 743 parser = parser.reset() 744 parser.parse( 745 """ 746 dictionary Foo { 747 unrestricted float urFloat = 0; 748 unrestricted float urFloat2 = 1.1; 749 unrestricted float urFloat3 = -1.1; 750 unrestricted float? urFloat4 = null; 751 unrestricted float infUrFloat = Infinity; 752 unrestricted float negativeInfUrFloat = -Infinity; 753 unrestricted float nanUrFloat = NaN; 754 755 unrestricted double urDouble = 0; 756 unrestricted double urDouble2 = 1.1; 757 unrestricted double urDouble3 = -1.1; 758 unrestricted double? urDouble4 = null; 759 unrestricted double infUrDouble = Infinity; 760 unrestricted double negativeInfUrDouble = -Infinity; 761 unrestricted double nanUrDouble = NaN; 762 }; 763 """ 764 ) 765 parser.finish() 766 harness.ok(True, "Parsing default values for unrestricted types succeeded.") 767 768 parser = parser.reset() 769 threw = False 770 try: 771 parser.parse( 772 """ 773 dictionary Foo { 774 double f = Infinity; 775 }; 776 """ 777 ) 778 parser.finish() 779 except WebIDL.WebIDLError: 780 threw = True 781 782 harness.ok(threw, "Only unrestricted values can be initialized to Infinity") 783 784 parser = parser.reset() 785 threw = False 786 try: 787 parser.parse( 788 """ 789 dictionary Foo { 790 double f = -Infinity; 791 }; 792 """ 793 ) 794 parser.finish() 795 except WebIDL.WebIDLError: 796 threw = True 797 798 harness.ok(threw, "Only unrestricted values can be initialized to -Infinity") 799 800 parser = parser.reset() 801 threw = False 802 try: 803 parser.parse( 804 """ 805 dictionary Foo { 806 double f = NaN; 807 }; 808 """ 809 ) 810 parser.finish() 811 except WebIDL.WebIDLError: 812 threw = True 813 814 harness.ok(threw, "Only unrestricted values can be initialized to NaN") 815 816 parser = parser.reset() 817 threw = False 818 try: 819 parser.parse( 820 """ 821 dictionary Foo { 822 float f = Infinity; 823 }; 824 """ 825 ) 826 parser.finish() 827 except WebIDL.WebIDLError: 828 threw = True 829 830 harness.ok(threw, "Only unrestricted values can be initialized to Infinity") 831 832 parser = parser.reset() 833 threw = False 834 try: 835 parser.parse( 836 """ 837 dictionary Foo { 838 float f = -Infinity; 839 }; 840 """ 841 ) 842 parser.finish() 843 except WebIDL.WebIDLError: 844 threw = True 845 846 harness.ok(threw, "Only unrestricted values can be initialized to -Infinity") 847 848 parser = parser.reset() 849 threw = False 850 try: 851 parser.parse( 852 """ 853 dictionary Foo { 854 float f = NaN; 855 }; 856 """ 857 ) 858 parser.finish() 859 except WebIDL.WebIDLError: 860 threw = True 861 862 harness.ok(threw, "Only unrestricted values can be initialized to NaN") 863 864 parser = parser.reset() 865 threw = False 866 try: 867 parser.parse( 868 """ 869 dictionary Foo { 870 long module; 871 }; 872 """ 873 ) 874 parser.finish() 875 except WebIDL.WebIDLError: 876 threw = True 877 878 harness.ok(not threw, "Should be able to use 'module' as a dictionary member name")