mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1263304
- Add wpt tests for async waitUntil(). r=bkelly
This commit is contained in:
parent
794fc5461a
commit
c313b322bb
@ -4,27 +4,79 @@
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/extendable-event-async-waituntil.js';
|
||||
var scope = 'resources/async-waituntil';
|
||||
var worker;
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = function(e) { resolve(e.data); }
|
||||
});
|
||||
worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
return saw_message;
|
||||
})
|
||||
.then(function(message) {
|
||||
assert_equals(message, 'PASS');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
}, 'Calling waitUntil asynchronously throws an exception');
|
||||
function sync_message(worker, message, transfer) {
|
||||
let wait = new Promise((res, rej) => {
|
||||
navigator.serviceWorker.addEventListener('message', function(e) {
|
||||
if (e.data === 'ACK') {
|
||||
res();
|
||||
} else {
|
||||
rej();
|
||||
}
|
||||
});
|
||||
});
|
||||
worker.postMessage(message, transfer);
|
||||
return wait;
|
||||
}
|
||||
|
||||
function runTest(test, step, testBody) {
|
||||
var scope = './resources/' + step;
|
||||
var script = 'resources/extendable-event-async-waituntil.js?' + scope;
|
||||
service_worker_unregister_and_register(test, script, scope)
|
||||
.then(function(registration) {
|
||||
let worker = registration.installing;
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = function(e) { resolve(e.data); }
|
||||
});
|
||||
|
||||
wait_for_state(test, worker, 'activated')
|
||||
.then(function() {
|
||||
return sync_message(worker, { step: 'init', port: channel.port2 },
|
||||
[channel.port2]);
|
||||
})
|
||||
.then(function() { return testBody(worker); })
|
||||
.then(function() { return saw_message; })
|
||||
.then(function(output) {
|
||||
assert_equals(output.result, output.expected);
|
||||
})
|
||||
.then(function() { return sync_message(worker, { step: 'done' }); })
|
||||
.then(() => { service_worker_unregister_and_done(test, scope); })
|
||||
.catch(unreached_rejection(test));
|
||||
});
|
||||
}
|
||||
|
||||
function msg_event_test(scope, test) {
|
||||
var testBody = function(worker) {
|
||||
return sync_message(worker, { step: scope });
|
||||
};
|
||||
runTest(test, scope, testBody);
|
||||
}
|
||||
|
||||
async_test(msg_event_test.bind(this, 'no-current-extension-different-task'),
|
||||
'Test calling waitUntil in a different task without an existing extension throws');
|
||||
|
||||
async_test(msg_event_test.bind(this, 'no-current-extension-different-microtask'),
|
||||
'Test calling waitUntil in a different microtask without an existing extension throws');
|
||||
|
||||
async_test(msg_event_test.bind(this, 'current-extension-different-task'),
|
||||
'Test calling waitUntil in a different task with an existing extension succeeds');
|
||||
|
||||
async_test(msg_event_test.bind(this, 'current-extension-expired-same-microtask-turn'),
|
||||
'Test calling waitUntil with an existing extension promise handler succeeds');
|
||||
|
||||
// The promise handler will queue a new microtask after the check for new
|
||||
// extensions was performed.
|
||||
async_test(msg_event_test.bind(this, 'current-extension-expired-same-microtask-turn-extra'),
|
||||
'Test calling waitUntil at the end of the microtask turn throws');
|
||||
|
||||
async_test(msg_event_test.bind(this, 'current-extension-expired-different-task'),
|
||||
'Test calling waitUntil after the current extension expired in a different task fails');
|
||||
|
||||
async_test(function(t) {
|
||||
var testBody = function(worker) {
|
||||
return with_iframe('./resources/pending-respondwith-async-waituntil/dummy.html');
|
||||
}
|
||||
runTest(t, 'pending-respondwith-async-waituntil', testBody);
|
||||
}, 'Test calling waitUntil asynchronously with pending respondWith promise.');
|
||||
</script>
|
||||
|
@ -1,20 +1,100 @@
|
||||
var result = 'FAIL: did not throw.';
|
||||
// controlled by 'init'/'done' messages.
|
||||
var resolveLockPromise;
|
||||
var port;
|
||||
|
||||
self.addEventListener('message', function(event) {
|
||||
event.data.port.postMessage(result);
|
||||
});
|
||||
var waitPromise;
|
||||
var resolveTestPromise;
|
||||
|
||||
self.addEventListener('install', function(event) {
|
||||
self.installEvent = event;
|
||||
});
|
||||
|
||||
self.addEventListener('activate', function(event) {
|
||||
try {
|
||||
self.installEvent.waitUntil(new Promise(function(){}));
|
||||
} catch (error) {
|
||||
if (error.name == 'InvalidStateError')
|
||||
result = 'PASS';
|
||||
else
|
||||
result = 'FAIL: unexpected exception: ' + error;
|
||||
switch (event.data.step) {
|
||||
case 'init':
|
||||
event.waitUntil(new Promise((res) => { resolveLockPromise = res; }));
|
||||
port = event.data.port;
|
||||
break;
|
||||
case 'done':
|
||||
resolveLockPromise();
|
||||
break;
|
||||
case 'no-current-extension-different-task':
|
||||
async_task_waituntil(event).then(reportResultExpecting('InvalidStateError'));
|
||||
break;
|
||||
case 'no-current-extension-different-microtask':
|
||||
async_microtask_waituntil(event).then(reportResultExpecting('InvalidStateError'));
|
||||
break;
|
||||
case 'current-extension-different-task':
|
||||
event.waitUntil(new Promise((res) => { resolveTestPromise = res; }));
|
||||
async_task_waituntil(event).then(reportResultExpecting('OK')).then(resolveTestPromise);
|
||||
break;
|
||||
case 'current-extension-expired-same-microtask-turn':
|
||||
waitPromise = Promise.resolve();
|
||||
event.waitUntil(waitPromise);
|
||||
waitPromise.then(() => { return sync_waituntil(event); })
|
||||
.then(reportResultExpecting('OK'))
|
||||
break;
|
||||
case 'current-extension-expired-same-microtask-turn-extra':
|
||||
// The promise handler queues a new microtask *after* the check for new
|
||||
// extensions was performed.
|
||||
waitPromise = Promise.resolve();
|
||||
event.waitUntil(waitPromise);
|
||||
waitPromise.then(() => { return async_microtask_waituntil(event); })
|
||||
.then(reportResultExpecting('InvalidStateError'))
|
||||
break;
|
||||
case 'current-extension-expired-different-task':
|
||||
event.waitUntil(Promise.resolve());
|
||||
async_task_waituntil(event).then(reportResultExpecting('InvalidStateError'));
|
||||
break;
|
||||
}
|
||||
event.source.postMessage('ACK');
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', function(event) {
|
||||
var resolveFetch;
|
||||
let response = new Promise((res) => { resolveFetch = res; });
|
||||
event.respondWith(response);
|
||||
async_task_waituntil(event)
|
||||
.then(reportResultExpecting('OK'))
|
||||
.then(() => { resolveFetch(new Response('OK')); });
|
||||
});
|
||||
|
||||
function reportResultExpecting(expectedResult) {
|
||||
return function (result) {
|
||||
port.postMessage({result : result, expected: expectedResult});
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function sync_waituntil(event) {
|
||||
return new Promise((res, rej) => {
|
||||
try {
|
||||
event.waitUntil(Promise.resolve());
|
||||
res('OK');
|
||||
} catch (error) {
|
||||
res(error.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function async_microtask_waituntil(event) {
|
||||
return new Promise((res, rej) => {
|
||||
Promise.resolve().then(() => {
|
||||
try {
|
||||
event.waitUntil(Promise.resolve());
|
||||
res('OK');
|
||||
} catch (error) {
|
||||
res(error.name);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function async_task_waituntil(event) {
|
||||
return new Promise((res, rej) => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
event.waitUntil(Promise.resolve());
|
||||
res('OK');
|
||||
} catch (error) {
|
||||
res(error.name);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user