Skip to content

Commit

Permalink
Merge be2fcd6 into 74cf111
Browse files Browse the repository at this point in the history
  • Loading branch information
jakearchibald authored Aug 4, 2017
2 parents 74cf111 + be2fcd6 commit 1438494
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 131 deletions.
2 changes: 1 addition & 1 deletion fetch/api/abort/general-serviceworker.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
let reg = await navigator.serviceWorker.getRegistration(scope);
if (reg) await reg.unregister();

reg = await navigator.serviceWorker.register('general.js', {scope});
reg = await navigator.serviceWorker.register('general.any.worker.js', {scope});

fetch_tests_from_worker(reg.installing);
})();
Expand Down
14 changes: 14 additions & 0 deletions fetch/api/abort/general-sharedworker.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>General fetch abort tests - shared worker</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
fetch_tests_from_worker(new SharedWorker("general.any.worker.js"));
</script>
</body>
</html>
92 changes: 54 additions & 38 deletions fetch/api/abort/general.js → fetch/api/abort/general.any.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
const BODY_METHODS = ['arrayBuffer', 'blob', 'formData', 'json', 'text'];
// META: script=/common/utils.js
// META: script=../request/request-error.js

if (self.importScripts) {
// Load scripts if being run from a worker
importScripts(
'/resources/testharness.js',
'/common/utils.js'
);
}
const BODY_METHODS = ['arrayBuffer', 'blob', 'formData', 'json', 'text'];

// This is used to close connections that weren't correctly closed during the tests,
// otherwise you can end up running out of HTTP connections.
Expand All @@ -20,11 +15,6 @@ function abortRequests() {
);
}

// Add the global name to the test name
function contextualTestName(name) {
return `${self.constructor.name}: ${name}`;
}

promise_test(async t => {
const controller = new AbortController();
const signal = controller.signal;
Expand All @@ -33,7 +23,7 @@ promise_test(async t => {
const fetchPromise = fetch('../resources/data.json', { signal });

await promise_rejects(t, "AbortError", fetchPromise);
}, contextualTestName("Aborting rejects with AbortError"));
}, "Aborting rejects with AbortError");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -49,13 +39,34 @@ promise_test(async t => {
});

await promise_rejects(t, "AbortError", fetchPromise);
}, contextualTestName("Aborting rejects with AbortError - no-cors"));
}, "Aborting rejects with AbortError - no-cors");

// Test that errors thrown from the request constructor take priority over abort errors.
// badRequestArgTests is from response-error.js
for (const { args, testName } of badRequestArgTests) {
promise_test(async t => {
try {
// If this doesn't throw, we'll effectively skip the test.
// It'll fail properly in ../request/request-error.html
new Request(...args);
}
catch (err) {
const controller = new AbortController();
controller.abort();

// Add signal to 2nd arg
args[1] = args[1] || {};
args[1].signal = controller.signal;
await promise_rejects(t, err, fetch(...args));
}
}, `TypeError from request constructor takes priority - ${testName}`);
}

test(() => {
const request = new Request('');
assert_true(Boolean(request.signal), "Signal member is present & truthy");
assert_equals(request.signal.constructor, AbortSignal);
}, contextualTestName("Request objects have a signal property"));
}, "Request objects have a signal property");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -71,7 +82,7 @@ promise_test(async t => {
const fetchPromise = fetch(request);

await promise_rejects(t, "AbortError", fetchPromise);
}, contextualTestName("Signal on request object"));
}, "Signal on request object");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -84,7 +95,7 @@ promise_test(async t => {
const fetchPromise = fetch(requestFromRequest);

await promise_rejects(t, "AbortError", fetchPromise);
}, contextualTestName("Signal on request object created from request object"));
}, "Signal on request object created from request object");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -97,7 +108,7 @@ promise_test(async t => {
const fetchPromise = fetch(requestFromRequest);

await promise_rejects(t, "AbortError", fetchPromise);
}, contextualTestName("Signal on request object created from request object, with signal on second request"));
}, "Signal on request object created from request object, with signal on second request");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -110,7 +121,7 @@ promise_test(async t => {
const fetchPromise = fetch(requestFromRequest);

await promise_rejects(t, "AbortError", fetchPromise);
}, contextualTestName("Signal on request object created from request object, with signal on second request overriding another"));
}, "Signal on request object created from request object, with signal on second request overriding another");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -122,7 +133,7 @@ promise_test(async t => {
const fetchPromise = fetch(request, {method: 'POST'});

await promise_rejects(t, "AbortError", fetchPromise);
}, contextualTestName("Signal retained after unrelated properties are overridden by fetch"));
}, "Signal retained after unrelated properties are overridden by fetch");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -133,7 +144,7 @@ promise_test(async t => {

const data = await fetch(request, { signal: null }).then(r => r.json());
assert_equals(data.key, 'value', 'Fetch fully completes');
}, contextualTestName("Signal removed by setting to null"));
}, "Signal removed by setting to null");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -151,7 +162,7 @@ promise_test(async t => {
]);

assert_array_equals(log, ['fetch-reject', 'next-microtask']);
}, contextualTestName("Already aborted signal rejects immediately"));
}, "Already aborted signal rejects immediately");

promise_test(async t => {
const controller = new AbortController();
Expand All @@ -168,7 +179,7 @@ promise_test(async t => {
await fetch(request).catch(() => {});

assert_true(request.bodyUsed, "Body has been used");
}, contextualTestName("Request is still 'used' if signal is aborted before fetching"));
}, "Request is still 'used' if signal is aborted before fetching");

