Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /fetch/api/request/request-init-stream-not-disturbed.any.html - WPT Dashboard Interop Dashboard
- /fetch/api/request/request-init-stream-not-disturbed.any.serviceworker.html - WPT Dashboard Interop Dashboard
- /fetch/api/request/request-init-stream-not-disturbed.any.sharedworker.html - WPT Dashboard Interop Dashboard
- /fetch/api/request/request-init-stream-not-disturbed.any.worker.html - WPT Dashboard Interop Dashboard
// META: global=window,worker
// ReadableStream, so a Request constructor that throws must leave the stream
// untouched.
function newStream() {
return new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode("hello"));
controller.close();
},
});
}
async function readAll(stream) {
const reader = stream.getReader();
let out = "";
const decoder = new TextDecoder();
for (;;) {
const { done, value } = await reader.read();
if (done) {
return out;
}
out += decoder.decode(value, { stream: true });
}
}
test(() => {
const stream = newStream();
assert_throws_js(
TypeError,
() => new Request("/", { method: "POST", body: stream }),
"omitting duplex must throw"
);
assert_false(stream.locked, "stream must not be left locked");
}, "A Request constructor that throws for a missing duplex leaves the stream unlocked");
promise_test(async () => {
const stream = newStream();
assert_throws_js(TypeError, () =>
new Request("/", { method: "POST", body: stream })
);
// Not disturbed either, so the stream is still fully readable.
assert_equals(await readAll(stream), "hello", "stream must still be readable");
}, "A Request constructor that throws for a missing duplex leaves the stream readable");
test(() => {
const stream = newStream();
assert_throws_js(
TypeError,
() => new Request("/", { method: "POST", body: stream, keepalive: true, duplex: "half" }),
"keepalive with a stream body must throw"
);
assert_false(stream.locked, "stream must not be left locked");
}, "A Request constructor that throws for keepalive leaves the stream unlocked");
test(() => {
const stream = newStream();
assert_throws_js(TypeError, () => new Request("/", {
method: "POST", body: stream, duplex: "half", mode: "no-cors"
}));
assert_false(stream.locked, "stream must not be left locked");
}, "A Request constructor that throws for no-cors leaves the stream unlocked");
for (const body of [undefined, null]) {
test(() => {
const request = new Request("/", {
method: "POST", body: newStream(), duplex: "half"
});
assert_throws_js(TypeError, () =>
new Request(request, { mode: "no-cors", body })
);
assert_false(request.bodyUsed, "input request must not be disturbed");
}, `An inherited streaming body rejects no-cors with init.body ${body}`);
}
test(() => {
const request = new Request("/", {
method: "POST", body: newStream(), duplex: "half"
});
const replacement = new Request(request, {
mode: "no-cors", body: "replacement"
});
assert_equals(replacement.mode, "no-cors");
const copied = new Request(replacement, { mode: "no-cors" });
assert_equals(copied.mode, "no-cors");
}, "Replacing a streaming body with a string permits no-cors");