Index: third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/support/promise-rejection-events.js |
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/support/promise-rejection-events.js b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/support/promise-rejection-events.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0de39f695ab6381aa2216cbb37a6427d94b6043d |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/support/promise-rejection-events.js |
@@ -0,0 +1,900 @@ |
+'use strict'; |
+ |
+if (self.importScripts) { |
+ importScripts('/resources/testharness.js'); |
+} |
+ |
+setup({ |
+ allow_uncaught_exception: true |
+}); |
+ |
+// |
+// Straightforward unhandledrejection tests |
+// |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = Promise.reject(e); |
+}, 'unhandledrejection: from Promise.reject'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = new Promise(function(_, reject) { |
+ reject(e); |
+ }); |
+}, 'unhandledrejection: from a synchronous rejection in new Promise'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = new Promise(function(_, reject) { |
+ postMessageTask(function() { |
+ reject(e); |
+ }); |
+ }); |
+}, 'unhandledrejection: from a task-delayed rejection'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = new Promise(function(_, reject) { |
+ setTimeout(function() { |
+ reject(e); |
+ }, 1); |
+ }); |
+}, 'unhandledrejection: from a setTimeout-delayed rejection'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var e2 = new Error(); |
+ var promise2; |
+ |
+ onUnhandledSucceed(t, e2, function() { return promise2; }); |
+ |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ promise2 = Promise.reject(e).then(unreached, function(reason) { |
+ t.step(function() { |
+ assert_equals(reason, e); |
+ }); |
+ throw e2; |
+ }); |
+}, 'unhandledrejection: from a throw in a rejection handler chained off of Promise.reject'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var e2 = new Error(); |
+ var promise2; |
+ |
+ onUnhandledSucceed(t, e2, function() { return promise2; }); |
+ |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ promise2 = new Promise(function(_, reject) { |
+ setTimeout(function() { |
+ reject(e); |
+ }, 1); |
+ }).then(unreached, function(reason) { |
+ t.step(function() { |
+ assert_equals(reason, e); |
+ }); |
+ throw e2; |
+ }); |
+}, 'unhandledrejection: from a throw in a rejection handler chained off of a setTimeout-delayed rejection'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var e2 = new Error(); |
+ var promise2; |
+ |
+ onUnhandledSucceed(t, e2, function() { return promise2; }); |
+ |
+ var promise = new Promise(function(_, reject) { |
+ setTimeout(function() { |
+ reject(e); |
+ mutationObserverMicrotask(function() { |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ promise2 = promise.then(unreached, function(reason) { |
+ t.step(function() { |
+ assert_equals(reason, e); |
+ }); |
+ throw e2; |
+ }); |
+ }); |
+ }, 1); |
+ }); |
+}, 'unhandledrejection: from a throw in a rejection handler attached one microtask after a setTimeout-delayed rejection'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = Promise.resolve().then(function() { |
+ return Promise.reject(e); |
+ }); |
+}, 'unhandledrejection: from returning a Promise.reject-created rejection in a fulfillment handler'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = Promise.resolve().then(function() { |
+ throw e; |
+ }); |
+}, 'unhandledrejection: from a throw in a fulfillment handler'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = Promise.resolve().then(function() { |
+ return new Promise(function(_, reject) { |
+ setTimeout(function() { |
+ reject(e); |
+ }, 1); |
+ }); |
+ }); |
+}, 'unhandledrejection: from returning a setTimeout-delayed rejection in a fulfillment handler'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = Promise.all([Promise.reject(e)]); |
+}, 'unhandledrejection: from Promise.reject, indirected through Promise.all'); |
+ |
+// |
+// Negative unhandledrejection/rejectionhandled tests with immediate attachment |
+// |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p = Promise.reject(e).then(unreached, function() {}); |
+}, 'no unhandledrejection/rejectionhandled: rejection handler attached synchronously to a promise from Promise.reject'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p = Promise.all([Promise.reject(e)]).then(unreached, function() {}); |
+}, 'no unhandledrejection/rejectionhandled: rejection handler attached synchronously to a promise from ' + |
+ 'Promise.reject, indirecting through Promise.all'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p = new Promise(function(_, reject) { |
+ reject(e); |
+ }).then(unreached, function() {}); |
+}, 'no unhandledrejection/rejectionhandled: rejection handler attached synchronously to a synchronously-rejected ' + |
+ 'promise created with new Promise'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p = Promise.resolve().then(function() { |
+ throw e; |
+ }).then(unreached, function(reason) { |
+ t.step(function() { |
+ assert_equals(reason, e); |
+ }); |
+ }); |
+}, 'no unhandledrejection/rejectionhandled: rejection handler attached synchronously to a promise created from ' + |
+ 'throwing in a fulfillment handler'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p = Promise.resolve().then(function() { |
+ return Promise.reject(e); |
+ }).then(unreached, function(reason) { |
+ t.step(function() { |
+ assert_equals(reason, e); |
+ }); |
+ }); |
+}, 'no unhandledrejection/rejectionhandled: rejection handler attached synchronously to a promise created from ' + |
+ 'returning a Promise.reject-created promise in a fulfillment handler'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p = Promise.resolve().then(function() { |
+ return new Promise(function(_, reject) { |
+ setTimeout(function() { |
+ reject(e); |
+ }, 1); |
+ }); |
+ }).then(unreached, function(reason) { |
+ t.step(function() { |
+ assert_equals(reason, e); |
+ }); |
+ }); |
+}, 'no unhandledrejection/rejectionhandled: rejection handler attached synchronously to a promise created from ' + |
+ 'returning a setTimeout-delayed rejection in a fulfillment handler'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ postMessageTask(function() { |
+ p = Promise.resolve().then(function() { |
+ return Promise.reject(e); |
+ }) |
+ .catch(function() {}); |
+ }); |
+}, 'no unhandledrejection/rejectionhandled: all inside a queued task, a rejection handler attached synchronously to ' + |
+ 'a promise created from returning a Promise.reject-created promise in a fulfillment handler'); |
+ |
+// |
+// Negative unhandledrejection/rejectionhandled tests with microtask-delayed attachment |
+// |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ p = Promise.reject(e); |
+ mutationObserverMicrotask(function() { |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p.then(unreached, function() {}); |
+ }); |
+}, 'delayed handling: a microtask delay before attaching a handler prevents both events (Promise.reject-created ' + |
+ 'promise)'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ p = new Promise(function(_, reject) { |
+ reject(e); |
+ }); |
+ mutationObserverMicrotask(function() { |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p.then(unreached, function() {}); |
+ }); |
+}, 'delayed handling: a microtask delay before attaching a handler prevents both events (immediately-rejected new ' + |
+ 'Promise-created promise)'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p1; |
+ var p2; |
+ |
+ onUnhandledFail(t, function() { return p1; }); |
+ onUnhandledFail(t, function() { return p2; }); |
+ |
+ p1 = new Promise(function(_, reject) { |
+ mutationObserverMicrotask(function() { |
+ reject(e); |
+ }); |
+ }); |
+ p2 = Promise.all([p1]); |
+ mutationObserverMicrotask(function() { |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p2.then(unreached, function() {}); |
+ }); |
+}, 'delayed handling: a microtask delay before attaching the handler, and before rejecting the promise, indirected ' + |
+ 'through Promise.all'); |
+ |
+// |
+// Negative unhandledrejection/rejectionhandled tests with nested-microtask-delayed attachment |
+// |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ p = Promise.reject(e); |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+}, 'microtask nesting: attaching a handler inside a combination of mutationObserverMicrotask + promise microtasks'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ postMessageTask(function() { |
+ p = Promise.reject(e); |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+}, 'microtask nesting: attaching a handler inside a combination of mutationObserverMicrotask + promise microtasks, ' + |
+ 'all inside a postMessageTask'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ setTimeout(function() { |
+ p = Promise.reject(e); |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }, 0); |
+}, 'microtask nesting: attaching a handler inside a combination of mutationObserverMicrotask + promise microtasks, ' + |
+ 'all inside a setTimeout'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ p = Promise.reject(e); |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+}, 'microtask nesting: attaching a handler inside a combination of promise microtasks + mutationObserverMicrotask'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ postMessageTask(function() { |
+ p = Promise.reject(e); |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+}, 'microtask nesting: attaching a handler inside a combination of promise microtasks + mutationObserverMicrotask, ' + |
+ 'all inside a postMessageTask'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ setTimeout(function() { |
+ p = Promise.reject(e); |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ Promise.resolve().then(function() { |
+ mutationObserverMicrotask(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }, 0); |
+}, 'microtask nesting: attaching a handler inside a combination of promise microtasks + mutationObserverMicrotask, ' + |
+ 'all inside a setTimeout'); |
+ |
+ |
+// For workers, postMessageTask() involves posting tasks to other threads, so |
+// the following tests don't work there. |
+ |
+if ('document' in self) { |
+ // |
+ // Negative unhandledrejection/rejectionhandled tests with task-delayed attachment |
+ // |
+ |
+ async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ var _reject; |
+ p = new Promise(function(_, reject) { |
+ _reject = reject; |
+ }); |
+ _reject(e); |
+ postMessageTask(function() { |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p.then(unreached, function() {}); |
+ }); |
+ }, 'delayed handling: a task delay before attaching a handler prevents unhandledrejection'); |
+ |
+ async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ p = Promise.reject(e); |
+ postMessageTask(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }, 'delayed handling: postMessageTask after promise creation/rejection, plus promise microtasks, is not too late to ' + |
+ 'attach a rejection handler'); |
+ |
+ async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ postMessageTask(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+ p = Promise.reject(e); |
+ }, 'delayed handling: postMessageTask before promise creation/rejection, plus many promise microtasks, is not too ' + |
+ 'late to attach a rejection handler'); |
+ |
+ async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledFail(t, function() { return p; }); |
+ |
+ p = Promise.reject(e); |
+ postMessageTask(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }, 'delayed handling: postMessageTask after promise creation/rejection, plus many promise microtasks, is not too ' + |
+ 'late to attach a rejection handler'); |
+} |
+ |
+// |
+// Positive unhandledrejection/rejectionhandled tests with delayed attachment |
+// |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ var _reject; |
+ p = new Promise(function(_, reject) { |
+ _reject = reject; |
+ }); |
+ _reject(e); |
+ postMessageTask(function() { |
+ postMessageTask(function() { |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p.then(unreached, function() {}); |
+ }); |
+ }); |
+}, 'delayed handling: a nested-task delay before attaching a handler causes unhandledrejection'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = Promise.reject(e); |
+ postMessageTask(function() { |
+ postMessageTask(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+}, 'delayed handling: a nested-postMessageTask after promise creation/rejection, plus promise microtasks, is too ' + |
+ 'late to attach a rejection handler'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ postMessageTask(function() { |
+ postMessageTask(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+ p = Promise.reject(e); |
+}, 'delayed handling: a nested-postMessageTask before promise creation/rejection, plus many promise microtasks, is ' + |
+ 'too late to attach a rejection handler'); |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var p; |
+ |
+ onUnhandledSucceed(t, e, function() { return p; }); |
+ |
+ p = Promise.reject(e); |
+ postMessageTask(function() { |
+ postMessageTask(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ Promise.resolve().then(function() { |
+ p.catch(function() {}); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+ }); |
+}, 'delayed handling: a nested-postMessageTask after promise creation/rejection, plus many promise microtasks, is ' + |
+ 'too late to attach a rejection handler'); |
+ |
+async_test(function(t) { |
+ var unhandledPromises = []; |
+ var unhandledReasons = []; |
+ var e = new Error(); |
+ var p; |
+ |
+ var unhandled = function(ev) { |
+ if (ev.promise === p) { |
+ t.step(function() { |
+ unhandledPromises.push(ev.promise); |
+ unhandledReasons.push(ev.reason); |
+ }); |
+ } |
+ }; |
+ var handled = function(ev) { |
+ if (ev.promise === p) { |
+ t.step(function() { |
+ assert_array_equals(unhandledPromises, [p]); |
+ assert_array_equals(unhandledReasons, [e]); |
+ assert_equals(ev.promise, p); |
+ assert_equals(ev.reason, e); |
+ }); |
+ } |
+ }; |
+ addEventListener('unhandledrejection', unhandled); |
+ addEventListener('rejectionhandled', handled); |
+ ensureCleanup(t, unhandled, handled); |
+ |
+ p = new Promise(function() { |
+ throw e; |
+ }); |
+ setTimeout(function() { |
+ var unreached = t.unreached_func('promise should not be fulfilled'); |
+ p.then(unreached, function(reason) { |
+ assert_equals(reason, e); |
+ setTimeout(function() { t.done(); }, 10); |
+ }); |
+ }, 10); |
+}, 'delayed handling: delaying handling by setTimeout(,10) will cause both events to fire'); |
+ |
+// |
+// Miscellaneous tests about integration with the rest of the platform |
+// |
+ |
+async_test(function(t) { |
+ var e = new Error(); |
+ var l = function(ev) { |
+ var order = []; |
+ mutationObserverMicrotask(function() { |
+ order.push(1); |
+ }); |
+ setTimeout(function() { |
+ order.push(2); |
+ t.step(function() { |
+ assert_array_equals(order, [1, 2]); |
+ }); |
+ t.done(); |
+ }, 1); |
+ }; |
+ addEventListener('unhandledrejection', l); |
+ ensureCleanup(t, l); |
+ Promise.reject(e); |
+}, 'mutationObserverMicrotask vs. postMessageTask ordering is not disturbed inside unhandledrejection events'); |
+ |
+// For workers, postMessageTask() involves posting tasks to other threads, so |
+// the following tests don't work there. |
+ |
+if ('document' in self) { |
+ |
+ // For the next two see https://github.com/domenic/unhandled-rejections-browser-spec/issues/2#issuecomment-121121695 |
+ // and the following comments. |
+ |
+ async_test(function(t) { |
+ var sequenceOfEvents = []; |
+ |
+ addEventListener('unhandledrejection', l); |
+ ensureCleanup(t, l); |
+ |
+ var p1 = Promise.reject(); |
+ var p2; |
+ postMessageTask(function() { |
+ p2 = Promise.reject(); |
+ postMessageTask(function() { |
+ sequenceOfEvents.push('postMessageTask'); |
+ checkSequence(); |
+ }); |
+ }); |
+ |
+ function l(ev) { |
+ if (ev.promise === p1 || ev.promise === p2) { |
+ sequenceOfEvents.push(ev.promise); |
+ checkSequence(); |
+ } |
+ } |
+ |
+ function checkSequence() { |
+ if (sequenceOfEvents.length === 3) { |
+ t.step(function() { |
+ assert_array_equals(sequenceOfEvents, [p1, 'postMessageTask', p2]); |
+ }); |
+ t.done(); |
+ } |
+ } |
+ }, 'postMessageTask ordering vs. the task queued for unhandled rejection notification (1)'); |
+ |
+ async_test(function(t) { |
+ var sequenceOfEvents = []; |
+ |
+ addEventListener('unhandledrejection', l); |
+ ensureCleanup(t, l); |
+ |
+ var p2; |
+ postMessageTask(function() { |
+ p2 = Promise.reject(); |
+ postMessageTask(function() { |
+ sequenceOfEvents.push('postMessageTask'); |
+ checkSequence(); |
+ }); |
+ }); |
+ |
+ function l(ev) { |
+ if (ev.promise == p2) { |
+ sequenceOfEvents.push(ev.promise); |
+ checkSequence(); |
+ } |
+ } |
+ |
+ function checkSequence() { |
+ if (sequenceOfEvents.length === 2) { |
+ t.step(function() { |
+ assert_array_equals(sequenceOfEvents, ['postMessageTask', p2]); |
+ }); |
+ t.done(); |
+ } |
+ } |
+ }, 'postMessageTask ordering vs. the task queued for unhandled rejection notification (2)'); |
+ |
+ async_test(function(t) { |
+ var sequenceOfEvents = []; |
+ |
+ |
+ addEventListener('unhandledrejection', unhandled); |
+ addEventListener('rejectionhandled', handled); |
+ ensureCleanup(t, unhandled, handled); |
+ |
+ var p = Promise.reject(); |
+ |
+ setTimeout(function() { |
+ postMessageTask(function() { |
+ sequenceOfEvents.push('task before catch'); |
+ checkSequence(); |
+ }); |
+ |
+ p.catch(function() { |
+ sequenceOfEvents.push('catch'); |
+ checkSequence(); |
+ }); |
+ |
+ postMessageTask(function() { |
+ sequenceOfEvents.push('task after catch'); |
+ checkSequence(); |
+ }); |
+ |
+ sequenceOfEvents.push('after catch'); |
+ checkSequence(); |
+ }, 10); |
+ |
+ function unhandled(ev) { |
+ if (ev.promise === p) { |
+ sequenceOfEvents.push('unhandled'); |
+ checkSequence(); |
+ } |
+ } |
+ |
+ function handled(ev) { |
+ if (ev.promise === p) { |
+ sequenceOfEvents.push('handled'); |
+ checkSequence(); |
+ } |
+ } |
+ |
+ function checkSequence() { |
+ if (sequenceOfEvents.length === 6) { |
+ t.step(function() { |
+ assert_array_equals(sequenceOfEvents, |
+ ['unhandled', 'after catch', 'catch', 'task before catch', 'handled', 'task after catch']); |
+ }); |
+ t.done(); |
+ } |
+ } |
+ }, 'rejectionhandled is dispatched from a queued task, and not immediately'); |
+} |
+ |
+// |
+// HELPERS |
+// |
+ |
+var globalPostMessageCounter = 0; |
+ |
+function postMessageTask(f) { |
+ if ('document' in self) { |
+ var message = 'abusingpostmessageforfunandprofit' + globalPostMessageCounter; |
+ globalPostMessageCounter++; |
+ var l = function(ev) { |
+ if (ev.data === message) { |
+ removeEventListener('message', l); |
+ f(); |
+ } |
+ }; |
+ addEventListener('message', l); |
+ postMessage(message, '*'); |
+ } else { |
+ var channel = new MessageChannel(); |
+ channel.port1.onmessage = function() { channel.port1.close(); f(); }; |
+ channel.port2.postMessage('abusingpostmessageforfunandprofit'); |
+ channel.port2.close(); |
+ } |
+} |
+ |
+function mutationObserverMicrotask(f) { |
+ if ('document' in self) { |
+ var observer = new MutationObserver(function() { f(); }); |
+ var node = document.createTextNode(''); |
+ observer.observe(node, { characterData: true }); |
+ node.data = 'foo'; |
+ } else { |
+ // We don't have mutation observers on workers, so just post a promise-based |
+ // microtask. |
+ Promise.resolve().then(function() { f(); }); |
+ } |
+} |
+ |
+function onUnhandledSucceed(t, expectedReason, expectedPromiseGetter) { |
+ var l = function(ev) { |
+ if (ev.promise === expectedPromiseGetter()) { |
+ t.step(function() { |
+ assert_equals(ev.reason, expectedReason); |
+ assert_equals(ev.promise, expectedPromiseGetter()); |
+ }); |
+ t.done(); |
+ } |
+ }; |
+ addEventListener('unhandledrejection', l); |
+ ensureCleanup(t, l); |
+} |
+ |
+function onUnhandledFail(t, expectedPromiseGetter) { |
+ var unhandled = function(evt) { |
+ if (evt.promise === expectedPromiseGetter()) { |
+ t.step(function() { |
+ assert_unreached('unhandledrejection event is not supposed to be triggered'); |
+ }); |
+ } |
+ }; |
+ var handled = function(evt) { |
+ if (evt.promise === expectedPromiseGetter()) { |
+ t.step(function() { |
+ assert_unreached('rejectionhandled event is not supposed to be triggered'); |
+ }); |
+ } |
+ }; |
+ addEventListener('unhandledrejection', unhandled); |
+ addEventListener('rejectionhandled', handled); |
+ ensureCleanup(t, unhandled, handled); |
+ setTimeout(function() { |
+ t.done(); |
+ }, 10); |
+} |
+ |
+function ensureCleanup(t, unhandled, handled) { |
+ t.add_cleanup(function() { |
+ if (unhandled) |
+ removeEventListener('unhandledrejection', unhandled); |
+ if (handled) |
+ removeEventListener('rejectionhandled', handled); |
+ }); |
+} |
+ |
+done(); |