for (const bodyMethod of BODY_METHODS) {
promise_test(async t => {
Expand All @@ -190,7 +201,7 @@ for (const bodyMethod of BODY_METHODS) {
await promise_rejects(t, "AbortError", bodyPromise);

assert_array_equals(log, [`${bodyMethod}-reject`, 'next-microtask']);
}, contextualTestName(`response.${bodyMethod}() rejects if already aborted`));
}, `response.${bodyMethod}() rejects if already aborted`);
}

promise_test(async t => {
Expand All @@ -213,7 +224,7 @@ promise_test(async t => {
const data = await response.json();

assert_equals(data, null, "Request hasn't been made to the server");
}, contextualTestName("Already aborted signal does not make request"));
}, "Already aborted signal does not make request");

promise_test(async t => {
await abortRequests();
Expand All @@ -236,7 +247,7 @@ promise_test(async t => {
for (const fetchPromise of fetches) {
await promise_rejects(t, "AbortError", fetchPromise);
}
}, contextualTestName("Already aborted signal can be used for many fetches"));
}, "Already aborted signal can be used for many fetches");

promise_test(async t => {
await abortRequests();
Expand All @@ -262,7 +273,7 @@ promise_test(async t => {
for (const fetchPromise of fetches) {
await promise_rejects(t, "AbortError", fetchPromise);
}
}, contextualTestName("Signal can be used to abort other fetches, even if another fetch succeeded before aborting"));
}, "Signal can be used to abort other fetches, even if another fetch succeeded before aborting");

promise_test(async t => {
await abortRequests();
Expand Down Expand Up @@ -290,7 +301,7 @@ promise_test(async t => {
const afterAbortResult = await fetch(`../resources/stash-take.py?key=${stateKey}`).then(r => r.json());
if (afterAbortResult == 'closed') break;
}
}, contextualTestName("Underlying connection is closed when aborting after receiving response"));
}, "Underlying connection is closed when aborting after receiving response");

promise_test(async t => {
await abortRequests();
Expand Down Expand Up @@ -327,7 +338,7 @@ promise_test(async t => {
const afterAbortResult = await fetch(stashTakeURL).then(r => r.json());
if (afterAbortResult == 'closed') break;
}
}, contextualTestName("Underlying connection is closed when aborting after receiving response - no-cors"));
}, "Underlying connection is closed when aborting after receiving response - no-cors");

for (const bodyMethod of BODY_METHODS) {
promise_test(async t => {
Expand Down Expand Up @@ -359,7 +370,7 @@ for (const bodyMethod of BODY_METHODS) {
const afterAbortResult = await fetch(`../resources/stash-take.py?key=${stateKey}`).then(r => r.json());
if (afterAbortResult == 'closed') break;
}
}, contextualTestName(`Fetch aborted & connection closed when aborted after calling response.${bodyMethod}()`));
}, `Fetch aborted & connection closed when aborted after calling response.${bodyMethod}()`);
}

promise_test(async t => {
Expand Down Expand Up @@ -389,7 +400,7 @@ promise_test(async t => {
const afterAbortResult = await fetch(`../resources/stash-take.py?key=${stateKey}`).then(r => r.json());
if (afterAbortResult == 'closed') break;
}
}, contextualTestName("Stream errors once aborted. Underlying connection closed."));
}, "Stream errors once aborted. Underlying connection closed.");

promise_test(async t => {
await abortRequests();
Expand Down Expand Up @@ -420,7 +431,7 @@ promise_test(async t => {
const afterAbortResult = await fetch(`../resources/stash-take.py?key=${stateKey}`).then(r => r.json());
if (afterAbortResult == 'closed') break;
}
}, contextualTestName("Stream errors once aborted, after reading. Underlying connection closed."));
}, "Stream errors once aborted, after reading. Underlying connection closed.");

promise_test(async t => {
await abortRequests();
Expand All @@ -436,10 +447,9 @@ promise_test(async t => {
const item = await reader.read();

assert_true(item.done, "Stream is done");
}, contextualTestName("Stream will not error if body is empty. It's closed with an empty queue before it errors."));
}, "Stream will not error if body is empty. It's closed with an empty queue before it errors.");


test(t => {
promise_test(async t => {
const controller = new AbortController();
const signal = controller.signal;
controller.abort();
Expand All @@ -455,7 +465,7 @@ test(t => {
}
});

fetch('../resources/empty.txt', {
const fetchPromise = fetch('../resources/empty.txt', {
body, signal,
method: 'POST',
headers: {
Expand All @@ -466,4 +476,10 @@ test(t => {
assert_true(!!cancelReason, 'Cancel called sync');
assert_equals(cancelReason.constructor, DOMException);
assert_equals(cancelReason.name, 'AbortError');
}, contextualTestName("Readable stream synchronously cancels with AbortError if aborted before reading"));

await promise_rejects(t, "AbortError", fetchPromise);

const fetchErr = await fetchPromise.catch(e => e);

assert_equals(cancelReason, fetchErr, "Fetch rejects with same error instance");
}, "Readable stream synchronously cancels with AbortError if aborted before reading");
19 changes: 0 additions & 19 deletions fetch/api/abort/general.html

This file was deleted.

Loading

0 comments on commit 1438494

Please sign in to comment.