mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Update web-platform-tests to revision 7a767a52741f628430ffbbed46e7f3df68ba3534
Fixes #15648.
This commit is contained in:
parent
a1e4c547f0
commit
4fadf9b0b6
1184 changed files with 22551 additions and 9856 deletions
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/cors/support.js?pipe=sub"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#unhandled-promise-rejections">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#muted-errors">
|
||||
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
setup({
|
||||
allow_uncaught_exception: true
|
||||
});
|
||||
|
||||
async_test(function(t) {
|
||||
addEventListener('unhandledrejection', t.step_func(function(e) {
|
||||
assert_equals(e.reason, 42, 'reason should be the one given by the script');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Promise rejection event should be received for the cross-origin CORS script');
|
||||
|
||||
(function() {
|
||||
var scriptEl = document.createElement('script');
|
||||
scriptEl.src = CROSSDOMAIN + 'support/promise-access-control.py?allow=true';
|
||||
scriptEl.crossOrigin = 'anonymous';
|
||||
document.body.appendChild(scriptEl);
|
||||
}());
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/cors/support.js?pipe=sub"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#unhandled-promise-rejections">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#muted-errors">
|
||||
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var resolveLoaded;
|
||||
var loadedPromise = new Promise(function(resolve) { resolveLoaded = resolve; });
|
||||
|
||||
async_test(function(t) {
|
||||
addEventListener('unhandledrejection', t.unreached_func('unhandledrejection event should never be triggered'));
|
||||
addEventListener('rejectionhandled', t.unreached_func('rejectionhandled event should never be triggered'));
|
||||
|
||||
loadedPromise.then(t.step_func(function() {
|
||||
t.step_timeout(function() {
|
||||
t.done();
|
||||
}, 1000);
|
||||
}));
|
||||
}, 'Promise rejection event should be muted for cross-origin non-CORS script');
|
||||
|
||||
var scriptEl = document.createElement('script');
|
||||
scriptEl.src = CROSSDOMAIN + 'support/promise-access-control.py?allow=false';
|
||||
scriptEl.onload = resolveLoaded;
|
||||
document.body.appendChild(scriptEl);
|
||||
}());
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#the-promiserejectionevent-interface">
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
test(function() {
|
||||
var p = new Promise(function(resolve, reject) {});
|
||||
|
||||
// No custom options are passed (besides required promise).
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { promise: p }).bubbles, false);
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { promise: p }).cancelable, false);
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { promise: p }).promise, p);
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { promise: p }).reason, undefined);
|
||||
|
||||
// No promise is passed.
|
||||
assert_throws(new TypeError(),
|
||||
function() {
|
||||
new PromiseRejectionEvent('eventType', { bubbles: false });
|
||||
},
|
||||
'Cannot construct PromiseRejectionEventInit without promise');
|
||||
|
||||
// bubbles is passed.
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { bubbles: false, promise: p }).bubbles, false);
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { bubbles: true, promise: p }).bubbles, true);
|
||||
|
||||
// cancelable is passed.
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { cancelable: false, promise: p }).cancelable, false);
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { cancelable: true, promise: p }).cancelable, true);
|
||||
|
||||
// reason is passed.
|
||||
var r = new Error();
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { promise: p, reason: r }).reason, r);
|
||||
|
||||
|
||||
// All initializers are passed.
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { bubbles: true, cancelable: true, promise: p, reason: r }).bubbles, true);
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { bubbles: true, cancelable: true, promise: p, reason: r }).cancelable, true);
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { bubbles: true, cancelable: true, promise: p, reason: r }).promise, p);
|
||||
assert_equals(new PromiseRejectionEvent('eventType', { bubbles: true, cancelable: true, promise: p, reason: r }).reason, r);
|
||||
}, "This tests the constructor for the PromiseRejectionEvent DOM class.");
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#unhandled-promise-rejections">
|
||||
<script>
|
||||
'use strict';
|
||||
setup({
|
||||
allow_uncaught_exception: true
|
||||
});
|
||||
async_test(function(t) {
|
||||
var e = new Error('e');
|
||||
var p = Promise.reject(e);
|
||||
|
||||
window.onunhandledrejection = function(evt) {
|
||||
t.step(function() {
|
||||
assert_equals(evt.promise, p);
|
||||
assert_equals(evt.reason, e);
|
||||
});
|
||||
var unreached = t.unreached_func('promise should not be fulfilled');
|
||||
p.then(unreached, function(reason) {
|
||||
t.step(function() {
|
||||
assert_equals(reason, e);
|
||||
});
|
||||
t.step_timeout(function() { t.done(); }, 10);
|
||||
});
|
||||
};
|
||||
|
||||
window.onrejectionhandled = t.unreached_func('rejectionhandled event should not be invoked');
|
||||
}, 'Attaching a handler in unhandledrejection should not trigger rejectionhandled.');
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#runtime-script-errors">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#unhandled-promise-rejections">
|
||||
<script>
|
||||
'use strict';
|
||||
setup({
|
||||
allow_uncaught_exception: true
|
||||
});
|
||||
async_test(function(t) {
|
||||
var e = new Error('e');
|
||||
var e2 = new Error('e2');
|
||||
|
||||
window.onerror = function (msg, url, line, col, error) {
|
||||
t.step(function() {
|
||||
assert_equals(msg, 'Uncaught Error: e2');
|
||||
assert_equals(error, e2);
|
||||
});
|
||||
t.done();
|
||||
};
|
||||
|
||||
window.onrejectionhandled = function() {
|
||||
// This should cause onerror
|
||||
throw e2;
|
||||
};
|
||||
|
||||
var p = Promise.reject(e);
|
||||
setTimeout(t.step_func(function() {
|
||||
// This will cause onrejectionhandled
|
||||
p.catch(function() {});
|
||||
}), 1);
|
||||
}, 'Throwing inside an unhandledrejection handler invokes the error handler.');
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Promise rejection events tests: in a dedicated worker context</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#unhandled-promise-rejections">
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new Worker('support/promise-rejection-events.js'));
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Promise rejection events tests: in a Window context</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#unhandled-promise-rejections">
|
||||
|
||||
<script src="support/promise-rejection-events.js"></script>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Promise rejection events tests: in a service worker context</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#unhandled-promise-rejections">
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
service_worker_test('support/promise-rejection-events.js', 'Service worker setup');
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Promise rejection events tests: in a shared worker context</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#unhandled-promise-rejections">
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new SharedWorker('support/promise-rejection-events.js'));
|
||||
</script>
|
|
@ -0,0 +1,10 @@
|
|||
def main(request, response):
|
||||
allow = request.GET.first("allow", "false")
|
||||
|
||||
headers = [("Content-Type", "application/javascript")]
|
||||
if allow != "false":
|
||||
headers.append(("Access-Control-Allow-Origin", "*"))
|
||||
|
||||
body = "new Promise(function(resolve, reject) { reject(42); })"
|
||||
|
||||
return headers, body
|
|
@ -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();
|
Loading…
Add table
Add a link
Reference in a new issue