| OLD | NEW |
| 1 'use strict'; | 1 'use strict'; |
| 2 | 2 |
| 3 if (self.importScripts) { | 3 if (self.importScripts) { |
| 4 if ('ServiceWorkerGlobalScope' in self && self instanceof ServiceWorkerGlobalS
cope) { | 4 if ('ServiceWorkerGlobalScope' in self && self instanceof ServiceWorkerGlobalS
cope) { |
| 5 importScripts('../../serviceworker/resources/worker-testharness.js'); | 5 importScripts('../../serviceworker/resources/worker-testharness.js'); |
| 6 } else { | 6 } else { |
| 7 importScripts('../../resources/testharness.js'); | 7 importScripts('../../resources/testharness.js'); |
| 8 } | 8 } |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 postMessageTask(function() { | 264 postMessageTask(function() { |
| 265 p = Promise.resolve().then(function() { | 265 p = Promise.resolve().then(function() { |
| 266 return Promise.reject(e); | 266 return Promise.reject(e); |
| 267 }) | 267 }) |
| 268 .catch(function() {}); | 268 .catch(function() {}); |
| 269 }); | 269 }); |
| 270 }, 'no unhandledrejection/rejectionhandled: all inside a queued task, a rejectio
n handler attached synchronously to ' + | 270 }, 'no unhandledrejection/rejectionhandled: all inside a queued task, a rejectio
n handler attached synchronously to ' + |
| 271 'a promise created from returning a Promise.reject-created promise in a fulfi
llment handler'); | 271 'a promise created from returning a Promise.reject-created promise in a fulfi
llment handler'); |
| 272 | 272 |
| 273 // | 273 // |
| 274 // Negative unhandledrejection/rejectionhandled tests with delayed attachment | 274 // Negative unhandledrejection/rejectionhandled tests with microtask-delayed att
achment |
| 275 // | 275 // |
| 276 | 276 |
| 277 async_test(function(t) { | 277 async_test(function(t) { |
| 278 var e = new Error(); | 278 var e = new Error(); |
| 279 var p; | 279 var p; |
| 280 | 280 |
| 281 onUnhandledFail(t, function() { return p; }); | 281 onUnhandledFail(t, function() { return p; }); |
| 282 | 282 |
| 283 p = Promise.reject(e); | 283 p = Promise.reject(e); |
| 284 mutationObserverMicrotask(function() { | 284 mutationObserverMicrotask(function() { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 p.catch(function() {}); | 443 p.catch(function() {}); |
| 444 }); | 444 }); |
| 445 }); | 445 }); |
| 446 }); | 446 }); |
| 447 }); | 447 }); |
| 448 }, 0); | 448 }, 0); |
| 449 }, 'microtask nesting: attaching a handler inside a combination of promise micro
tasks + mutationObserverMicrotask, ' + | 449 }, 'microtask nesting: attaching a handler inside a combination of promise micro
tasks + mutationObserverMicrotask, ' + |
| 450 'all inside a setTimeout'); | 450 'all inside a setTimeout'); |
| 451 | 451 |
| 452 // | 452 // |
| 453 // Positive unhandledrejection/rejectionhandled tests with delayed attachment | 453 // Negative unhandledrejection/rejectionhandled tests with task-delayed attachme
nt |
| 454 // | 454 // |
| 455 | 455 |
| 456 async_test(function(t) { | 456 async_test(function(t) { |
| 457 var e = new Error(); | 457 var e = new Error(); |
| 458 var p; | 458 var p; |
| 459 | 459 |
| 460 onUnhandledSucceed(t, e, function() { return p; }); | 460 onUnhandledFail(t, function() { return p; }); |
| 461 | 461 |
| 462 var _reject; | 462 var _reject; |
| 463 p = new Promise(function(_, reject) { | 463 p = new Promise(function(_, reject) { |
| 464 _reject = reject; | 464 _reject = reject; |
| 465 }); | 465 }); |
| 466 _reject(e); | 466 _reject(e); |
| 467 postMessageTask(function() { | 467 postMessageTask(function() { |
| 468 var unreached = t.unreached_func('promise should not be fulfilled'); | 468 var unreached = t.unreached_func('promise should not be fulfilled'); |
| 469 p.then(unreached, function() {}); | 469 p.then(unreached, function() {}); |
| 470 }); | 470 }); |
| 471 }, 'delayed handling: a task delay before attaching a handler does not prevent u
nhandledrejection'); | 471 }, 'delayed handling: a task delay before attaching a handler prevents unhandled
rejection'); |
| 472 | 472 |
| 473 async_test(function(t) { | 473 async_test(function(t) { |
| 474 var unhandledPromises = []; | |
| 475 var unhandledReasons = []; | |
| 476 var e = new Error(); | 474 var e = new Error(); |
| 477 var p; | 475 var p; |
| 478 | 476 |
| 479 var unhandled = function(ev) { | 477 onUnhandledFail(t, function() { return p; }); |
| 480 if (ev.promise === p) { | |
| 481 t.step(function() { | |
| 482 unhandledPromises.push(ev.promise); | |
| 483 unhandledReasons.push(ev.reason); | |
| 484 }); | |
| 485 } | |
| 486 }; | |
| 487 var handled = function(ev) { | |
| 488 if (ev.promise === p) { | |
| 489 t.step(function() { | |
| 490 assert_array_equals(unhandledPromises, [p]); | |
| 491 assert_array_equals(unhandledReasons, [e]); | |
| 492 assert_equals(ev.promise, p); | |
| 493 assert_equals(ev.reason, e); | |
| 494 }); | |
| 495 } | |
| 496 }; | |
| 497 addEventListener('unhandledrejection', unhandled); | |
| 498 addEventListener('rejectionhandled', handled); | |
| 499 ensureCleanup(t, unhandled, handled); | |
| 500 | 478 |
| 501 p = new Promise(function() { | 479 p = Promise.reject(e); |
| 502 throw e; | 480 postMessageTask(function() { |
| 481 Promise.resolve().then(function() { |
| 482 p.catch(function() {}); |
| 483 }); |
| 503 }); | 484 }); |
| 504 setTimeout(function() { | 485 }, 'delayed handling: postMessageTask after promise creation/rejection, plus pro
mise microtasks, is not too late to ' + |
| 505 var unreached = t.unreached_func('promise should not be fulfilled'); | 486 'attach a rejection handler'); |
| 506 p.then(unreached, function(reason) { | |
| 507 assert_equals(reason, e); | |
| 508 setTimeout(function() { t.done(); }, 10); | |
| 509 }); | |
| 510 }, 10); | |
| 511 }, 'delayed handling: delaying handling by setTimeout(,10) will cause both event
s to fire'); | |
| 512 | 487 |
| 513 async_test(function(t) { | 488 async_test(function(t) { |
| 514 var e = new Error(); | 489 var e = new Error(); |
| 490 var p; |
| 491 |
| 492 onUnhandledFail(t, function() { return p; }); |
| 493 |
| 494 postMessageTask(function() { |
| 495 Promise.resolve().then(function() { |
| 496 Promise.resolve().then(function() { |
| 497 Promise.resolve().then(function() { |
| 498 Promise.resolve().then(function() { |
| 499 p.catch(function() {}); |
| 500 }); |
| 501 }); |
| 502 }); |
| 503 }); |
| 504 }); |
| 505 p = Promise.reject(e); |
| 506 }, 'delayed handling: postMessageTask before promise creation/rejection, plus ma
ny promise microtasks, is not too ' + |
| 507 'late to attach a rejection handler'); |
| 508 |
| 509 async_test(function(t) { |
| 510 var e = new Error(); |
| 511 var p; |
| 512 |
| 513 onUnhandledFail(t, function() { return p; }); |
| 514 |
| 515 p = Promise.reject(e); |
| 516 postMessageTask(function() { |
| 517 Promise.resolve().then(function() { |
| 518 Promise.resolve().then(function() { |
| 519 Promise.resolve().then(function() { |
| 520 Promise.resolve().then(function() { |
| 521 p.catch(function() {}); |
| 522 }); |
| 523 }); |
| 524 }); |
| 525 }); |
| 526 }); |
| 527 }, 'delayed handling: postMessageTask after promise creation/rejection, plus man
y promise microtasks, is not too ' + |
| 528 'late to attach a rejection handler'); |
| 529 |
| 530 // |
| 531 // Positive unhandledrejection/rejectionhandled tests with delayed attachment |
| 532 // |
| 533 |
| 534 async_test(function(t) { |
| 535 var e = new Error(); |
| 536 var p; |
| 537 |
| 538 onUnhandledSucceed(t, e, function() { return p; }); |
| 539 |
| 540 var _reject; |
| 541 p = new Promise(function(_, reject) { |
| 542 _reject = reject; |
| 543 }); |
| 544 _reject(e); |
| 545 postMessageTask(function() { |
| 546 postMessageTask(function() { |
| 547 var unreached = t.unreached_func('promise should not be fulfilled'); |
| 548 p.then(unreached, function() {}); |
| 549 }); |
| 550 }); |
| 551 }, 'delayed handling: a nested-task delay before attaching a handler causes unha
ndledrejection'); |
| 552 |
| 553 async_test(function(t) { |
| 554 var e = new Error(); |
| 515 var p; | 555 var p; |
| 516 | 556 |
| 517 onUnhandledSucceed(t, e, function() { return p; }); | 557 onUnhandledSucceed(t, e, function() { return p; }); |
| 518 | 558 |
| 519 p = Promise.reject(e); | 559 p = Promise.reject(e); |
| 520 postMessageTask(function() { | 560 postMessageTask(function() { |
| 521 Promise.resolve().then(function() { | 561 postMessageTask(function() { |
| 522 p.catch(function() {}); | 562 Promise.resolve().then(function() { |
| 563 p.catch(function() {}); |
| 564 }); |
| 523 }); | 565 }); |
| 524 }); | 566 }); |
| 525 }, 'delayed handling: postMessageTask after promise creation/rejection, plus pro
mise microtasks, is too late to ' + | 567 }, 'delayed handling: a nested-postMessageTask after promise creation/rejection,
plus promise microtasks, is too ' + |
| 526 'attach a rejection handler'); | 568 'late to attach a rejection handler'); |
| 527 | 569 |
| 528 async_test(function(t) { | 570 async_test(function(t) { |
| 529 var e = new Error(); | 571 var e = new Error(); |
| 530 var p; | 572 var p; |
| 531 | 573 |
| 532 onUnhandledSucceed(t, e, function() { return p; }); | 574 onUnhandledSucceed(t, e, function() { return p; }); |
| 575 |
| 533 postMessageTask(function() { | 576 postMessageTask(function() { |
| 534 Promise.resolve().then(function() { | 577 postMessageTask(function() { |
| 535 Promise.resolve().then(function() { | 578 Promise.resolve().then(function() { |
| 536 Promise.resolve().then(function() { | 579 Promise.resolve().then(function() { |
| 537 Promise.resolve().then(function() { | 580 Promise.resolve().then(function() { |
| 538 p.catch(function() {}); | 581 Promise.resolve().then(function() { |
| 582 p.catch(function() {}); |
| 583 }); |
| 539 }); | 584 }); |
| 540 }); | 585 }); |
| 541 }); | 586 }); |
| 542 }); | 587 }); |
| 543 }); | 588 }); |
| 544 p = Promise.reject(e); | 589 p = Promise.reject(e); |
| 545 }, 'delayed handling: postMessageTask before promise creation/rejection, plus ma
ny promise microtasks, is too late ' + | 590 }, 'delayed handling: a nested-postMessageTask before promise creation/rejection
, plus many promise microtasks, is ' + |
| 546 'to attach a rejection handler'); | 591 'too late to attach a rejection handler'); |
| 547 | 592 |
| 548 async_test(function(t) { | 593 async_test(function(t) { |
| 549 var e = new Error(); | 594 var e = new Error(); |
| 550 var p; | 595 var p; |
| 551 | 596 |
| 552 onUnhandledSucceed(t, e, function() { return p; }); | 597 onUnhandledSucceed(t, e, function() { return p; }); |
| 553 | 598 |
| 554 p = Promise.reject(e); | 599 p = Promise.reject(e); |
| 555 postMessageTask(function() { | 600 postMessageTask(function() { |
| 556 Promise.resolve().then(function() { | 601 postMessageTask(function() { |
| 557 Promise.resolve().then(function() { | 602 Promise.resolve().then(function() { |
| 558 Promise.resolve().then(function() { | 603 Promise.resolve().then(function() { |
| 559 Promise.resolve().then(function() { | 604 Promise.resolve().then(function() { |
| 560 p.catch(function() {}); | 605 Promise.resolve().then(function() { |
| 606 p.catch(function() {}); |
| 607 }); |
| 561 }); | 608 }); |
| 562 }); | 609 }); |
| 563 }); | 610 }); |
| 564 }); | 611 }); |
| 565 }); | 612 }); |
| 566 }, 'delayed handling: postMessageTask after promise creation/rejection, plus man
y promise microtasks, is too late ' + | 613 }, 'delayed handling: a nested-postMessageTask after promise creation/rejection,
plus many promise microtasks, is ' + |
| 567 'to attach a rejection handler'); | 614 'too late to attach a rejection handler'); |
| 615 |
| 616 async_test(function(t) { |
| 617 var unhandledPromises = []; |
| 618 var unhandledReasons = []; |
| 619 var e = new Error(); |
| 620 var p; |
| 621 |
| 622 var unhandled = function(ev) { |
| 623 if (ev.promise === p) { |
| 624 t.step(function() { |
| 625 unhandledPromises.push(ev.promise); |
| 626 unhandledReasons.push(ev.reason); |
| 627 }); |
| 628 } |
| 629 }; |
| 630 var handled = function(ev) { |
| 631 if (ev.promise === p) { |
| 632 t.step(function() { |
| 633 assert_array_equals(unhandledPromises, [p]); |
| 634 assert_array_equals(unhandledReasons, [e]); |
| 635 assert_equals(ev.promise, p); |
| 636 assert_equals(ev.reason, e); |
| 637 }); |
| 638 } |
| 639 }; |
| 640 addEventListener('unhandledrejection', unhandled); |
| 641 addEventListener('rejectionhandled', handled); |
| 642 ensureCleanup(t, unhandled, handled); |
| 643 |
| 644 p = new Promise(function() { |
| 645 throw e; |
| 646 }); |
| 647 setTimeout(function() { |
| 648 var unreached = t.unreached_func('promise should not be fulfilled'); |
| 649 p.then(unreached, function(reason) { |
| 650 assert_equals(reason, e); |
| 651 setTimeout(function() { t.done(); }, 10); |
| 652 }); |
| 653 }, 10); |
| 654 }, 'delayed handling: delaying handling by setTimeout(,10) will cause both event
s to fire'); |
| 568 | 655 |
| 569 // | 656 // |
| 570 // Miscellaneous tests about integration with the rest of the platform | 657 // Miscellaneous tests about integration with the rest of the platform |
| 571 // | 658 // |
| 572 | 659 |
| 573 async_test(function(t) { | 660 async_test(function(t) { |
| 574 var e = new Error(); | 661 var e = new Error(); |
| 575 var l = function(ev) { | 662 var l = function(ev) { |
| 576 var order = []; | 663 var order = []; |
| 577 mutationObserverMicrotask(function() { | 664 mutationObserverMicrotask(function() { |
| 578 order.push(1); | 665 order.push(1); |
| 579 }); | 666 }); |
| 580 setTimeout(function() { | 667 setTimeout(function() { |
| 581 order.push(2); | 668 order.push(2); |
| 582 t.step(function() { | 669 t.step(function() { |
| 583 assert_array_equals(order, [1, 2]); | 670 assert_array_equals(order, [1, 2]); |
| 584 }); | 671 }); |
| 585 t.done(); | 672 t.done(); |
| 586 }, 1); | 673 }, 1); |
| 587 }; | 674 }; |
| 588 addEventListener('unhandledrejection', l); | 675 addEventListener('unhandledrejection', l); |
| 589 ensureCleanup(t, l); | 676 ensureCleanup(t, l); |
| 590 Promise.reject(e); | 677 Promise.reject(e); |
| 591 }, 'mutationObserverMicrotask vs. postMessageTask ordering is not disturbed insi
de unhandledrejection events'); | 678 }, 'mutationObserverMicrotask vs. postMessageTask ordering is not disturbed insi
de unhandledrejection events'); |
| 592 | 679 |
| 680 // For workers, postMessageTask() involves posting tasks to other threads, so |
| 681 // the following tests don't work there. |
| 682 |
| 683 if ('document' in self) { |
| 684 |
| 685 // For the next two see https://github.com/domenic/unhandled-rejections-browse
r-spec/issues/2#issuecomment-121121695 |
| 686 // and the following comments. |
| 687 |
| 688 async_test(function(t) { |
| 689 var sequenceOfEvents = []; |
| 690 |
| 691 addEventListener('unhandledrejection', l); |
| 692 ensureCleanup(t, l); |
| 693 |
| 694 var p1 = Promise.reject(); |
| 695 var p2; |
| 696 postMessageTask(function() { |
| 697 p2 = Promise.reject(); |
| 698 postMessageTask(function() { |
| 699 sequenceOfEvents.push('postMessageTask'); |
| 700 checkSequence(); |
| 701 }); |
| 702 }); |
| 703 |
| 704 function l(ev) { |
| 705 if (ev.promise === p1 || ev.promise === p2) { |
| 706 sequenceOfEvents.push(ev.promise); |
| 707 checkSequence(); |
| 708 } |
| 709 } |
| 710 |
| 711 function checkSequence() { |
| 712 if (sequenceOfEvents.length === 3) { |
| 713 t.step(function() { |
| 714 assert_array_equals(sequenceOfEvents, [p1, 'postMessageTask', p2]); |
| 715 }); |
| 716 t.done(); |
| 717 } |
| 718 } |
| 719 }, 'postMessageTask ordering vs. the task queued for unhandled rejection notif
ication (1)'); |
| 720 |
| 721 async_test(function(t) { |
| 722 var sequenceOfEvents = []; |
| 723 |
| 724 addEventListener('unhandledrejection', l); |
| 725 ensureCleanup(t, l); |
| 726 |
| 727 var p2; |
| 728 postMessageTask(function() { |
| 729 p2 = Promise.reject(); |
| 730 postMessageTask(function() { |
| 731 sequenceOfEvents.push('postMessageTask'); |
| 732 checkSequence(); |
| 733 }); |
| 734 }); |
| 735 |
| 736 function l(ev) { |
| 737 if (ev.promise == p2) { |
| 738 sequenceOfEvents.push(ev.promise); |
| 739 checkSequence(); |
| 740 } |
| 741 } |
| 742 |
| 743 function checkSequence() { |
| 744 if (sequenceOfEvents.length === 2) { |
| 745 t.step(function() { |
| 746 assert_array_equals(sequenceOfEvents, ['postMessageTask', p2]); |
| 747 }); |
| 748 t.done(); |
| 749 } |
| 750 } |
| 751 }, 'postMessageTask ordering vs. the task queued for unhandled rejection notif
ication (2)'); |
| 752 |
| 753 async_test(function(t) { |
| 754 var sequenceOfEvents = []; |
| 755 |
| 756 |
| 757 addEventListener('unhandledrejection', unhandled); |
| 758 addEventListener('rejectionhandled', handled); |
| 759 ensureCleanup(t, unhandled, handled); |
| 760 |
| 761 var p = Promise.reject(); |
| 762 |
| 763 setTimeout(function() { |
| 764 postMessageTask(function() { |
| 765 sequenceOfEvents.push('task before catch'); |
| 766 checkSequence(); |
| 767 }); |
| 768 |
| 769 p.catch(function() { |
| 770 sequenceOfEvents.push('catch'); |
| 771 checkSequence(); |
| 772 }); |
| 773 |
| 774 postMessageTask(function() { |
| 775 sequenceOfEvents.push('task after catch'); |
| 776 checkSequence(); |
| 777 }); |
| 778 |
| 779 sequenceOfEvents.push('after catch'); |
| 780 checkSequence(); |
| 781 }, 10); |
| 782 |
| 783 function unhandled(ev) { |
| 784 if (ev.promise === p) { |
| 785 sequenceOfEvents.push('unhandled'); |
| 786 checkSequence(); |
| 787 } |
| 788 } |
| 789 |
| 790 function handled(ev) { |
| 791 if (ev.promise === p) { |
| 792 sequenceOfEvents.push('handled'); |
| 793 checkSequence(); |
| 794 } |
| 795 } |
| 796 |
| 797 function checkSequence() { |
| 798 if (sequenceOfEvents.length === 6) { |
| 799 t.step(function() { |
| 800 assert_array_equals(sequenceOfEvents, |
| 801 ['unhandled', 'after catch', 'catch', 'task before catch', 'handled'
, 'task after catch']); |
| 802 }); |
| 803 t.done(); |
| 804 } |
| 805 } |
| 806 }, 'rejectionhandled is dispatched from a queued task, and not immediately'); |
| 807 } |
| 808 |
| 593 // | 809 // |
| 594 // HELPERS | 810 // HELPERS |
| 595 // | 811 // |
| 596 | 812 |
| 813 var globalPostMessageCounter = 0; |
| 814 |
| 597 function postMessageTask(f) { | 815 function postMessageTask(f) { |
| 598 if ('document' in self) { | 816 if ('document' in self) { |
| 599 var l = function() { | 817 var message = 'abusingpostmessageforfunandprofit' + globalPostMessageCounter
; |
| 600 removeEventListener('message', l); | 818 globalPostMessageCounter++; |
| 601 f(); | 819 var l = function(ev) { |
| 820 if (ev.data === message) { |
| 821 removeEventListener('message', l); |
| 822 f(); |
| 823 } |
| 602 }; | 824 }; |
| 603 addEventListener('message', l); | 825 addEventListener('message', l); |
| 604 postMessage('abusingpostmessageforfunandprofit', '*'); | 826 postMessage(message, '*'); |
| 605 } else { | 827 } else { |
| 606 var channel = new MessageChannel(); | 828 var channel = new MessageChannel(); |
| 607 channel.port1.onmessage = function() { channel.port1.close(); f(); }; | 829 channel.port1.onmessage = function() { channel.port1.close(); f(); }; |
| 608 channel.port2.postMessage('abusingpostmessageforfunandprofit'); | 830 channel.port2.postMessage('abusingpostmessageforfunandprofit'); |
| 609 channel.port2.close(); | 831 channel.port2.close(); |
| 610 } | 832 } |
| 611 } | 833 } |
| 612 | 834 |
| 613 function mutationObserverMicrotask(f) { | 835 function mutationObserverMicrotask(f) { |
| 614 if ('document' in self) { | 836 if ('document' in self) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 function ensureCleanup(t, unhandled, handled) { | 881 function ensureCleanup(t, unhandled, handled) { |
| 660 t.add_cleanup(function() { | 882 t.add_cleanup(function() { |
| 661 if (unhandled) | 883 if (unhandled) |
| 662 removeEventListener('unhandledrejection', unhandled); | 884 removeEventListener('unhandledrejection', unhandled); |
| 663 if (handled) | 885 if (handled) |
| 664 removeEventListener('rejectionhandled', handled); | 886 removeEventListener('rejectionhandled', handled); |
| 665 }); | 887 }); |
| 666 } | 888 } |
| 667 | 889 |
| 668 done(); | 890 done(); |
| OLD | NEW |