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