Files

94 lines
6.0 KiB
JavaScript

import { WritableStream, WritableStreamDefaultWriter, WritableStreamDefaultController, CountQueuingStrategy, ByteLengthQueuingStrategy, ReadableStream, TransformStream } from "node:stream/web";
import { out, deferred, result, caught, sameError, launch } from "./helpers.js";
export function reportErrors() { launch(async () => {
for (const [name, fn] of [
["null-sink", () => new WritableStream(null)],
["false-sink", () => new WritableStream(false)],
["type", () => new WritableStream({ type: "bytes" })],
["hwm", () => new WritableStream({}, { highWaterMark: -1 })],
["nan", () => new WritableStream({}, { highWaterMark: NaN })],
["size-fn", () => new WritableStream({}, { size: 1 })],
["write-fn", () => new WritableStream({ write: true })],
["close-fn", () => new WritableStream({ close: {} })],
["abort-fn", () => new WritableStream({ abort: "bad" })],
["writer", () => new WritableStreamDefaultWriter({})],
["controller", () => new WritableStreamDefaultController()],
["count-init", () => new CountQueuingStrategy()],
["bytes-init", () => new ByteLengthQueuingStrategy(null)],
["count-missing", () => new CountQueuingStrategy({})],
["bytes-array", () => new ByteLengthQueuingStrategy([])],
]) out(name, caught(fn));
out("unchecked-hwm", new CountQueuingStrategy({ highWaterMark: -1 }).highWaterMark, new ByteLengthQueuingStrategy({ highWaterMark: NaN }).highWaterMark);
out("null-strategy", caught(() => new WritableStream({}, null)), caught(() => new WritableStream(() => {})));
const wproto = WritableStreamDefaultWriter.prototype;
for (const name of ["abort", "close", "write"]) out("writer-brand:" + name, await result(wproto[name].call({})));
out("writer-release-brand", caught(() => wproto.releaseLock.call({})));
for (const name of ["ready", "closed"]) out("writer-brand:" + name, await result(Object.getOwnPropertyDescriptor(wproto, name).get.call({})));
out("writer-size-brand", caught(() => Object.getOwnPropertyDescriptor(wproto, "desiredSize").get.call({})));
for (const name of ["abort", "close"]) out("stream-brand:" + name, await result(WritableStream.prototype[name].call({})));
out("stream-writer-brand", caught(() => WritableStream.prototype.getWriter.call({})));
out("controller-brand", caught(() => WritableStreamDefaultController.prototype.error.call({})));
{
const entered = deferred(), gate = deferred(), reason = new Error("controller-error"); let controller, abortCalls = 0;
const stream = new WritableStream({ start(c) { controller = c; }, write() { entered.resolve(); return gate.promise; }, abort() { abortCalls++; } });
const w = stream.getWriter(), a = result(w.write("a")), b = sameError(w.write("b"), reason);
await entered.promise;
controller.error(reason); controller.error(new Error("ignored"));
out("controller-error", w.desiredSize, controller.signal.aborted, await sameError(w.ready, reason));
gate.resolve(); out("controller-writes", await a, await b, await sameError(w.closed, reason), await sameError(w.write(), reason));
out("errored-abort", await result(w.abort()), abortCalls);
}
for (const kind of ["start", "write", "close", "abort"]) {
const error = new Error("sink-" + kind), seen = [], sink = {};
for (const name of ["start", "write", "close", "abort"]) sink[name] = function () { seen.push(name); if (name === kind) return Promise.reject(error); };
const stream = new WritableStream(sink), w = stream.getWriter();
if (kind === "start" || kind === "write") {
const a = sameError(w.write("a"), error), b = sameError(w.write("b"), error), c = sameError(w.close(), error);
out("sink-error:" + kind, await a, await b, await c, await sameError(w.closed, error), seen.join(","));
} else if (kind === "close") {
await w.write("a"); out("sink-error:close", await sameError(w.close(), error), await sameError(w.closed, error), seen.join(","));
} else {
const reason = new Error("original-abort");
out("sink-error:abort", await sameError(w.abort(reason), error), await sameError(w.closed, reason), seen.join(","));
}
}
for (const size of [-1, NaN, Infinity, undefined]) {
const stream = new WritableStream({}, { size() { return size; } }), w = stream.getWriter();
out("bad-size", String(size), await result(w.write("a")), await result(w.closed), w.desiredSize);
}
{
const w = new WritableStream({}, { size() { return 1n; } }).getWriter();
const error = await w.write("bigint").catch((e) => e);
out("bigint-size", error instanceof TypeError, error.code === undefined, await sameError(w.closed, error), w.desiredSize);
}
{
const error = new Error("size-callback");
const stream = new WritableStream({}, { size() { throw error; } }), w = stream.getWriter();
out("throwing-size", await sameError(w.write(), error), await sameError(w.closed, error));
}
{
let writer;
const stream = new WritableStream({}, { size() { writer.releaseLock(); return 1; } });
writer = stream.getWriter();
out("size-release", await result(writer.write("a")), stream.locked); await stream.close();
}
{
let controller;
const stream = new ReadableStream({ start(c) { controller = c; } }, { size() { return -1; } });
out("readable-size", caught(() => controller.enqueue("bad")), controller.desiredSize, await result(stream.getReader().read()));
}
{
const reason = new Error("sync-start");
out("sync-start", caught(() => new WritableStream({ start() { throw reason; } })));
const w = new WritableStream({ write() { throw new Error("sync-write"); } }).getWriter();
out("sync-write", await result(w.write()), await result(w.closed));
}
{
const reason = new Error("transform-start");
const t = new TransformStream({ start() { return Promise.reject(reason); } });
const r = t.readable.getReader(), w = t.writable.getWriter();
out("transform-start-error", await sameError(r.read(), reason), await sameError(w.write("a"), reason), await sameError(r.closed, reason), await sameError(w.closed, reason));
}
}); }