node/test/parallel/test-whatwg-webstreams-adapters-to-streamwritable.js

235 lines
5.7 KiB
JavaScript
Raw Normal View History

// Flags: --no-warnings --expose-internals
'use strict';
const common = require('../common');
const assert = require('assert');
const {
WritableStream,
} = require('stream/web');
const {
newStreamWritableFromWritableStream,
} = require('internal/webstreams/adapters');
const {
finished,
pipeline,
Readable,
} = require('stream');
const {
kState,
} = require('internal/webstreams/util');
class TestSource {
constructor() {
this.chunks = [];
}
start(c) {
this.controller = c;
this.started = true;
}
write(chunk) {
this.chunks.push(chunk);
}
close() {
this.closed = true;
}
abort(reason) {
this.abortReason = reason;
}
}
[1, {}, false, []].forEach((arg) => {
assert.throws(() => newStreamWritableFromWritableStream(arg), {
code: 'ERR_INVALID_ARG_TYPE',
});
});
{
// Ending the stream.Writable should close the writableStream
const source = new TestSource();
const writableStream = new WritableStream(source);
const writable = newStreamWritableFromWritableStream(writableStream);
assert(writableStream.locked);
writable.end('chunk');
writable.on('close', common.mustCall(() => {
assert(writableStream.locked);
assert.strictEqual(writableStream[kState].state, 'closed');
assert.strictEqual(source.chunks.length, 1);
assert.deepStrictEqual(source.chunks[0], Buffer.from('chunk'));
}));
}
{
// Destroying the stream.Writable without an error should close
// the writableStream with no error.
const source = new TestSource();
const writableStream = new WritableStream(source);
const writable = newStreamWritableFromWritableStream(writableStream);
assert(writableStream.locked);
writable.destroy();
writable.on('close', common.mustCall(() => {
assert(writableStream.locked);
assert.strictEqual(writableStream[kState].state, 'closed');
assert.strictEqual(source.chunks.length, 0);
}));
}
{
// Destroying the stream.Writable with an error should error
// the writableStream
const error = new Error('boom');
const source = new TestSource();
const writableStream = new WritableStream(source);
const writable = newStreamWritableFromWritableStream(writableStream);
assert(writableStream.locked);
writable.destroy(error);
writable.on('error', common.mustCall((reason) => {
assert.strictEqual(reason, error);
}));
writable.on('close', common.mustCall(() => {
assert(writableStream.locked);
assert.strictEqual(writableStream[kState].state, 'errored');
assert.strictEqual(writableStream[kState].storedError, error);
assert.strictEqual(source.chunks.length, 0);
}));
}
{
// Attempting to close, abort, or getWriter on writableStream
// should fail because it is locked. An internal error in
// writableStream should error the writable.
const error = new Error('boom');
const source = new TestSource();
const writableStream = new WritableStream(source);
const writable = newStreamWritableFromWritableStream(writableStream);
assert(writableStream.locked);
assert.rejects(writableStream.close(), {
code: 'ERR_INVALID_STATE',
}).then(common.mustCall());
assert.rejects(writableStream.abort(), {
code: 'ERR_INVALID_STATE',
}).then(common.mustCall());
assert.throws(() => writableStream.getWriter(), {
code: 'ERR_INVALID_STATE',
});
writable.on('error', common.mustCall((reason) => {
assert.strictEqual(error, reason);
}));
source.controller.error(error);
}
{
const source = new TestSource();
const writableStream = new WritableStream(source);
const writable = newStreamWritableFromWritableStream(writableStream);
writable.on('error', common.mustNotCall());
writable.on('finish', common.mustCall());
writable.on('close', common.mustCall(() => {
assert.strictEqual(source.chunks.length, 1);
assert.deepStrictEqual(source.chunks[0], Buffer.from('hello'));
}));
writable.write('hello', common.mustCall());
writable.end();
}
{
const source = new TestSource();
const writableStream = new WritableStream(source);
const writable =
newStreamWritableFromWritableStream(writableStream, {
decodeStrings: false,
});
writable.on('error', common.mustNotCall());
writable.on('finish', common.mustCall());
writable.on('close', common.mustCall(() => {
assert.strictEqual(source.chunks.length, 1);
assert.strictEqual(source.chunks[0], 'hello');
}));
writable.write('hello', common.mustCall());
writable.end();
}
{
const source = new TestSource();
const writableStream = new WritableStream(source);
const writable =
newStreamWritableFromWritableStream(
writableStream, {
objectMode: true
});
assert(writable.writableObjectMode);
writable.on('error', common.mustNotCall());
writable.on('finish', common.mustCall());
writable.on('close', common.mustCall(() => {
assert.strictEqual(source.chunks.length, 1);
assert.strictEqual(source.chunks[0], 'hello');
}));
writable.write('hello', common.mustCall());
writable.end();
}
{
const writableStream = new WritableStream({
write: common.mustCall(5),
close: common.mustCall(),
});
const writable = newStreamWritableFromWritableStream(writableStream);
finished(writable, common.mustCall());
writable.write('hello');
writable.write('hello');
writable.write('hello');
writable.write('world');
writable.write('world');
writable.end();
}
{
const writableStream = new WritableStream({
write: common.mustCall(2),
close: common.mustCall(),
});
const writable = newStreamWritableFromWritableStream(writableStream);
const readable = new Readable({
read() {
readable.push(Buffer.from('hello'));
readable.push(Buffer.from('world'));
readable.push(null);
}
});
pipeline(readable, writable, common.mustCall());
}