2021-06-16 19:44:22 +00:00
|
|
|
// Flags: --expose-internals --no-warnings
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const common = require('../common');
|
|
|
|
const assert = require('assert');
|
|
|
|
|
|
|
|
const {
|
|
|
|
WritableStream,
|
|
|
|
WritableStreamDefaultController,
|
|
|
|
WritableStreamDefaultWriter,
|
|
|
|
CountQueuingStrategy,
|
|
|
|
} = require('stream/web');
|
|
|
|
|
|
|
|
const {
|
|
|
|
kState,
|
|
|
|
} = require('internal/webstreams/util');
|
|
|
|
|
|
|
|
const {
|
|
|
|
isPromise,
|
|
|
|
} = require('util/types');
|
|
|
|
|
|
|
|
const {
|
|
|
|
kTransfer,
|
|
|
|
} = require('internal/worker/js_transferable');
|
|
|
|
|
|
|
|
const {
|
|
|
|
inspect,
|
|
|
|
} = require('util');
|
|
|
|
|
|
|
|
class Sink {
|
|
|
|
constructor() {
|
|
|
|
this.chunks = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
start() {
|
|
|
|
this.started = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
write(chunk) {
|
|
|
|
this.chunks.push(chunk);
|
|
|
|
}
|
|
|
|
|
|
|
|
close() {
|
|
|
|
this.closed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
abort() {
|
|
|
|
this.aborted = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const stream = new WritableStream();
|
|
|
|
|
|
|
|
assert(stream[kState].controller instanceof WritableStreamDefaultController);
|
|
|
|
assert(!stream.locked);
|
|
|
|
|
|
|
|
assert.strictEqual(typeof stream.abort, 'function');
|
|
|
|
assert.strictEqual(typeof stream.close, 'function');
|
|
|
|
assert.strictEqual(typeof stream.getWriter, 'function');
|
|
|
|
}
|
|
|
|
|
2024-01-04 11:37:44 +00:00
|
|
|
['a', false, 1, null].forEach((sink) => {
|
|
|
|
assert.throws(() => new WritableStream(sink), {
|
|
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
['a', false, 1].forEach((strategy) => {
|
|
|
|
assert.throws(() => new WritableStream({}, strategy), {
|
|
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-06-16 19:44:22 +00:00
|
|
|
[1, false, ''].forEach((type) => {
|
|
|
|
assert.throws(() => new WritableStream({ type }), {
|
|
|
|
code: 'ERR_INVALID_ARG_VALUE',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
['a', {}].forEach((highWaterMark) => {
|
|
|
|
assert.throws(() => new WritableStream({}, { highWaterMark }), {
|
|
|
|
code: 'ERR_INVALID_ARG_VALUE',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
['a', false, {}].forEach((size) => {
|
|
|
|
assert.throws(() => new WritableStream({}, { size }), {
|
|
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
{
|
2024-01-04 11:37:44 +00:00
|
|
|
new WritableStream({});
|
|
|
|
new WritableStream([]);
|
2021-06-16 19:44:22 +00:00
|
|
|
new WritableStream({}, null);
|
2024-01-04 11:37:44 +00:00
|
|
|
new WritableStream({}, {});
|
|
|
|
new WritableStream({}, []);
|
2021-06-16 19:44:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const sink = new Sink();
|
|
|
|
const stream = new WritableStream(
|
|
|
|
sink,
|
|
|
|
new CountQueuingStrategy({ highWaterMark: 1 }));
|
|
|
|
|
|
|
|
assert(!stream.locked);
|
|
|
|
const writer = stream.getWriter();
|
|
|
|
assert(stream.locked);
|
|
|
|
assert(writer instanceof WritableStreamDefaultWriter);
|
|
|
|
|
|
|
|
assert(isPromise(writer.closed));
|
|
|
|
assert(isPromise(writer.ready));
|
|
|
|
assert(typeof writer.desiredSize, 'number');
|
|
|
|
assert(typeof writer.abort, 'function');
|
|
|
|
assert(typeof writer.close, 'function');
|
|
|
|
assert(typeof writer.releaseLock, 'function');
|
|
|
|
assert(typeof writer.write, 'function');
|
|
|
|
|
|
|
|
writer.releaseLock();
|
|
|
|
assert(!stream.locked);
|
|
|
|
|
|
|
|
const writer2 = stream.getWriter();
|
|
|
|
|
|
|
|
assert(sink.started);
|
|
|
|
|
|
|
|
writer2.closed.then(common.mustCall());
|
|
|
|
writer2.ready.then(common.mustCall());
|
|
|
|
|
|
|
|
writer2.close().then(common.mustCall(() => {
|
|
|
|
assert.strict(sink.closed);
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const sink = new Sink();
|
|
|
|
|
|
|
|
const stream = new WritableStream(
|
|
|
|
sink,
|
|
|
|
new CountQueuingStrategy({ highWaterMark: 1 }));
|
|
|
|
|
|
|
|
const error = new Error('boom');
|
|
|
|
|
|
|
|
const writer = stream.getWriter();
|
|
|
|
|
2023-10-23 17:55:50 +00:00
|
|
|
assert.rejects(writer.closed, error).then(common.mustCall());
|
2021-06-16 19:44:22 +00:00
|
|
|
|
|
|
|
writer.abort(error).then(common.mustCall(() => {
|
|
|
|
assert.strictEqual(stream[kState].state, 'errored');
|
|
|
|
assert(sink.aborted);
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const sink = new Sink();
|
|
|
|
|
|
|
|
const stream = new WritableStream(
|
|
|
|
sink, { highWaterMark: 1 }
|
|
|
|
);
|
|
|
|
|
|
|
|
async function write(stream) {
|
|
|
|
const writer = stream.getWriter();
|
|
|
|
const p = writer.write('hello');
|
|
|
|
assert.strictEqual(writer.desiredSize, 0);
|
|
|
|
await p;
|
|
|
|
assert.strictEqual(writer.desiredSize, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
write(stream).then(common.mustCall(() => {
|
|
|
|
assert.deepStrictEqual(['hello'], sink.chunks);
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
assert.throws(() => Reflect.get(WritableStream.prototype, 'locked', {}), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
|
|
|
});
|
|
|
|
assert.rejects(() => WritableStream.prototype.abort({}), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
2023-10-23 17:55:50 +00:00
|
|
|
}).then(common.mustCall());
|
2021-06-16 19:44:22 +00:00
|
|
|
assert.rejects(() => WritableStream.prototype.close({}), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
2023-10-23 17:55:50 +00:00
|
|
|
}).then(common.mustCall());
|
2021-06-16 19:44:22 +00:00
|
|
|
assert.throws(() => WritableStream.prototype.getWriter.call(), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
|
|
|
});
|
|
|
|
assert.throws(() => WritableStream.prototype[kTransfer].call(), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
|
|
|
});
|
|
|
|
assert.rejects(
|
|
|
|
Reflect.get(WritableStreamDefaultWriter.prototype, 'closed'), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
2023-10-23 17:55:50 +00:00
|
|
|
}).then(common.mustCall());
|
2021-06-16 19:44:22 +00:00
|
|
|
assert.rejects(
|
|
|
|
Reflect.get(WritableStreamDefaultWriter.prototype, 'ready'), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
2023-10-23 17:55:50 +00:00
|
|
|
}).then(common.mustCall());
|
2021-06-16 19:44:22 +00:00
|
|
|
assert.throws(
|
|
|
|
() => Reflect.get(WritableStreamDefaultWriter.prototype, 'desiredSize'), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
|
|
|
});
|
|
|
|
assert.rejects(WritableStreamDefaultWriter.prototype.abort({}), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
2023-10-23 17:55:50 +00:00
|
|
|
}).then(common.mustCall());
|
2021-06-16 19:44:22 +00:00
|
|
|
assert.rejects(WritableStreamDefaultWriter.prototype.close({}), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
2023-10-23 17:55:50 +00:00
|
|
|
}).then(common.mustCall());
|
2021-06-16 19:44:22 +00:00
|
|
|
assert.rejects(WritableStreamDefaultWriter.prototype.write({}), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
2023-10-23 17:55:50 +00:00
|
|
|
}).then(common.mustCall());
|
2021-06-16 19:44:22 +00:00
|
|
|
assert.throws(() => WritableStreamDefaultWriter.prototype.releaseLock({}), {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.throws(() => {
|
|
|
|
Reflect.get(WritableStreamDefaultController.prototype, 'signal', {});
|
|
|
|
}, {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.throws(() => {
|
|
|
|
WritableStreamDefaultController.prototype.error({});
|
|
|
|
}, {
|
|
|
|
code: 'ERR_INVALID_THIS',
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let controller;
|
|
|
|
const writable = new WritableStream({
|
|
|
|
start(c) { controller = c; }
|
|
|
|
});
|
|
|
|
assert.strictEqual(
|
|
|
|
inspect(writable),
|
|
|
|
'WritableStream { locked: false, state: \'writable\' }');
|
|
|
|
assert.strictEqual(
|
|
|
|
inspect(writable, { depth: null }),
|
|
|
|
'WritableStream { locked: false, state: \'writable\' }');
|
|
|
|
assert.strictEqual(
|
|
|
|
inspect(writable, { depth: 0 }),
|
|
|
|
'WritableStream [Object]');
|
|
|
|
|
|
|
|
const writer = writable.getWriter();
|
|
|
|
assert.match(
|
|
|
|
inspect(writer),
|
|
|
|
/WritableStreamDefaultWriter/);
|
|
|
|
assert.match(
|
|
|
|
inspect(writer, { depth: null }),
|
|
|
|
/WritableStreamDefaultWriter/);
|
|
|
|
assert.match(
|
|
|
|
inspect(writer, { depth: 0 }),
|
|
|
|
/WritableStreamDefaultWriter \[/);
|
|
|
|
|
|
|
|
assert.match(
|
|
|
|
inspect(controller),
|
|
|
|
/WritableStreamDefaultController/);
|
|
|
|
assert.match(
|
|
|
|
inspect(controller, { depth: null }),
|
|
|
|
/WritableStreamDefaultController/);
|
|
|
|
assert.match(
|
|
|
|
inspect(controller, { depth: 0 }),
|
|
|
|
/WritableStreamDefaultController \[/);
|
|
|
|
|
|
|
|
writer.abort(new Error('boom'));
|
|
|
|
|
|
|
|
assert.strictEqual(writer.desiredSize, null);
|
|
|
|
setImmediate(() => assert.strictEqual(writer.desiredSize, null));
|
|
|
|
}
|