• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --no-warnings --expose-internals
2
3'use strict';
4
5const common = require('../common');
6
7const assert = require('assert');
8
9const {
10  newWritableStreamFromStreamWritable,
11} = require('internal/webstreams/adapters');
12
13const {
14  Duplex,
15  Writable,
16  PassThrough,
17} = require('stream');
18
19class TestWritable extends Writable {
20  constructor(asyncWrite = false) {
21    super();
22    this.chunks = [];
23    this.asyncWrite = asyncWrite;
24  }
25
26  _write(chunk, encoding, callback) {
27    this.chunks.push({ chunk, encoding });
28    if (this.asyncWrite) {
29      setImmediate(() => callback());
30      return;
31    }
32    callback();
33  }
34}
35
36[1, {}, false, []].forEach((arg) => {
37  assert.throws(() => newWritableStreamFromStreamWritable(arg), {
38    code: 'ERR_INVALID_ARG_TYPE',
39  });
40});
41
42{
43  // Closing the WritableStream normally closes the stream.Writable
44  // without errors.
45
46  const writable = new TestWritable();
47  writable.on('error', common.mustNotCall());
48  writable.on('finish', common.mustCall());
49  writable.on('close', common.mustCall());
50
51  const writableStream = newWritableStreamFromStreamWritable(writable);
52
53  writableStream.close().then(common.mustCall(() => {
54    assert(writable.destroyed);
55  }));
56}
57
58{
59  // Aborting the WritableStream errors the stream.Writable
60
61  const error = new Error('boom');
62  const writable = new TestWritable();
63  writable.on('error', common.mustCall((reason) => {
64    assert.strictEqual(reason, error);
65  }));
66  writable.on('finish', common.mustNotCall());
67  writable.on('close', common.mustCall());
68
69  const writableStream = newWritableStreamFromStreamWritable(writable);
70
71  writableStream.abort(error).then(common.mustCall(() => {
72    assert(writable.destroyed);
73  }));
74}
75
76{
77  // Destroying the stream.Writable prematurely errors the
78  // WritableStream
79
80  const error = new Error('boom');
81  const writable = new TestWritable();
82
83  const writableStream = newWritableStreamFromStreamWritable(writable);
84  assert.rejects(writableStream.close(), error);
85  writable.destroy(error);
86}
87
88{
89  // Ending the stream.Writable directly errors the WritableStream
90  const writable = new TestWritable();
91
92  const writableStream = newWritableStreamFromStreamWritable(writable);
93
94  assert.rejects(writableStream.close(), {
95    code: 'ABORT_ERR'
96  });
97
98  writable.end();
99}
100
101{
102  const writable = new TestWritable();
103  const writableStream = newWritableStreamFromStreamWritable(writable);
104  const writer = writableStream.getWriter();
105  const ec = new TextEncoder();
106  writer.write(ec.encode('hello')).then(common.mustCall(() => {
107    assert.strictEqual(writable.chunks.length, 1);
108    assert.deepStrictEqual(
109      writable.chunks[0],
110      {
111        chunk: Buffer.from('hello'),
112        encoding: 'buffer'
113      });
114  }));
115}
116
117{
118  const writable = new TestWritable(true);
119
120  writable.on('error', common.mustNotCall());
121  writable.on('close', common.mustCall());
122  writable.on('finish', common.mustCall());
123
124  const writableStream = newWritableStreamFromStreamWritable(writable);
125  const writer = writableStream.getWriter();
126  const ec = new TextEncoder();
127  writer.write(ec.encode('hello')).then(common.mustCall(() => {
128    assert.strictEqual(writable.chunks.length, 1);
129    assert.deepStrictEqual(
130      writable.chunks[0],
131      {
132        chunk: Buffer.from('hello'),
133        encoding: 'buffer'
134      });
135    writer.close().then(common.mustCall());
136  }));
137}
138
139{
140  const duplex = new PassThrough();
141  duplex.setEncoding('utf8');
142  const writableStream = newWritableStreamFromStreamWritable(duplex);
143  const ec = new TextEncoder();
144  writableStream
145    .getWriter()
146    .write(ec.encode('hello'))
147    .then(common.mustCall());
148
149  duplex.on('data', common.mustCall((chunk) => {
150    assert.strictEqual(chunk, 'hello');
151  }));
152}
153
154{
155  const writable = new Writable();
156  writable.destroy();
157  const writableStream = newWritableStreamFromStreamWritable(writable);
158  const writer = writableStream.getWriter();
159  writer.closed.then(common.mustCall());
160}
161
162{
163  const duplex = new Duplex({ writable: false });
164  const writableStream = newWritableStreamFromStreamWritable(duplex);
165  const writer = writableStream.getWriter();
166  writer.closed.then(common.mustCall());
167}
168