1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24const assert = require('assert'); 25 26const stream = require('stream'); 27 28const queue = []; 29for (let decode = 0; decode < 2; decode++) { 30 for (let uncork = 0; uncork < 2; uncork++) { 31 for (let multi = 0; multi < 2; multi++) { 32 queue.push([!!decode, !!uncork, !!multi]); 33 } 34 } 35} 36 37run(); 38 39function run() { 40 const t = queue.pop(); 41 if (t) 42 test(t[0], t[1], t[2], run); 43 else 44 console.log('ok'); 45} 46 47function test(decode, uncork, multi, next) { 48 console.log(`# decode=${decode} uncork=${uncork} multi=${multi}`); 49 let counter = 0; 50 let expectCount = 0; 51 function cnt(msg) { 52 expectCount++; 53 const expect = expectCount; 54 return function(er) { 55 assert.ifError(er); 56 counter++; 57 assert.strictEqual(counter, expect); 58 }; 59 } 60 61 const w = new stream.Writable({ decodeStrings: decode }); 62 w._write = common.mustNotCall('Should not call _write'); 63 64 const expectChunks = decode ? [ 65 { encoding: 'buffer', 66 chunk: [104, 101, 108, 108, 111, 44, 32] }, 67 { encoding: 'buffer', 68 chunk: [119, 111, 114, 108, 100] }, 69 { encoding: 'buffer', 70 chunk: [33] }, 71 { encoding: 'buffer', 72 chunk: [10, 97, 110, 100, 32, 116, 104, 101, 110, 46, 46, 46] }, 73 { encoding: 'buffer', 74 chunk: [250, 206, 190, 167, 222, 173, 190, 239, 222, 202, 251, 173] }, 75 ] : [ 76 { encoding: 'ascii', chunk: 'hello, ' }, 77 { encoding: 'utf8', chunk: 'world' }, 78 { encoding: 'buffer', chunk: [33] }, 79 { encoding: 'latin1', chunk: '\nand then...' }, 80 { encoding: 'hex', chunk: 'facebea7deadbeefdecafbad' }, 81 ]; 82 83 let actualChunks; 84 w._writev = function(chunks, cb) { 85 actualChunks = chunks.map(function(chunk) { 86 return { 87 encoding: chunk.encoding, 88 chunk: Buffer.isBuffer(chunk.chunk) ? 89 Array.prototype.slice.call(chunk.chunk) : chunk.chunk 90 }; 91 }); 92 cb(); 93 }; 94 95 w.cork(); 96 w.write('hello, ', 'ascii', cnt('hello')); 97 w.write('world', 'utf8', cnt('world')); 98 99 if (multi) 100 w.cork(); 101 102 w.write(Buffer.from('!'), 'buffer', cnt('!')); 103 w.write('\nand then...', 'latin1', cnt('and then')); 104 105 if (multi) 106 w.uncork(); 107 108 w.write('facebea7deadbeefdecafbad', 'hex', cnt('hex')); 109 110 if (uncork) 111 w.uncork(); 112 113 w.end(cnt('end')); 114 115 w.on('finish', function() { 116 // Make sure finish comes after all the write cb 117 cnt('finish')(); 118 assert.deepStrictEqual(actualChunks, expectChunks); 119 next(); 120 }); 121} 122 123{ 124 const w = new stream.Writable({ 125 writev: common.mustCall(function(chunks, cb) { 126 cb(); 127 }) 128 }); 129 w.write('asd', common.mustCall()); 130} 131