1 package minify 2 3 import ( 4 "reflect" 5 "testing" 6 7 "vimagination.zapto.org/javascript" 8 ) 9 10 func TestBlockAsModule(t *testing.T) { 11 for n, test := range [...]struct { 12 Input *javascript.Block 13 Callback func(*javascript.Module) 14 Output *javascript.Block 15 }{ 16 { // 1 17 &javascript.Block{}, 18 func(m *javascript.Module) { 19 }, 20 &javascript.Block{}, 21 }, 22 { // 2 23 &javascript.Block{ 24 StatementList: []javascript.StatementListItem{ 25 { 26 Statement: &javascript.Statement{ 27 Type: javascript.StatementDebugger, 28 }, 29 }, 30 { 31 Statement: &javascript.Statement{ 32 Type: javascript.StatementContinue, 33 }, 34 }, 35 { 36 Statement: &javascript.Statement{ 37 Type: javascript.StatementDebugger, 38 }, 39 }, 40 { 41 Statement: &javascript.Statement{ 42 Type: javascript.StatementContinue, 43 }, 44 }, 45 }, 46 }, 47 func(m *javascript.Module) { 48 for i := 0; i < len(m.ModuleListItems); i++ { 49 if m.ModuleListItems[i].StatementListItem.Statement.Type == javascript.StatementDebugger { 50 m.ModuleListItems = append(m.ModuleListItems[:i], m.ModuleListItems[i+1:]...) 51 i-- 52 } 53 } 54 }, 55 &javascript.Block{ 56 StatementList: []javascript.StatementListItem{ 57 { 58 Statement: &javascript.Statement{ 59 Type: javascript.StatementContinue, 60 }, 61 }, 62 { 63 Statement: &javascript.Statement{ 64 Type: javascript.StatementContinue, 65 }, 66 }, 67 }, 68 }, 69 }, 70 } { 71 blockAsModule(test.Input, test.Callback) 72 if !reflect.DeepEqual(test.Input, test.Output) { 73 t.Errorf("test %d: expecting output %v, got %v", n+1, test.Output, test.Input) 74 } 75 } 76 } 77 78 func TestExpressionsAsModule(t *testing.T) { 79 for n, test := range [...]struct { 80 Input *javascript.Expression 81 Callback func(*javascript.Module) 82 Output *javascript.Expression 83 }{ 84 { // 1 85 &javascript.Expression{}, 86 func(m *javascript.Module) { 87 }, 88 &javascript.Expression{}, 89 }, 90 { // 2 91 &javascript.Expression{ 92 Expressions: []javascript.AssignmentExpression{ 93 { 94 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 95 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 96 }), 97 }, 98 { 99 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 100 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 101 }), 102 }, 103 { 104 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 105 IdentifierReference: makeToken(javascript.TokenIdentifier, "c"), 106 }), 107 }, 108 { 109 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 110 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 111 }), 112 }, 113 { 114 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 115 IdentifierReference: makeToken(javascript.TokenIdentifier, "d"), 116 }), 117 }, 118 }, 119 }, 120 func(m *javascript.Module) { 121 for i := 0; i < len(m.ModuleListItems); i++ { 122 if javascript.UnwrapConditional(m.ModuleListItems[i].StatementListItem.Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference.Data == "b" { 123 m.ModuleListItems = append(m.ModuleListItems[:i], m.ModuleListItems[i+1:]...) 124 } 125 } 126 }, 127 &javascript.Expression{ 128 Expressions: []javascript.AssignmentExpression{ 129 { 130 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 131 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 132 }), 133 }, 134 { 135 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 136 IdentifierReference: makeToken(javascript.TokenIdentifier, "c"), 137 }), 138 }, 139 { 140 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 141 IdentifierReference: makeToken(javascript.TokenIdentifier, "d"), 142 }), 143 }, 144 }, 145 }, 146 }, 147 } { 148 expressionsAsModule(test.Input, test.Callback) 149 if !reflect.DeepEqual(test.Input, test.Output) { 150 t.Errorf("test %d: expecting output %v, got %v", n+1, test.Output, test.Input) 151 } 152 } 153 } 154 155 func TestIsReturnStatement(t *testing.T) { 156 for n, test := range [...]struct { 157 Input *javascript.Statement 158 IsReturn bool 159 }{ 160 { // 1 161 nil, 162 false, 163 }, 164 { // 2 165 &javascript.Statement{}, 166 false, 167 }, 168 { // 3 169 &javascript.Statement{ 170 Type: javascript.StatementReturn, 171 }, 172 true, 173 }, 174 { // 4 175 &javascript.Statement{ 176 Type: javascript.StatementReturn, 177 ExpressionStatement: &javascript.Expression{ 178 Expressions: []javascript.AssignmentExpression{ 179 { 180 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 181 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 182 }), 183 }, 184 }, 185 }, 186 }, 187 true, 188 }, 189 } { 190 if isReturnStatement(test.Input) != test.IsReturn { 191 t.Errorf("test %d: expecting return %v, got %v", n+1, test.IsReturn, !test.IsReturn) 192 } 193 } 194 } 195 196 func TestIsNonEmptyReturnStatement(t *testing.T) { 197 for n, test := range [...]struct { 198 Input *javascript.Statement 199 IsReturn bool 200 }{ 201 { // 1 202 nil, 203 false, 204 }, 205 { // 2 206 &javascript.Statement{}, 207 false, 208 }, 209 { // 3 210 &javascript.Statement{ 211 Type: javascript.StatementReturn, 212 }, 213 false, 214 }, 215 { // 4 216 &javascript.Statement{ 217 Type: javascript.StatementReturn, 218 ExpressionStatement: &javascript.Expression{ 219 Expressions: []javascript.AssignmentExpression{ 220 { 221 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 222 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 223 }), 224 }, 225 }, 226 }, 227 }, 228 true, 229 }, 230 } { 231 if isNonEmptyReturnStatement(test.Input) != test.IsReturn { 232 t.Errorf("test %d: expecting return %v, got %v", n+1, test.IsReturn, !test.IsReturn) 233 } 234 } 235 } 236 237 func TestIsStatementExpression(t *testing.T) { 238 for n, test := range [...]struct { 239 Input *javascript.Statement 240 IsStatementExpression bool 241 }{ 242 { // 1 243 nil, 244 false, 245 }, 246 { // 2 247 &javascript.Statement{}, 248 false, 249 }, 250 { // 3 251 &javascript.Statement{ 252 Type: javascript.StatementDebugger, 253 }, 254 false, 255 }, 256 { // 4 257 &javascript.Statement{ 258 Type: javascript.StatementDebugger, 259 }, 260 false, 261 }, 262 { // 5 263 &javascript.Statement{ 264 Type: javascript.StatementReturn, 265 ExpressionStatement: &javascript.Expression{ 266 Expressions: []javascript.AssignmentExpression{ 267 { 268 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 269 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 270 }), 271 }, 272 }, 273 }, 274 }, 275 false, 276 }, 277 { // 6 278 &javascript.Statement{ 279 ExpressionStatement: &javascript.Expression{ 280 Expressions: []javascript.AssignmentExpression{ 281 { 282 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 283 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 284 }), 285 }, 286 }, 287 }, 288 }, 289 true, 290 }, 291 } { 292 if isStatementExpression(test.Input) != test.IsStatementExpression { 293 t.Errorf("test %d: expecting return %v, got %v", n+1, test.IsStatementExpression, !test.IsStatementExpression) 294 } 295 } 296 } 297 298 func TestIsSLIExpression(t *testing.T) { 299 for n, test := range [...]struct { 300 Input *javascript.StatementListItem 301 IsSLIExpression bool 302 }{ 303 { // 1 304 nil, 305 false, 306 }, 307 { // 2 308 &javascript.StatementListItem{}, 309 false, 310 }, 311 { // 3 312 &javascript.StatementListItem{ 313 Statement: &javascript.Statement{ 314 Type: javascript.StatementDebugger, 315 }, 316 }, 317 false, 318 }, 319 { // 4 320 &javascript.StatementListItem{ 321 Statement: &javascript.Statement{ 322 Type: javascript.StatementDebugger, 323 }, 324 }, 325 false, 326 }, 327 { // 5 328 &javascript.StatementListItem{ 329 Statement: &javascript.Statement{ 330 Type: javascript.StatementReturn, 331 ExpressionStatement: &javascript.Expression{ 332 Expressions: []javascript.AssignmentExpression{ 333 { 334 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 335 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 336 }), 337 }, 338 }, 339 }, 340 }, 341 }, 342 false, 343 }, 344 { // 6 345 &javascript.StatementListItem{ 346 Statement: &javascript.Statement{ 347 ExpressionStatement: &javascript.Expression{ 348 Expressions: []javascript.AssignmentExpression{ 349 { 350 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 351 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 352 }), 353 }, 354 }, 355 }, 356 }, 357 }, 358 true, 359 }, 360 { // 7 361 &javascript.StatementListItem{ 362 Declaration: &javascript.Declaration{ 363 FunctionDeclaration: &javascript.FunctionDeclaration{ 364 BindingIdentifier: makeToken(javascript.TokenIdentifier, "a"), 365 }, 366 }, 367 }, 368 false, 369 }, 370 } { 371 if isSLIExpression(test.Input) != test.IsSLIExpression { 372 t.Errorf("test %d: expecting return %v, got %v", n+1, test.IsSLIExpression, !test.IsSLIExpression) 373 } 374 } 375 } 376 377 func TestIsEmptyStatement(t *testing.T) { 378 for n, test := range [...]struct { 379 Input *javascript.Statement 380 IsEmptyStatement bool 381 }{ 382 { // 1 383 nil, 384 false, 385 }, 386 { // 2 387 &javascript.Statement{}, 388 true, 389 }, 390 { // 3 391 &javascript.Statement{ 392 Type: javascript.StatementContinue, 393 }, 394 false, 395 }, 396 { // 4 397 &javascript.Statement{ 398 BlockStatement: &javascript.Block{}, 399 }, 400 false, 401 }, 402 } { 403 if isEmptyStatement(test.Input) != test.IsEmptyStatement { 404 t.Errorf("test %d: expecting return %v, got %v", n+1, test.IsEmptyStatement, !test.IsEmptyStatement) 405 } 406 } 407 } 408 409 func TestIsHoistable(t *testing.T) { 410 for n, test := range [...]struct { 411 Input *javascript.StatementListItem 412 IsHoistable bool 413 }{ 414 { // 1 415 nil, 416 false, 417 }, 418 { // 2 419 &javascript.StatementListItem{}, 420 false, 421 }, 422 { // 3 423 &javascript.StatementListItem{ 424 Statement: &javascript.Statement{}, 425 }, 426 false, 427 }, 428 { // 4 429 &javascript.StatementListItem{ 430 Statement: &javascript.Statement{ 431 VariableStatement: &javascript.VariableStatement{}, 432 }, 433 }, 434 true, 435 }, 436 { // 5 437 &javascript.StatementListItem{ 438 Statement: &javascript.Statement{ 439 LabelIdentifier: makeToken(javascript.TokenIdentifier, "a"), 440 LabelledItemFunction: &javascript.FunctionDeclaration{ 441 BindingIdentifier: makeToken(javascript.TokenIdentifier, "b"), 442 }, 443 }, 444 }, 445 true, 446 }, 447 { // 6 448 &javascript.StatementListItem{ 449 Declaration: &javascript.Declaration{}, 450 }, 451 false, 452 }, 453 { // 7 454 &javascript.StatementListItem{ 455 Declaration: &javascript.Declaration{ 456 LexicalDeclaration: &javascript.LexicalDeclaration{}, 457 }, 458 }, 459 false, 460 }, 461 { // 8 462 &javascript.StatementListItem{ 463 Declaration: &javascript.Declaration{ 464 FunctionDeclaration: &javascript.FunctionDeclaration{ 465 BindingIdentifier: makeToken(javascript.TokenIdentifier, "a"), 466 }, 467 }, 468 }, 469 true, 470 }, 471 { // 9 472 &javascript.StatementListItem{ 473 Declaration: &javascript.Declaration{ 474 ClassDeclaration: &javascript.ClassDeclaration{ 475 BindingIdentifier: makeToken(javascript.TokenIdentifier, "a"), 476 }, 477 }, 478 }, 479 true, 480 }, 481 } { 482 if isHoistable(test.Input) != test.IsHoistable { 483 t.Errorf("test %d: expecting return %v, got %v", n+1, test.IsHoistable, !test.IsHoistable) 484 } 485 } 486 } 487 488 func TestStatementsListItemsAsExpressionsAndReturn(t *testing.T) { 489 for n, test := range [...]struct { 490 StatementListItems []javascript.StatementListItem 491 Expressions []javascript.AssignmentExpression 492 Return bool 493 }{ 494 { // 1 495 nil, 496 nil, 497 false, 498 }, 499 { // 2 500 []javascript.StatementListItem{}, 501 nil, 502 false, 503 }, 504 { // 3 505 []javascript.StatementListItem{ 506 { 507 Declaration: &javascript.Declaration{ 508 FunctionDeclaration: &javascript.FunctionDeclaration{ 509 BindingIdentifier: makeToken(javascript.TokenIdentifier, "a"), 510 }, 511 }, 512 }, 513 }, 514 nil, 515 false, 516 }, 517 { // 4 518 []javascript.StatementListItem{ 519 { 520 Statement: &javascript.Statement{}, 521 }, 522 }, 523 nil, 524 false, 525 }, 526 { // 5 527 []javascript.StatementListItem{ 528 { 529 Statement: &javascript.Statement{ 530 Type: javascript.StatementReturn, 531 }, 532 }, 533 }, 534 nil, 535 false, 536 }, 537 { // 6 538 []javascript.StatementListItem{ 539 { 540 Statement: &javascript.Statement{ 541 Type: javascript.StatementReturn, 542 ExpressionStatement: &javascript.Expression{ 543 Expressions: []javascript.AssignmentExpression{ 544 { 545 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 546 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 547 }), 548 }, 549 }, 550 }, 551 }, 552 }, 553 }, 554 []javascript.AssignmentExpression{ 555 { 556 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 557 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 558 }), 559 }, 560 }, 561 true, 562 }, 563 { // 7 564 []javascript.StatementListItem{ 565 { 566 Statement: &javascript.Statement{ 567 Type: javascript.StatementReturn, 568 ExpressionStatement: &javascript.Expression{ 569 Expressions: []javascript.AssignmentExpression{ 570 { 571 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 572 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 573 }), 574 }, 575 { 576 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 577 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 578 }), 579 }, 580 }, 581 }, 582 }, 583 }, 584 }, 585 []javascript.AssignmentExpression{ 586 { 587 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 588 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 589 }), 590 }, 591 { 592 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 593 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 594 }), 595 }, 596 }, 597 true, 598 }, 599 { // 8 600 []javascript.StatementListItem{ 601 { 602 Statement: &javascript.Statement{ 603 ExpressionStatement: &javascript.Expression{ 604 Expressions: []javascript.AssignmentExpression{ 605 { 606 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 607 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 608 }), 609 }, 610 }, 611 }, 612 }, 613 }, 614 }, 615 []javascript.AssignmentExpression{ 616 { 617 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 618 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 619 }), 620 }, 621 }, 622 false, 623 }, 624 { // 9 625 []javascript.StatementListItem{ 626 { 627 Statement: &javascript.Statement{ 628 ExpressionStatement: &javascript.Expression{ 629 Expressions: []javascript.AssignmentExpression{ 630 { 631 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 632 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 633 }), 634 }, 635 { 636 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 637 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 638 }), 639 }, 640 }, 641 }, 642 }, 643 }, 644 }, 645 []javascript.AssignmentExpression{ 646 { 647 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 648 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 649 }), 650 }, 651 { 652 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 653 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 654 }), 655 }, 656 }, 657 false, 658 }, 659 { // 10 660 []javascript.StatementListItem{ 661 { 662 Statement: &javascript.Statement{ 663 ExpressionStatement: &javascript.Expression{ 664 Expressions: []javascript.AssignmentExpression{ 665 { 666 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 667 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 668 }), 669 }, 670 }, 671 }, 672 }, 673 }, 674 { 675 Statement: &javascript.Statement{ 676 ExpressionStatement: &javascript.Expression{ 677 Expressions: []javascript.AssignmentExpression{ 678 { 679 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 680 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 681 }), 682 }, 683 }, 684 }, 685 }, 686 }, 687 }, 688 []javascript.AssignmentExpression{ 689 { 690 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 691 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 692 }), 693 }, 694 { 695 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 696 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 697 }), 698 }, 699 }, 700 false, 701 }, 702 { // 11 703 []javascript.StatementListItem{ 704 { 705 Statement: &javascript.Statement{ 706 ExpressionStatement: &javascript.Expression{ 707 Expressions: []javascript.AssignmentExpression{ 708 { 709 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 710 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 711 }), 712 }, 713 }, 714 }, 715 }, 716 }, 717 { 718 Statement: &javascript.Statement{ 719 Type: javascript.StatementReturn, 720 ExpressionStatement: &javascript.Expression{ 721 Expressions: []javascript.AssignmentExpression{ 722 { 723 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 724 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 725 }), 726 }, 727 }, 728 }, 729 }, 730 }, 731 }, 732 []javascript.AssignmentExpression{ 733 { 734 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 735 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 736 }), 737 }, 738 { 739 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 740 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 741 }), 742 }, 743 }, 744 true, 745 }, 746 { // 12 747 []javascript.StatementListItem{ 748 { 749 Declaration: &javascript.Declaration{ 750 FunctionDeclaration: &javascript.FunctionDeclaration{ 751 BindingIdentifier: makeToken(javascript.TokenIdentifier, "a"), 752 }, 753 }, 754 }, 755 { 756 Statement: &javascript.Statement{ 757 Type: javascript.StatementReturn, 758 ExpressionStatement: &javascript.Expression{ 759 Expressions: []javascript.AssignmentExpression{ 760 { 761 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 762 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 763 }), 764 }, 765 }, 766 }, 767 }, 768 }, 769 }, 770 nil, 771 false, 772 }, 773 { // 13 774 []javascript.StatementListItem{ 775 { 776 Statement: &javascript.Statement{ 777 Type: javascript.StatementReturn, 778 ExpressionStatement: &javascript.Expression{ 779 Expressions: []javascript.AssignmentExpression{ 780 { 781 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 782 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 783 }), 784 }, 785 }, 786 }, 787 }, 788 }, 789 { 790 Declaration: &javascript.Declaration{ 791 FunctionDeclaration: &javascript.FunctionDeclaration{ 792 BindingIdentifier: makeToken(javascript.TokenIdentifier, "b"), 793 }, 794 }, 795 }, 796 }, 797 nil, 798 true, 799 }, 800 { // 14 801 []javascript.StatementListItem{ 802 { 803 Statement: &javascript.Statement{ 804 Type: javascript.StatementReturn, 805 ExpressionStatement: &javascript.Expression{ 806 Expressions: []javascript.AssignmentExpression{ 807 { 808 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 809 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 810 }), 811 }, 812 }, 813 }, 814 }, 815 }, 816 { 817 Statement: &javascript.Statement{ 818 ExpressionStatement: &javascript.Expression{ 819 Expressions: []javascript.AssignmentExpression{ 820 { 821 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 822 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 823 }), 824 }, 825 }, 826 }, 827 }, 828 }, 829 }, 830 []javascript.AssignmentExpression{ 831 { 832 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 833 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 834 }), 835 }, 836 }, 837 true, 838 }, 839 } { 840 aes, ret := statementsListItemsAsExpressionsAndReturn(test.StatementListItems) 841 if ret != test.Return { 842 t.Errorf("test %d: expecting Return value of %v, got %v", n+1, test.Return, ret) 843 } else if !reflect.DeepEqual(aes, test.Expressions) { 844 t.Errorf("test %d: expecting AEs of %v, got %v", n+1, test.Expressions, aes) 845 } 846 } 847 } 848 849 func TestAEIsCE(t *testing.T) { 850 for n, test := range [...]struct { 851 AssignmentExpression *javascript.AssignmentExpression 852 IsConditionalExpression bool 853 }{ 854 { // 1 855 nil, 856 false, 857 }, 858 { // 2 859 &javascript.AssignmentExpression{}, 860 false, 861 }, 862 { // 3 863 &javascript.AssignmentExpression{ 864 AssignmentOperator: javascript.AssignmentAdd, 865 AssignmentExpression: &javascript.AssignmentExpression{ 866 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 867 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 868 }), 869 }, 870 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 871 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 872 }), 873 }, 874 false, 875 }, 876 { // 4 877 &javascript.AssignmentExpression{ 878 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 879 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 880 }), 881 }, 882 true, 883 }, 884 } { 885 if aeIsCE(test.AssignmentExpression) != test.IsConditionalExpression { 886 t.Errorf("test %d: expecting aeIsCE toreturn %v, got %v", n+1, test.IsConditionalExpression, !test.IsConditionalExpression) 887 } 888 } 889 } 890 891 func TestAEAsParen(t *testing.T) { 892 for n, test := range [...]struct { 893 AssignmentExpression *javascript.AssignmentExpression 894 ParenthesizedExpression *javascript.ParenthesizedExpression 895 }{ 896 { // 1 897 nil, 898 nil, 899 }, 900 { // 2 901 &javascript.AssignmentExpression{}, 902 nil, 903 }, 904 { // 3 905 &javascript.AssignmentExpression{ 906 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 907 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 908 }), 909 }, 910 nil, 911 }, 912 { // 4 913 &javascript.AssignmentExpression{ 914 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 915 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 916 Expressions: []javascript.AssignmentExpression{ 917 { 918 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 919 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 920 }), 921 }, 922 }, 923 }, 924 }), 925 }, 926 &javascript.ParenthesizedExpression{ 927 Expressions: []javascript.AssignmentExpression{ 928 { 929 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 930 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 931 }), 932 }, 933 }, 934 }, 935 }, 936 { // 5 937 &javascript.AssignmentExpression{ 938 AssignmentOperator: javascript.AssignmentAdd, 939 AssignmentExpression: &javascript.AssignmentExpression{ 940 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 941 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 942 Expressions: []javascript.AssignmentExpression{ 943 { 944 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 945 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 946 }), 947 }, 948 }, 949 }, 950 }), 951 }, 952 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 953 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 954 Expressions: []javascript.AssignmentExpression{ 955 { 956 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 957 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 958 }), 959 }, 960 }, 961 }, 962 }), 963 }, 964 nil, 965 }, 966 { // 6 967 &javascript.AssignmentExpression{ 968 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 969 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 970 Expressions: []javascript.AssignmentExpression{ 971 { 972 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 973 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 974 }), 975 }, 976 { 977 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 978 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 979 }), 980 }, 981 }, 982 }, 983 }), 984 }, 985 &javascript.ParenthesizedExpression{ 986 Expressions: []javascript.AssignmentExpression{ 987 { 988 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 989 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 990 }), 991 }, 992 { 993 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 994 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 995 }), 996 }, 997 }, 998 }, 999 }, 1000 } { 1001 if pe := aeAsParen(test.AssignmentExpression); !reflect.DeepEqual(pe, test.ParenthesizedExpression) { 1002 t.Errorf("test %d: expecting %v, got %v", n+1, test.ParenthesizedExpression, pe) 1003 } 1004 } 1005 } 1006 1007 func TestMEIsSinglePE(t *testing.T) { 1008 for n, test := range [...]struct { 1009 MemberExpression *javascript.MemberExpression 1010 IsSinglePE bool 1011 }{ 1012 { // 1 1013 nil, 1014 false, 1015 }, 1016 { // 2 1017 &javascript.MemberExpression{}, 1018 false, 1019 }, 1020 { // 3 1021 &javascript.MemberExpression{ 1022 PrimaryExpression: &javascript.PrimaryExpression{ 1023 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1024 }, 1025 }, 1026 false, 1027 }, 1028 { // 4 1029 &javascript.MemberExpression{ 1030 PrimaryExpression: &javascript.PrimaryExpression{ 1031 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1032 Expressions: []javascript.AssignmentExpression{ 1033 { 1034 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1035 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1036 }), 1037 }, 1038 }, 1039 }, 1040 }, 1041 }, 1042 true, 1043 }, 1044 { // 5 1045 &javascript.MemberExpression{ 1046 PrimaryExpression: &javascript.PrimaryExpression{ 1047 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1048 Expressions: []javascript.AssignmentExpression{ 1049 { 1050 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1051 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1052 }), 1053 }, 1054 { 1055 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1056 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 1057 }), 1058 }, 1059 }, 1060 }, 1061 }, 1062 }, 1063 false, 1064 }, 1065 { // 6 1066 &javascript.MemberExpression{ 1067 MemberExpression: &javascript.MemberExpression{ 1068 PrimaryExpression: &javascript.PrimaryExpression{ 1069 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1070 Expressions: []javascript.AssignmentExpression{ 1071 { 1072 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1073 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1074 }), 1075 }, 1076 }, 1077 }, 1078 }, 1079 }, 1080 IdentifierName: makeToken(javascript.TokenIdentifier, "b"), 1081 }, 1082 false, 1083 }, 1084 } { 1085 if isPE := meIsSinglePe(test.MemberExpression); isPE != test.IsSinglePE { 1086 t.Errorf("test %d: expecting meIsSinglePe to return %v, got %v", n+1, test.IsSinglePE, !test.IsSinglePE) 1087 } 1088 } 1089 } 1090 1091 func TestMEAsCE(t *testing.T) { 1092 for n, test := range [...]struct { 1093 MemberExpression *javascript.MemberExpression 1094 CallExpression *javascript.CallExpression 1095 }{ 1096 { // 1 1097 nil, 1098 nil, 1099 }, 1100 { // 2 1101 &javascript.MemberExpression{}, 1102 nil, 1103 }, 1104 { // 3 1105 &javascript.MemberExpression{ 1106 PrimaryExpression: &javascript.PrimaryExpression{ 1107 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1108 Expressions: []javascript.AssignmentExpression{ 1109 { 1110 ConditionalExpression: javascript.WrapConditional(&javascript.CallExpression{ 1111 MemberExpression: &javascript.MemberExpression{ 1112 PrimaryExpression: &javascript.PrimaryExpression{ 1113 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1114 }, 1115 }, 1116 Arguments: &javascript.Arguments{}, 1117 }), 1118 }, 1119 }, 1120 }, 1121 }, 1122 }, 1123 &javascript.CallExpression{ 1124 MemberExpression: &javascript.MemberExpression{ 1125 PrimaryExpression: &javascript.PrimaryExpression{ 1126 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1127 }, 1128 }, 1129 Arguments: &javascript.Arguments{}, 1130 }, 1131 }, 1132 { // 4 1133 &javascript.MemberExpression{ 1134 MemberExpression: &javascript.MemberExpression{ 1135 PrimaryExpression: &javascript.PrimaryExpression{ 1136 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1137 Expressions: []javascript.AssignmentExpression{ 1138 { 1139 ConditionalExpression: javascript.WrapConditional(&javascript.CallExpression{ 1140 MemberExpression: &javascript.MemberExpression{ 1141 PrimaryExpression: &javascript.PrimaryExpression{ 1142 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1143 }, 1144 }, 1145 Arguments: &javascript.Arguments{}, 1146 }), 1147 }, 1148 }, 1149 }, 1150 }, 1151 }, 1152 Arguments: &javascript.Arguments{}, 1153 }, 1154 nil, 1155 }, 1156 { // 5 1157 &javascript.MemberExpression{ 1158 MemberExpression: &javascript.MemberExpression{ 1159 PrimaryExpression: &javascript.PrimaryExpression{ 1160 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1161 Expressions: []javascript.AssignmentExpression{ 1162 { 1163 ConditionalExpression: javascript.WrapConditional(&javascript.CallExpression{ 1164 MemberExpression: &javascript.MemberExpression{ 1165 PrimaryExpression: &javascript.PrimaryExpression{ 1166 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1167 }, 1168 }, 1169 Arguments: &javascript.Arguments{}, 1170 }), 1171 }, 1172 }, 1173 }, 1174 }, 1175 }, 1176 IdentifierName: makeToken(javascript.TokenIdentifier, "b"), 1177 }, 1178 &javascript.CallExpression{ 1179 CallExpression: &javascript.CallExpression{ 1180 MemberExpression: &javascript.MemberExpression{ 1181 PrimaryExpression: &javascript.PrimaryExpression{ 1182 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1183 }, 1184 }, 1185 Arguments: &javascript.Arguments{}, 1186 }, 1187 IdentifierName: makeToken(javascript.TokenIdentifier, "b"), 1188 }, 1189 }, 1190 } { 1191 if ce := meAsCE(test.MemberExpression); !reflect.DeepEqual(ce, test.CallExpression) { 1192 t.Errorf("test %d: expecting %v, got %v", n+1, test.MemberExpression, ce) 1193 } 1194 } 1195 } 1196 1197 func TestIsStatementListItemExpression(t *testing.T) { 1198 for n, test := range [...]struct { 1199 StatementListItem *javascript.StatementListItem 1200 IsStatementListItemExpression bool 1201 }{ 1202 { // 1 1203 nil, 1204 false, 1205 }, 1206 { // 2 1207 &javascript.StatementListItem{}, 1208 false, 1209 }, 1210 { // 3 1211 &javascript.StatementListItem{ 1212 Declaration: &javascript.Declaration{}, 1213 }, 1214 false, 1215 }, 1216 { // 4 1217 &javascript.StatementListItem{ 1218 Statement: &javascript.Statement{ 1219 Type: javascript.StatementDebugger, 1220 }, 1221 }, 1222 false, 1223 }, 1224 { // 5 1225 &javascript.StatementListItem{ 1226 Statement: &javascript.Statement{ 1227 Type: javascript.StatementDebugger, 1228 }, 1229 }, 1230 false, 1231 }, 1232 { // 6 1233 &javascript.StatementListItem{ 1234 Statement: &javascript.Statement{ 1235 Type: javascript.StatementReturn, 1236 ExpressionStatement: &javascript.Expression{ 1237 Expressions: []javascript.AssignmentExpression{ 1238 { 1239 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1240 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1241 }), 1242 }, 1243 }, 1244 }, 1245 }, 1246 }, 1247 false, 1248 }, 1249 { // 7 1250 &javascript.StatementListItem{ 1251 Statement: &javascript.Statement{ 1252 ExpressionStatement: &javascript.Expression{ 1253 Expressions: []javascript.AssignmentExpression{ 1254 { 1255 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1256 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1257 }), 1258 }, 1259 }, 1260 }, 1261 }, 1262 }, 1263 true, 1264 }, 1265 } { 1266 if isStatementListItemExpression(test.StatementListItem) != test.IsStatementListItemExpression { 1267 t.Errorf("test %d: expecting return %v, got %v", n+1, test.IsStatementListItemExpression, !test.IsStatementListItemExpression) 1268 } 1269 } 1270 } 1271 1272 func TestleftMostLHS(t *testing.T) { 1273 for n, test := range [...]struct { 1274 Input javascript.ConditionalWrappable 1275 Output *javascript.LeftHandSideExpression 1276 }{ 1277 { // 1 1278 nil, 1279 nil, 1280 }, 1281 { // 2 1282 javascript.WrapConditional(&javascript.LeftHandSideExpression{ 1283 NewExpression: &javascript.NewExpression{}, 1284 }), 1285 &javascript.LeftHandSideExpression{ 1286 NewExpression: &javascript.NewExpression{}, 1287 }, 1288 }, 1289 { // 3 1290 javascript.WrapConditional(&javascript.AdditiveExpression{ 1291 MultiplicativeExpression: javascript.MultiplicativeExpression{ 1292 ExponentiationExpression: javascript.ExponentiationExpression{ 1293 UnaryExpression: javascript.UnaryExpression{ 1294 UpdateExpression: javascript.UpdateExpression{ 1295 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1296 CallExpression: &javascript.CallExpression{}, 1297 }, 1298 }, 1299 }, 1300 }, 1301 }, 1302 }), 1303 &javascript.LeftHandSideExpression{ 1304 CallExpression: &javascript.CallExpression{}, 1305 }, 1306 }, 1307 { // 4 1308 javascript.WrapConditional(&javascript.ExponentiationExpression{ 1309 ExponentiationExpression: &javascript.ExponentiationExpression{ 1310 UnaryExpression: javascript.UnaryExpression{ 1311 UpdateExpression: javascript.UpdateExpression{ 1312 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1313 NewExpression: &javascript.NewExpression{}, 1314 }, 1315 }, 1316 }, 1317 }, 1318 UnaryExpression: javascript.UnaryExpression{ 1319 UpdateExpression: javascript.UpdateExpression{ 1320 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1321 CallExpression: &javascript.CallExpression{}, 1322 }, 1323 }, 1324 }, 1325 }), 1326 &javascript.LeftHandSideExpression{ 1327 NewExpression: &javascript.NewExpression{}, 1328 }, 1329 }, 1330 { // 5 1331 javascript.WrapConditional(&javascript.ExponentiationExpression{ 1332 ExponentiationExpression: &javascript.ExponentiationExpression{ 1333 ExponentiationExpression: &javascript.ExponentiationExpression{ 1334 UnaryExpression: javascript.UnaryExpression{ 1335 UpdateExpression: javascript.UpdateExpression{ 1336 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1337 OptionalExpression: &javascript.OptionalExpression{}, 1338 }, 1339 }, 1340 }, 1341 }, 1342 UnaryExpression: javascript.UnaryExpression{ 1343 UpdateExpression: javascript.UpdateExpression{ 1344 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1345 NewExpression: &javascript.NewExpression{}, 1346 }, 1347 }, 1348 }, 1349 }, 1350 UnaryExpression: javascript.UnaryExpression{ 1351 UpdateExpression: javascript.UpdateExpression{ 1352 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1353 CallExpression: &javascript.CallExpression{}, 1354 }, 1355 }, 1356 }, 1357 }), 1358 &javascript.LeftHandSideExpression{ 1359 NewExpression: &javascript.NewExpression{}, 1360 }, 1361 }, 1362 } { 1363 if out := leftMostLHS(test.Input); !reflect.DeepEqual(out, test.Output) { 1364 t.Errorf("test %d: expecting %v, got %v", n+1, test.Output, out) 1365 } 1366 } 1367 } 1368 1369 func TestFixWrapping(t *testing.T) { 1370 for n, test := range [...]struct { 1371 Input, Output *javascript.Statement 1372 }{ 1373 { // 1 1374 nil, 1375 nil, 1376 }, 1377 { // 2 1378 &javascript.Statement{}, 1379 &javascript.Statement{}, 1380 }, 1381 { // 3 1382 &javascript.Statement{ 1383 BlockStatement: &javascript.Block{}, 1384 }, 1385 &javascript.Statement{ 1386 BlockStatement: &javascript.Block{}, 1387 }, 1388 }, 1389 { // 4 1390 &javascript.Statement{ 1391 ExpressionStatement: &javascript.Expression{}, 1392 }, 1393 &javascript.Statement{ 1394 ExpressionStatement: &javascript.Expression{}, 1395 }, 1396 }, 1397 { // 5 1398 &javascript.Statement{ 1399 ExpressionStatement: &javascript.Expression{ 1400 Expressions: []javascript.AssignmentExpression{ 1401 { 1402 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1403 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1404 }), 1405 }, 1406 }, 1407 }, 1408 }, 1409 &javascript.Statement{ 1410 ExpressionStatement: &javascript.Expression{ 1411 Expressions: []javascript.AssignmentExpression{ 1412 { 1413 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1414 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1415 }), 1416 }, 1417 }, 1418 }, 1419 }, 1420 }, 1421 { // 6 1422 &javascript.Statement{ 1423 ExpressionStatement: &javascript.Expression{ 1424 Expressions: []javascript.AssignmentExpression{ 1425 { 1426 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1427 ObjectLiteral: &javascript.ObjectLiteral{}, 1428 }), 1429 }, 1430 }, 1431 }, 1432 }, 1433 &javascript.Statement{ 1434 ExpressionStatement: &javascript.Expression{ 1435 Expressions: []javascript.AssignmentExpression{ 1436 { 1437 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1438 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1439 Expressions: []javascript.AssignmentExpression{ 1440 { 1441 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1442 ObjectLiteral: &javascript.ObjectLiteral{}, 1443 }), 1444 }, 1445 }, 1446 }, 1447 }), 1448 }, 1449 }, 1450 }, 1451 }, 1452 }, 1453 { // 7 1454 &javascript.Statement{ 1455 ExpressionStatement: &javascript.Expression{ 1456 Expressions: []javascript.AssignmentExpression{ 1457 { 1458 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1459 FunctionExpression: &javascript.FunctionDeclaration{}, 1460 }), 1461 }, 1462 { 1463 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1464 ObjectLiteral: &javascript.ObjectLiteral{}, 1465 }), 1466 }, 1467 }, 1468 }, 1469 }, 1470 &javascript.Statement{ 1471 ExpressionStatement: &javascript.Expression{ 1472 Expressions: []javascript.AssignmentExpression{ 1473 { 1474 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1475 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1476 Expressions: []javascript.AssignmentExpression{ 1477 { 1478 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1479 FunctionExpression: &javascript.FunctionDeclaration{}, 1480 }), 1481 }, 1482 }, 1483 }, 1484 }), 1485 }, 1486 { 1487 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1488 ObjectLiteral: &javascript.ObjectLiteral{}, 1489 }), 1490 }, 1491 }, 1492 }, 1493 }, 1494 }, 1495 } { 1496 fixWrapping(test.Input) 1497 if !reflect.DeepEqual(test.Input, test.Output) { 1498 t.Errorf("test %d: expecting %v, got %v", n+1, test.Output, test.Input) 1499 } 1500 } 1501 } 1502 1503 func TestScoreCE(t *testing.T) { 1504 for n, test := range [...]struct { 1505 Input javascript.ConditionalWrappable 1506 Output int 1507 }{ 1508 { // 1 1509 nil, 1510 -1, 1511 }, 1512 { // 2 1513 &javascript.LogicalORExpression{}, 1514 1, 1515 }, 1516 { // 3 1517 &javascript.EqualityExpression{}, 1518 6, 1519 }, 1520 { // 4 1521 &javascript.UpdateExpression{}, 1522 13, 1523 }, 1524 } { 1525 if out := scoreCE(test.Input); out != test.Output { 1526 t.Errorf("test %d: expecting %d, got %d", n+1, test.Output, out) 1527 } 1528 } 1529 } 1530 1531 func TestIsConditionalWrappingAConditional(t *testing.T) { 1532 for n, test := range [...]struct { 1533 Input, Below javascript.ConditionalWrappable 1534 Output *javascript.ConditionalExpression 1535 }{ 1536 { // 1 1537 nil, 1538 nil, 1539 nil, 1540 }, 1541 { // 2 1542 &javascript.PrimaryExpression{ 1543 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1544 }, 1545 nil, 1546 nil, 1547 }, 1548 { // 3 1549 &javascript.PrimaryExpression{ 1550 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1551 Expressions: []javascript.AssignmentExpression{ 1552 { 1553 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1554 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1555 }), 1556 }, 1557 }, 1558 }, 1559 }, 1560 nil, 1561 javascript.WrapConditional(&javascript.PrimaryExpression{ 1562 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1563 }), 1564 }, 1565 { // 4 1566 &javascript.PrimaryExpression{ 1567 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1568 Expressions: []javascript.AssignmentExpression{ 1569 { 1570 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1571 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1572 }), 1573 }, 1574 { 1575 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1576 IdentifierReference: makeToken(javascript.TokenIdentifier, "b"), 1577 }), 1578 }, 1579 }, 1580 }, 1581 }, 1582 nil, 1583 nil, 1584 }, 1585 { // 5 1586 &javascript.MultiplicativeExpression{ 1587 ExponentiationExpression: javascript.ExponentiationExpression{ 1588 UnaryExpression: javascript.UnaryExpression{ 1589 UpdateExpression: javascript.UpdateExpression{ 1590 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1591 NewExpression: &javascript.NewExpression{ 1592 MemberExpression: javascript.MemberExpression{ 1593 PrimaryExpression: &javascript.PrimaryExpression{ 1594 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1595 Expressions: []javascript.AssignmentExpression{ 1596 { 1597 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1598 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1599 }), 1600 }, 1601 }, 1602 }, 1603 }, 1604 }, 1605 }, 1606 }, 1607 }, 1608 }, 1609 }, 1610 }, 1611 nil, 1612 javascript.WrapConditional(&javascript.PrimaryExpression{ 1613 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1614 }), 1615 }, 1616 { // 6 1617 &javascript.MultiplicativeExpression{ 1618 ExponentiationExpression: javascript.ExponentiationExpression{ 1619 UnaryExpression: javascript.UnaryExpression{ 1620 UpdateExpression: javascript.UpdateExpression{ 1621 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1622 NewExpression: &javascript.NewExpression{ 1623 MemberExpression: javascript.MemberExpression{ 1624 PrimaryExpression: &javascript.PrimaryExpression{ 1625 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1626 Expressions: []javascript.AssignmentExpression{ 1627 { 1628 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1629 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1630 }), 1631 }, 1632 }, 1633 }, 1634 }, 1635 }, 1636 }, 1637 }, 1638 }, 1639 }, 1640 }, 1641 }, 1642 &javascript.AdditiveExpression{}, 1643 javascript.WrapConditional(&javascript.PrimaryExpression{ 1644 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1645 }), 1646 }, 1647 { // 7 1648 &javascript.MultiplicativeExpression{ 1649 ExponentiationExpression: javascript.ExponentiationExpression{ 1650 UnaryExpression: javascript.UnaryExpression{ 1651 UpdateExpression: javascript.UpdateExpression{ 1652 LeftHandSideExpression: &javascript.LeftHandSideExpression{ 1653 NewExpression: &javascript.NewExpression{ 1654 MemberExpression: javascript.MemberExpression{ 1655 PrimaryExpression: &javascript.PrimaryExpression{ 1656 ParenthesizedExpression: &javascript.ParenthesizedExpression{ 1657 Expressions: []javascript.AssignmentExpression{ 1658 { 1659 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1660 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1661 }), 1662 }, 1663 }, 1664 }, 1665 }, 1666 }, 1667 }, 1668 }, 1669 }, 1670 }, 1671 }, 1672 }, 1673 &javascript.ExponentiationExpression{}, 1674 javascript.WrapConditional(&javascript.PrimaryExpression{ 1675 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1676 }), 1677 }, 1678 } { 1679 if out := isConditionalWrappingAConditional(test.Input, test.Below); !reflect.DeepEqual(out, test.Output) { 1680 t.Errorf("test %d: expecting %v, got %v", n+1, test.Output, out) 1681 } 1682 } 1683 } 1684 1685 func TestRemoveLastReturnStatement(t *testing.T) { 1686 for n, test := range [...]struct { 1687 Input, Output *javascript.Block 1688 }{ 1689 { // 1 1690 nil, 1691 nil, 1692 }, 1693 { // 2 1694 &javascript.Block{}, 1695 &javascript.Block{}, 1696 }, 1697 { // 3 1698 &javascript.Block{ 1699 StatementList: []javascript.StatementListItem{ 1700 { 1701 Statement: &javascript.Statement{ 1702 ExpressionStatement: &javascript.Expression{ 1703 Expressions: []javascript.AssignmentExpression{ 1704 { 1705 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1706 IdentifierReference: makeToken(javascript.TokenLineTerminator, "a"), 1707 }), 1708 }, 1709 }, 1710 }, 1711 }, 1712 }, 1713 }, 1714 }, 1715 &javascript.Block{ 1716 StatementList: []javascript.StatementListItem{ 1717 { 1718 Statement: &javascript.Statement{ 1719 ExpressionStatement: &javascript.Expression{ 1720 Expressions: []javascript.AssignmentExpression{ 1721 { 1722 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1723 IdentifierReference: makeToken(javascript.TokenLineTerminator, "a"), 1724 }), 1725 }, 1726 }, 1727 }, 1728 }, 1729 }, 1730 }, 1731 }, 1732 }, 1733 { // 4 1734 &javascript.Block{ 1735 StatementList: []javascript.StatementListItem{ 1736 { 1737 Statement: &javascript.Statement{ 1738 Type: javascript.StatementReturn, 1739 }, 1740 }, 1741 }, 1742 }, 1743 &javascript.Block{ 1744 StatementList: []javascript.StatementListItem{}, 1745 }, 1746 }, 1747 { // 5 1748 &javascript.Block{ 1749 StatementList: []javascript.StatementListItem{ 1750 { 1751 Statement: &javascript.Statement{ 1752 ExpressionStatement: &javascript.Expression{ 1753 Expressions: []javascript.AssignmentExpression{ 1754 { 1755 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1756 IdentifierReference: makeToken(javascript.TokenLineTerminator, "a"), 1757 }), 1758 }, 1759 }, 1760 }, 1761 }, 1762 }, 1763 { 1764 Statement: &javascript.Statement{ 1765 Type: javascript.StatementReturn, 1766 }, 1767 }, 1768 }, 1769 }, 1770 &javascript.Block{ 1771 StatementList: []javascript.StatementListItem{ 1772 { 1773 Statement: &javascript.Statement{ 1774 ExpressionStatement: &javascript.Expression{ 1775 Expressions: []javascript.AssignmentExpression{ 1776 { 1777 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1778 IdentifierReference: makeToken(javascript.TokenLineTerminator, "a"), 1779 }), 1780 }, 1781 }, 1782 }, 1783 }, 1784 }, 1785 }, 1786 }, 1787 }, 1788 } { 1789 removeLastReturnStatement(test.Input) 1790 if !reflect.DeepEqual(test.Input, test.Output) { 1791 t.Errorf("test %d: expecting %b, got %v", n+1, test.Output, test.Input) 1792 } 1793 } 1794 } 1795 1796 func TestIsSimpleAE(t *testing.T) { 1797 for n, test := range [...]struct { 1798 Input *javascript.AssignmentExpression 1799 Output bool 1800 }{ 1801 { // 1 1802 nil, 1803 false, 1804 }, 1805 { // 2 1806 &javascript.AssignmentExpression{}, 1807 false, 1808 }, 1809 { // 3 1810 &javascript.AssignmentExpression{ 1811 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1812 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1813 }), 1814 }, 1815 true, 1816 }, 1817 { // 4 1818 &javascript.AssignmentExpression{ 1819 ConditionalExpression: javascript.WrapConditional(&javascript.PrimaryExpression{ 1820 Literal: makeToken(javascript.TokenNumericLiteral, "1"), 1821 }), 1822 }, 1823 true, 1824 }, 1825 { // 5 1826 &javascript.AssignmentExpression{ 1827 ConditionalExpression: javascript.WrapConditional(&javascript.CallExpression{ 1828 MemberExpression: &javascript.MemberExpression{ 1829 PrimaryExpression: &javascript.PrimaryExpression{ 1830 IdentifierReference: makeToken(javascript.TokenIdentifier, "a"), 1831 }, 1832 }, 1833 Arguments: &javascript.Arguments{}, 1834 }), 1835 }, 1836 false, 1837 }, 1838 } { 1839 if out := isSimpleAE(test.Input); out != test.Output { 1840 t.Errorf("test %d: expecting output %v, got %v", n+1, test.Output, out) 1841 } 1842 } 1843 } 1844