From 98296bb6265b87aa3bbf2903532377844f5509ef Mon Sep 17 00:00:00 2001 From: Calvin Metcalf Date: Fri, 9 Jun 2017 15:36:06 -0400 Subject: [PATCH] Build for node 8.1.0 --- README.md | 4 +- build/build.js | 12 +- build/common-replacements.js | 5 + build/files.js | 58 ++- build/package.json | 2 + build/test-replacements.js | 16 +- lib/_stream_duplex.js | 57 ++- lib/_stream_passthrough.js | 21 + lib/_stream_readable.js | 219 ++++++--- lib/_stream_transform.js | 34 +- lib/_stream_writable.js | 181 ++++++-- lib/internal/streams/BufferList.js | 124 ++--- lib/internal/streams/destroy.js | 72 +++ package.json | 2 +- .../test-stream2-readable-from-list.js | 2 +- test/common.js | 241 +++++++--- test/parallel/test-stream-big-packet.js | 23 +- test/parallel/test-stream-big-push.js | 23 +- .../test-stream-decoder-objectmode.js | 5 +- test/parallel/test-stream-duplex-destroy.js | 223 +++++++++ test/parallel/test-stream-duplex.js | 25 +- test/parallel/test-stream-end-paused.js | 23 +- test/parallel/test-stream-events-prepend.js | 2 +- test/parallel/test-stream-ispaused.js | 21 + test/parallel/test-stream-pipe-after-end.js | 25 +- test/parallel/test-stream-pipe-await-drain.js | 2 +- .../test-stream-pipe-cleanup-pause.js | 2 +- test/parallel/test-stream-pipe-cleanup.js | 21 + .../test-stream-pipe-error-handling.js | 27 +- test/parallel/test-stream-pipe-event.js | 21 + .../test-stream-pipe-multiple-pipes.js | 6 +- ...test-stream-pipe-same-destination-twice.js | 83 ++++ .../test-stream-pipe-unpipe-streams.js | 10 +- .../test-stream-pipe-without-listenerCount.js | 8 +- test/parallel/test-stream-push-order.js | 21 + test/parallel/test-stream-push-strings.js | 23 +- ...stream-readable-constructor-set-methods.js | 16 +- test/parallel/test-stream-readable-destroy.js | 186 ++++++++ .../test-stream-readable-emittedReadable.js | 6 +- test/parallel/test-stream-readable-event.js | 29 +- .../test-stream-readable-flow-recursion.js | 21 + .../test-stream-readable-invalid-chunk.js | 5 +- .../test-stream-readable-needReadable.js | 8 +- .../test-stream-readableListening-state.js | 4 +- .../test-stream-transform-callback-twice.js | 20 + ...tream-transform-constructor-set-methods.js | 24 +- .../parallel/test-stream-transform-destroy.js | 151 +++++++ .../test-stream-transform-final-sync.js | 102 +++++ test/parallel/test-stream-transform-final.js | 104 +++++ ...tream-transform-objectmode-falsey-value.js | 21 + .../test-stream-transform-split-objectmode.js | 21 + test/parallel/test-stream-uint8array.js | 108 +++++ test/parallel/test-stream-unpipe-event.js | 22 +- .../test-stream-unshift-empty-chunk.js | 21 + .../parallel/test-stream-unshift-read-race.js | 25 +- ...stream-writable-change-default-encoding.js | 21 + .../test-stream-writable-decoded-encoding.js | 21 + test/parallel/test-stream-writable-destroy.js | 217 +++++++++ .../test-stream-writable-writev-finish.js | 55 +++ test/parallel/test-stream-write-final.js | 26 ++ test/parallel/test-stream-writev.js | 21 + ...est-stream2-base64-single-char-read-end.js | 27 +- test/parallel/test-stream2-basic.js | 423 ++++++++++++++++++ test/parallel/test-stream2-compatibility.js | 21 + test/parallel/test-stream2-finish-pipe.js | 21 + .../parallel/test-stream2-large-read-stall.js | 21 + test/parallel/test-stream2-objects.js | 36 +- .../test-stream2-pipe-error-handling.js | 21 + .../test-stream2-pipe-error-once-listener.js | 33 +- test/parallel/test-stream2-push.js | 21 + test/parallel/test-stream2-read-sync-stack.js | 23 +- ...st-stream2-readable-empty-buffer-no-eof.js | 25 +- .../test-stream2-readable-from-list.js | 21 + .../test-stream2-readable-legacy-drain.js | 25 +- .../test-stream2-readable-non-empty-end.js | 23 +- .../test-stream2-readable-wrap-empty.js | 27 +- test/parallel/test-stream2-set-encoding.js | 21 + test/parallel/test-stream2-transform.js | 23 +- test/parallel/test-stream2-unpipe-drain.js | 21 + test/parallel/test-stream2-unpipe-leak.js | 21 + test/parallel/test-stream2-writable.js | 54 ++- test/parallel/test-stream3-pause-then-read.js | 21 + test/parallel/test-streams-highwatermark.js | 20 + 83 files changed, 3474 insertions(+), 374 deletions(-) create mode 100644 lib/internal/streams/destroy.js create mode 100644 test/parallel/test-stream-duplex-destroy.js create mode 100644 test/parallel/test-stream-pipe-same-destination-twice.js create mode 100644 test/parallel/test-stream-readable-destroy.js create mode 100644 test/parallel/test-stream-transform-callback-twice.js create mode 100644 test/parallel/test-stream-transform-destroy.js create mode 100644 test/parallel/test-stream-transform-final-sync.js create mode 100644 test/parallel/test-stream-transform-final.js create mode 100644 test/parallel/test-stream-uint8array.js create mode 100644 test/parallel/test-stream-writable-destroy.js create mode 100644 test/parallel/test-stream-writable-writev-finish.js create mode 100644 test/parallel/test-stream-write-final.js create mode 100644 test/parallel/test-stream2-basic.js create mode 100644 test/parallel/test-streams-highwatermark.js diff --git a/README.md b/README.md index 3024d77c69..5ef76c7bb9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # readable-stream -***Node-core v7.0.0 streams for userland*** [![Build Status](https://travis-ci.org/nodejs/readable-stream.svg?branch=master)](https://travis-ci.org/nodejs/readable-stream) +***Node-core v8.1.0 streams for userland*** [![Build Status](https://travis-ci.org/nodejs/readable-stream.svg?branch=master)](https://travis-ci.org/nodejs/readable-stream) [![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/) @@ -18,7 +18,7 @@ npm install --save readable-stream This package is a mirror of the Streams2 and Streams3 implementations in Node-core. -Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v7.10.0/docs/api/stream.html). +Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v8.1.0/docs/api/stream.html). If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core, for background see [this blogpost](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html). diff --git a/build/build.js b/build/build.js index 3e4b7ea096..bf5cc02493 100644 --- a/build/build.js +++ b/build/build.js @@ -16,7 +16,7 @@ const hyperquest = require('hyperquest') , nodeVersionRegexString = '\\d+\\.\\d+\\.\\d+' , usageVersionRegex = RegExp('^' + nodeVersionRegexString + '$') , readmeVersionRegex = - RegExp('((?:Node-core )|(?:https\:\/\/nodejs\.org\/dist\/)v)' + nodeVersionRegexString, 'g') + RegExp('((?:(?:Node-core )|(?:https\:\/\/nodejs\.org\/dist\/))v)' + nodeVersionRegexString, 'g') , readmePath = path.join(__dirname, '..', 'README.md') , files = require('./files') @@ -61,7 +61,9 @@ function processFile (inputLoc, out, replacements) { 'transform-es2015-shorthand-properties', 'transform-es2015-for-of', 'transform-es2015-classes', - 'transform-es2015-destructuring' + 'transform-es2015-destructuring', + 'transform-es2015-computed-properties', + 'transform-es2015-spread' ] }) data = transformed.code @@ -134,7 +136,8 @@ pump( file !== 'test-stream2-httpclient-response-end.js' && file !== 'test-stream-base-no-abort.js' && file !== 'test-stream-preprocess.js' && - file !== 'test-stream-inheritance.js') { + file !== 'test-stream-inheritance.js' && + file !== 'test-stream-base-typechecking.js') { processTestFile(file) } }) @@ -145,14 +148,13 @@ pump( // Grab the nodejs/node test/common.js processFile( - testsrcurl.replace(/parallel\/$/, 'common.js') + testsrcurl.replace(/parallel\/$/, 'common/index.js') , path.join(testourroot, '../common.js') , testReplace['common.js'] ) //-------------------------------------------------------------------- // Update Node version in README - processFile(readmePath, readmePath, [ [readmeVersionRegex, "$1" + nodeVersion] ]) diff --git a/build/common-replacements.js b/build/common-replacements.js index 8e84d4a208..c2dd472456 100644 --- a/build/common-replacements.js +++ b/build/common-replacements.js @@ -12,6 +12,11 @@ module.exports.altForEachUseReplacement = [ , '$1forEach($2, ' ] +module.exports.specialForEachReplacment = [ + /(\W)(\[(?:\d\,\s)+\d\])(\.forEach\()/gm + , '$1forEach($2, ' +] + module.exports.altIndexOfImplReplacement = [ /$/ , '\nfunction indexOf (xs, x) {\n' diff --git a/build/files.js b/build/files.js index e263eda9d2..949bc77c2c 100644 --- a/build/files.js +++ b/build/files.js @@ -121,7 +121,7 @@ const headRegexp = /(^module.exports = \w+;?)/m ] , processNextTickImport = [ - headRegexp + /^('use strict';)$/m , `$1 /**/ @@ -166,8 +166,8 @@ const headRegexp = /(^module.exports = \w+;?)/m /**/` ] , internalDirectory = [ - /require\('internal\/streams\/BufferList'\)/, - 'require(\'./internal/streams/BufferList\')' + /require\('internal\/streams\/([a-zA-z]+)'\)/g, + 'require(\'./internal/streams/$1\')' ] , fixInstanceCheck = [ /if \(typeof Symbol === 'function' && Symbol\.hasInstance\) \{/, @@ -177,20 +177,32 @@ const headRegexp = /(^module.exports = \w+;?)/m /onwrite\.bind\([^)]+?\)/, `function(er) { onwrite(stream, er); }` ] - , removeCorkedFinishBind = [ - /onCorkedFinish\.bind\([^)]+?\)/, - function (match) { - const code = this - var src = /^function onCorkedFinish[^{]*?\{([\s\S]+?\r?\n)\}/m.exec(code) - src = src[1].trim().replace(/corkReq/g, 'this').replace(/(\r?\n)/mg, ' $1') - return `(err) => {\n${src}\n}` - } + , addUintStuff = [ + /const Buffer = require\('buffer'\)\.Buffer;/, + `/**/ + const Buffer = require('safe-buffer').Buffer + +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} +function _isUint8Array(obj) { + return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj); +} +/**/ +` ] - , removeOnCorkedFinish = [ - /^function onCorkedFinish[\s\S]+?\r?\n\}/m, - '' + , fixUintStuff = [ + /Stream\.(_isUint8Array|_uint8ArrayToBuffer)\(/g, + `$1(` + ] + , fixBufferCheck = [ + /Object\.getPrototypeOf\((chunk)\) !== Buffer\.prototype/g, + '!Buffer.isBuffer($1)' + ] + , fixCopyBuffer = [ + /Buffer\.prototype\.copy\.call\(src, target, offset\);/, + 'src.copy(target, offset);' ] - module.exports['_stream_duplex.js'] = [ requireReplacement , instanceofReplacement @@ -233,8 +245,9 @@ module.exports['_stream_readable.js'] = [ , processNextTickImport , processNextTickReplacement , eventEmittterListenerCountReplacement - , safeBufferFix , internalDirectory + , fixUintStuff + , addUintStuff ] module.exports['_stream_transform.js'] = [ @@ -264,12 +277,19 @@ module.exports['_stream_writable.js'] = [ , processNextTickReplacement , internalUtilReplacement , fixSyncWrite - , safeBufferFix , fixInstanceCheck , removeOnWriteBind - , removeCorkedFinishBind - , removeOnCorkedFinish + , internalDirectory + , fixUintStuff + , addUintStuff + , fixBufferCheck ] module.exports['internal/streams/BufferList.js'] = [ safeBufferFix + , fixCopyBuffer + +] +module.exports['internal/streams/destroy.js'] = [ + processNextTickImport + , processNextTickReplacement ] diff --git a/build/package.json b/build/package.json index 384a3fc406..a72e400a0c 100644 --- a/build/package.json +++ b/build/package.json @@ -8,10 +8,12 @@ "babel-plugin-transform-es2015-arrow-functions": "^6.5.2", "babel-plugin-transform-es2015-block-scoping": "^6.24.1", "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", "babel-plugin-transform-es2015-destructuring": "^6.18.0", "babel-plugin-transform-es2015-for-of": "^6.8.0", "babel-plugin-transform-es2015-parameters": "^6.24.1", "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", "babel-plugin-transform-es2015-template-literals": "^6.8.0", "bl": "^1.2.1", "glob": "^7.1.2", diff --git a/build/test-replacements.js b/build/test-replacements.js index c3b0790442..ce8be65161 100644 --- a/build/test-replacements.js +++ b/build/test-replacements.js @@ -10,6 +10,8 @@ const altForEachImplReplacement = require('./common-replacements').altForEachImp require('./common-replacements').bufferShimFix , bufferStaticMethods = require('./common-replacements').bufferStaticMethods + , specialForEachReplacment = + require('./common-replacements').specialForEachReplacment module.exports.all = [ [ @@ -44,7 +46,7 @@ module.exports.all = [ module.exports['test-stream2-basic.js'] = [ altForEachImplReplacement - , altForEachUseReplacement + , specialForEachReplacment ] module.exports['test-stream2-objects.js'] = [ @@ -182,6 +184,18 @@ module.exports['common.js'] = [ [ /exports\.buildType/, '//exports.buildType' +], +[ + /require\('async_hooks'\)/, + '/*require(\'async_hooks\')' +], +[ + /\}\).enable\(\);/, + '}).enable();*/' +], +[ + /const async_wrap = process.binding\('async_wrap'\);/, + '//const async_wrap = process.binding(\'async_wrap\');' ] ] diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js index 736693b840..c599463dd8 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + // a duplex stream is just a stream that is both readable and writable. // Since JS doesn't have multiple prototypal inheritance, this class // prototypally inherits from Readable, and then parasitically from @@ -7,6 +28,10 @@ /**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ var objectKeys = Object.keys || function (obj) { var keys = []; for (var key in obj) { @@ -17,10 +42,6 @@ var objectKeys = Object.keys || function (obj) { module.exports = Duplex; -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - /**/ var util = require('core-util-is'); util.inherits = require('inherits'); @@ -68,6 +89,34 @@ function onEndNT(self) { self.end(); } +Object.defineProperty(Duplex.prototype, 'destroyed', { + get: function () { + if (this._readableState === undefined || this._writableState === undefined) { + return false; + } + return this._readableState.destroyed && this._writableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (this._readableState === undefined || this._writableState === undefined) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + this._writableState.destroyed = value; + } +}); + +Duplex.prototype._destroy = function (err, cb) { + this.push(null); + this.end(); + + processNextTick(cb, err); +}; + function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js index d06f71f186..a9c8358848 100644 --- a/lib/_stream_passthrough.js +++ b/lib/_stream_passthrough.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + // a passthrough stream. // basically just the most minimal sort of Transform stream. // Every written chunk gets output as-is. diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index a01012e3cf..8459c71565 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -1,11 +1,33 @@ -'use strict'; +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -module.exports = Readable; +'use strict'; /**/ + var processNextTick = require('process-nextick-args'); /**/ +module.exports = Readable; + /**/ var isArray = require('isarray'); /**/ @@ -30,6 +52,13 @@ var Stream = require('./internal/streams/stream'); /**/ var Buffer = require('safe-buffer').Buffer; + +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} +function _isUint8Array(obj) { + return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj); +} /**/ /**/ @@ -48,6 +77,7 @@ if (debugUtil && debugUtil.debuglog) { /**/ var BufferList = require('./internal/streams/BufferList'); +var destroyImpl = require('./internal/streams/destroy'); var StringDecoder; util.inherits(Readable, Stream); @@ -86,7 +116,7 @@ function ReadableState(options, stream) { this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. - this.highWaterMark = ~~this.highWaterMark; + this.highWaterMark = Math.floor(this.highWaterMark); // A linked list is used to store data chunks instead of an array because the // linked list can remove elements from the beginning faster than @@ -100,10 +130,10 @@ function ReadableState(options, stream) { this.endEmitted = false; this.reading = false; - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. + // a flag to be able to tell if the event 'readable'/'data' is emitted + // immediately, or on a later tick. We set this to true at first, because + // any actions that shouldn't happen until "later" should generally also + // not happen before the first read call. this.sync = true; // whenever we return null, then we set a flag to say @@ -113,15 +143,14 @@ function ReadableState(options, stream) { this.readableListening = false; this.resumeScheduled = false; + // has it been destroyed + this.destroyed = false; + // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; - // when piping, we only care about 'readable' events that happen - // after read()ing all the bytes and not getting any pushback. - this.ranOut = false; - // the number of writers that are awaiting a drain event in .pipe()s this.awaitDrain = 0; @@ -147,87 +176,129 @@ function Readable(options) { // legacy this.readable = true; - if (options && typeof options.read === 'function') this._read = options.read; + if (options) { + if (typeof options.read === 'function') this._read = options.read; + + if (typeof options.destroy === 'function') this._destroy = options.destroy; + } Stream.call(this); } +Object.defineProperty(Readable.prototype, 'destroyed', { + get: function () { + if (this._readableState === undefined) { + return false; + } + return this._readableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._readableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + } +}); + +Readable.prototype.destroy = destroyImpl.destroy; +Readable.prototype._undestroy = destroyImpl.undestroy; +Readable.prototype._destroy = function (err, cb) { + this.push(null); + cb(err); +}; + // Manually shove something into the read() buffer. // This returns true if the highWaterMark has not been hit yet, // similar to how Writable.write() returns true if you should // write() some more. Readable.prototype.push = function (chunk, encoding) { var state = this._readableState; - - if (!state.objectMode && typeof chunk === 'string') { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = Buffer.from(chunk, encoding); - encoding = ''; + var skipChunkCheck; + + if (!state.objectMode) { + if (typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = Buffer.from(chunk, encoding); + encoding = ''; + } + skipChunkCheck = true; } + } else { + skipChunkCheck = true; } - return readableAddChunk(this, state, chunk, encoding, false); + return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); }; // Unshift should *always* be something directly out of read() Readable.prototype.unshift = function (chunk) { - var state = this._readableState; - return readableAddChunk(this, state, chunk, '', true); + return readableAddChunk(this, chunk, null, true, false); }; -Readable.prototype.isPaused = function () { - return this._readableState.flowing === false; -}; - -function readableAddChunk(stream, state, chunk, encoding, addToFront) { - var er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (chunk === null) { +function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { + var state = stream._readableState; + if (chunk === null) { state.reading = false; onEofChunk(stream, state); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); - } else if (state.endEmitted && addToFront) { - var _e = new Error('stream.unshift() after end event'); - stream.emit('error', _e); - } else { - var skipAdd; - if (state.decoder && !addToFront && !encoding) { - chunk = state.decoder.write(chunk); - skipAdd = !state.objectMode && chunk.length === 0; + } else { + var er; + if (!skipChunkCheck) er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (typeof chunk !== 'string' && Object.getPrototypeOf(chunk) !== Buffer.prototype && !state.objectMode) { + chunk = _uint8ArrayToBuffer(chunk); } - if (!addToFront) state.reading = false; - - // Don't add to the buffer if we've decoded to an empty string chunk and - // we're not in object mode - if (!skipAdd) { - // if we want the data now, just emit it. - if (state.flowing && state.length === 0 && !state.sync) { - stream.emit('data', chunk); - stream.read(0); + if (addToFront) { + if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); + } else if (state.ended) { + stream.emit('error', new Error('stream.push() after EOF')); + } else { + state.reading = false; + if (state.decoder && !encoding) { + chunk = state.decoder.write(chunk); + if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - - if (state.needReadable) emitReadable(stream); + addChunk(stream, state, chunk, false); } } - - maybeReadMore(stream, state); + } else if (!addToFront) { + state.reading = false; } - } else if (!addToFront) { - state.reading = false; } return needMoreData(state); } +function addChunk(stream, state, chunk, addToFront) { + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + + if (state.needReadable) emitReadable(stream); + } + maybeReadMore(stream, state); +} + +function chunkInvalid(state, chunk) { + var er; + if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + // if it's past the high water mark, we can push in some more. // Also, if we have no data yet, we can stand some // more bytes. This is to work around cases where hwm=0, @@ -239,6 +310,10 @@ function needMoreData(state) { return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); } +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; +}; + // backwards compatibility. Readable.prototype.setEncoding = function (enc) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; @@ -387,14 +462,6 @@ Readable.prototype.read = function (n) { return ret; }; -function chunkInvalid(state, chunk) { - var er = null; - if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - return er; -} - function onEofChunk(stream, state) { if (state.ended) return; if (state.decoder) { @@ -486,10 +553,13 @@ Readable.prototype.pipe = function (dest, pipeOpts) { if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); - function onunpipe(readable) { + function onunpipe(readable, unpipeInfo) { debug('onunpipe'); if (readable === src) { - cleanup(); + if (unpipeInfo && unpipeInfo.hasUnpiped === false) { + unpipeInfo.hasUnpiped = true; + cleanup(); + } } } @@ -608,6 +678,7 @@ function pipeOnDrain(src) { Readable.prototype.unpipe = function (dest) { var state = this._readableState; + var unpipeInfo = { hasUnpiped: false }; // if we're not piping anywhere, then do nothing. if (state.pipesCount === 0) return this; @@ -623,7 +694,7 @@ Readable.prototype.unpipe = function (dest) { state.pipes = null; state.pipesCount = 0; state.flowing = false; - if (dest) dest.emit('unpipe', this); + if (dest) dest.emit('unpipe', this, unpipeInfo); return this; } @@ -638,7 +709,7 @@ Readable.prototype.unpipe = function (dest) { state.flowing = false; for (var i = 0; i < len; i++) { - dests[i].emit('unpipe', this); + dests[i].emit('unpipe', this, unpipeInfo); }return this; } @@ -650,7 +721,7 @@ Readable.prototype.unpipe = function (dest) { state.pipesCount -= 1; if (state.pipesCount === 1) state.pipes = state.pipes[0]; - dest.emit('unpipe', this); + dest.emit('unpipe', this, unpipeInfo); return this; }; @@ -671,7 +742,7 @@ Readable.prototype.on = function (ev, fn) { if (!state.reading) { processNextTick(nReadingNextTick, this); } else if (state.length) { - emitReadable(this, state); + emitReadable(this); } } } diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js index cd2583207f..a0c23173da 100644 --- a/lib/_stream_transform.js +++ b/lib/_stream_transform.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + // a transform stream is a readable/writable stream where you do // something with the data. Sometimes it's called a "filter", // but that's not a great name for it, since that implies a thing where @@ -71,7 +92,9 @@ function afterTransform(stream, er, data) { var cb = ts.writecb; - if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); + if (!cb) { + return stream.emit('error', new Error('write callback called multiple times')); + } ts.writechunk = null; ts.writecb = null; @@ -164,6 +187,15 @@ Transform.prototype._read = function (n) { } }; +Transform.prototype._destroy = function (err, cb) { + var _this = this; + + Duplex.prototype._destroy.call(this, err, function (err2) { + cb(err2); + _this.emit('close'); + }); +}; + function done(stream, er, data) { if (er) return stream.emit('error', er); diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index e9701f5007..f402d848fd 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -1,15 +1,37 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + // A bit simpler than readable streams. // Implement an async ._write(chunk, encoding, cb), and it'll handle all // the drain event emission and buffering. 'use strict'; -module.exports = Writable; - /**/ + var processNextTick = require('process-nextick-args'); /**/ +module.exports = Writable; + /**/ var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; /**/ @@ -37,19 +59,21 @@ var Stream = require('./internal/streams/stream'); /**/ var Buffer = require('safe-buffer').Buffer; + +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} +function _isUint8Array(obj) { + return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj); +} /**/ +var destroyImpl = require('./internal/streams/destroy'); + util.inherits(Writable, Stream); function nop() {} -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; - this.next = null; -} - function WritableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); @@ -69,7 +93,10 @@ function WritableState(options, stream) { this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. - this.highWaterMark = ~~this.highWaterMark; + this.highWaterMark = Math.floor(this.highWaterMark); + + // if _final has been called + this.finalCalled = false; // drain event flag. this.needDrain = false; @@ -80,6 +107,9 @@ function WritableState(options, stream) { // when 'finish' is emitted this.finished = false; + // has it been destroyed + this.destroyed = false; + // should we decode strings into buffers before passing to _write? // this is here so that some node-core streams can optimize string // handling at a lower level. @@ -143,7 +173,9 @@ function WritableState(options, stream) { // allocate the first CorkedRequest, there is always // one allocated and free to use, and we maintain at most two - this.corkedRequestsFree = new CorkedRequest(this); + var corkReq = { next: null, entry: null, finish: undefined }; + corkReq.finish = onCorkedFinish.bind(undefined, corkReq, this); + this.corkedRequestsFree = corkReq; } WritableState.prototype.getBuffer = function getBuffer() { @@ -161,7 +193,7 @@ WritableState.prototype.getBuffer = function getBuffer() { Object.defineProperty(WritableState.prototype, 'buffer', { get: internalUtil.deprecate(function () { return this.getBuffer(); - }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.') + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') }); } catch (_) {} })(); @@ -207,6 +239,10 @@ function Writable(options) { if (typeof options.write === 'function') this._write = options.write; if (typeof options.writev === 'function') this._writev = options.writev; + + if (typeof options.destroy === 'function') this._destroy = options.destroy; + + if (typeof options.final === 'function') this._final = options.final; } Stream.call(this); @@ -247,7 +283,11 @@ function validChunk(stream, state, chunk, cb) { Writable.prototype.write = function (chunk, encoding, cb) { var state = this._writableState; var ret = false; - var isBuf = Buffer.isBuffer(chunk); + var isBuf = _isUint8Array(chunk) && !state.objectMode; + + if (isBuf && !Buffer.isBuffer(chunk)) { + chunk = _uint8ArrayToBuffer(chunk); + } if (typeof encoding === 'function') { cb = encoding; @@ -302,8 +342,12 @@ function decodeChunk(state, chunk, encoding) { // If we return false, then we need a drain event, so set that flag. function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { if (!isBuf) { - chunk = decodeChunk(state, chunk, encoding); - if (Buffer.isBuffer(chunk)) encoding = 'buffer'; + var newChunk = decodeChunk(state, chunk, encoding); + if (chunk !== newChunk) { + isBuf = true; + encoding = 'buffer'; + chunk = newChunk; + } } var len = state.objectMode ? 1 : chunk.length; @@ -315,7 +359,13 @@ function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { if (state.writing || state.corked) { var last = state.lastBufferedRequest; - state.lastBufferedRequest = new WriteReq(chunk, encoding, cb); + state.lastBufferedRequest = { + chunk: chunk, + encoding: encoding, + isBuf: isBuf, + callback: cb, + next: null + }; if (last) { last.next = state.lastBufferedRequest; } else { @@ -340,12 +390,17 @@ function doWrite(stream, state, writev, len, chunk, encoding, cb) { function onwriteError(stream, state, sync, er, cb) { --state.pendingcb; - if (sync) processNextTick(cb, er);else cb(er); + if (sync) processNextTick(afterError, stream, state, cb, er);else afterError(stream, state, cb, er); stream._writableState.errorEmitted = true; stream.emit('error', er); } +function afterError(stream, state, cb, err) { + cb(err); + finishMaybe(stream, state); +} + function onwriteStateUpdate(state) { state.writing = false; state.writecb = null; @@ -408,11 +463,14 @@ function clearBuffer(stream, state) { holder.entry = entry; var count = 0; + var allBuffers = true; while (entry) { buffer[count] = entry; + if (!entry.isBuf) allBuffers = false; entry = entry.next; count += 1; } + buffer.allBuffers = allBuffers; doWrite(stream, state, true, state.length, buffer, '', holder.finish); @@ -424,7 +482,9 @@ function clearBuffer(stream, state) { state.corkedRequestsFree = holder.next; holder.next = null; } else { - state.corkedRequestsFree = new CorkedRequest(state); + var corkReq = { next: null, entry: null, finish: undefined }; + corkReq.finish = onCorkedFinish.bind(undefined, corkReq, state); + state.corkedRequestsFree = corkReq; } } else { // Slow case, write chunks one-by-one @@ -486,23 +546,37 @@ Writable.prototype.end = function (chunk, encoding, cb) { function needFinish(state) { return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; } - -function prefinish(stream, state) { - if (!state.prefinished) { +function callFinal(stream, state) { + stream._final(function (err) { + state.pendingcb--; + if (err) { + stream.emit('error', err); + } state.prefinished = true; stream.emit('prefinish'); + finishMaybe(stream, state); + }); +} +function prefinish(stream, state) { + if (!state.prefinished && !state.finalCalled) { + if (typeof stream._final === 'function') { + state.pendingcb++; + state.finalCalled = true; + processNextTick(callFinal, stream, state); + } else { + state.prefinished = true; + stream.emit('prefinish'); + } } } function finishMaybe(stream, state) { var need = needFinish(state); if (need) { + prefinish(stream, state); if (state.pendingcb === 0) { - prefinish(stream, state); state.finished = true; stream.emit('finish'); - } else { - prefinish(stream, state); } } return need; @@ -518,26 +592,45 @@ function endWritable(stream, state, cb) { stream.writable = false; } -// It seems a linked list but it is not -// there will be only 2 of these for each stream -function CorkedRequest(state) { - var _this = this; +function onCorkedFinish(corkReq, state, err) { + var entry = corkReq.entry; + corkReq.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = corkReq; + } else { + state.corkedRequestsFree = corkReq; + } +} - this.next = null; - this.entry = null; - this.finish = function (err) { - var entry = _this.entry; - _this.entry = null; - while (entry) { - var cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; +Object.defineProperty(Writable.prototype, 'destroyed', { + get: function () { + if (this._writableState === undefined) { + return false; } - if (state.corkedRequestsFree) { - state.corkedRequestsFree.next = _this; - } else { - state.corkedRequestsFree = _this; + return this._writableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._writableState) { + return; } - }; -} \ No newline at end of file + + // backward compatibility, the user is explicitly + // managing destroyed + this._writableState.destroyed = value; + } +}); + +Writable.prototype.destroy = destroyImpl.destroy; +Writable.prototype._undestroy = destroyImpl.undestroy; +Writable.prototype._destroy = function (err, cb) { + this.end(); + cb(err); +}; \ No newline at end of file diff --git a/lib/internal/streams/BufferList.js b/lib/internal/streams/BufferList.js index 82598c8521..8546bb06e4 100644 --- a/lib/internal/streams/BufferList.js +++ b/lib/internal/streams/BufferList.js @@ -2,63 +2,83 @@ /**/ +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + var Buffer = require('safe-buffer').Buffer; /**/ -module.exports = BufferList; - -function BufferList() { - this.head = null; - this.tail = null; - this.length = 0; +function copyBuffer(src, target, offset) { + src.copy(target, offset); } -BufferList.prototype.push = function (v) { - var entry = { data: v, next: null }; - if (this.length > 0) this.tail.next = entry;else this.head = entry; - this.tail = entry; - ++this.length; -}; - -BufferList.prototype.unshift = function (v) { - var entry = { data: v, next: this.head }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; -}; +module.exports = function () { + function BufferList() { + _classCallCheck(this, BufferList); -BufferList.prototype.shift = function () { - if (this.length === 0) return; - var ret = this.head.data; - if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; - --this.length; - return ret; -}; - -BufferList.prototype.clear = function () { - this.head = this.tail = null; - this.length = 0; -}; + this.head = null; + this.tail = null; + this.length = 0; + } -BufferList.prototype.join = function (s) { - if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; - while (p = p.next) { - ret += s + p.data; - }return ret; -}; + _createClass(BufferList, [{ + key: 'push', + value: function push(v) { + var entry = { data: v, next: null }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; + } + }, { + key: 'unshift', + value: function unshift(v) { + var entry = { data: v, next: this.head }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; + } + }, { + key: 'shift', + value: function shift() { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; + } + }, { + key: 'clear', + value: function clear() { + this.head = this.tail = null; + this.length = 0; + } + }, { + key: 'join', + value: function join(s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + while (p = p.next) { + ret += s + p.data; + }return ret; + } + }, { + key: 'concat', + value: function concat(n) { + if (this.length === 0) return Buffer.alloc(0); + if (this.length === 1) return this.head.data; + var ret = Buffer.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + while (p) { + copyBuffer(p.data, ret, i); + i += p.data.length; + p = p.next; + } + return ret; + } + }]); -BufferList.prototype.concat = function (n) { - if (this.length === 0) return Buffer.alloc(0); - if (this.length === 1) return this.head.data; - var ret = Buffer.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; - while (p) { - p.data.copy(ret, i); - i += p.data.length; - p = p.next; - } - return ret; -}; \ No newline at end of file + return BufferList; +}(); \ No newline at end of file diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js new file mode 100644 index 0000000000..b3e58c33bc --- /dev/null +++ b/lib/internal/streams/destroy.js @@ -0,0 +1,72 @@ +'use strict'; + +/**/ + +var processNextTick = require('process-nextick-args'); +/**/ + +// undocumented cb() API, needed for core, not for public API +function destroy(err, cb) { + var _this = this; + + var readableDestroyed = this._readableState && this._readableState.destroyed; + var writableDestroyed = this._writableState && this._writableState.destroyed; + + if (readableDestroyed || writableDestroyed) { + if (cb) { + cb(err); + } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { + processNextTick(emitErrorNT, this, err); + } + return; + } + + // we set destroyed to true before firing error callbacks in order + // to make it re-entrance safe in case destroy() is called within callbacks + + if (this._readableState) { + this._readableState.destroyed = true; + } + + // if this is a duplex stream mark the writable part as destroyed as well + if (this._writableState) { + this._writableState.destroyed = true; + } + + this._destroy(err || null, function (err) { + if (!cb && err) { + processNextTick(emitErrorNT, _this, err); + if (_this._writableState) { + _this._writableState.errorEmitted = true; + } + } else if (cb) { + cb(err); + } + }); +} + +function undestroy() { + if (this._readableState) { + this._readableState.destroyed = false; + this._readableState.reading = false; + this._readableState.ended = false; + this._readableState.endEmitted = false; + } + + if (this._writableState) { + this._writableState.destroyed = false; + this._writableState.ended = false; + this._writableState.ending = false; + this._writableState.finished = false; + this._writableState.errorEmitted = false; + } +} + +function emitErrorNT(self, err) { + self.emit('error', err); +} + +module.exports = { + destroy: destroy, + undestroy: undestroy +}; \ No newline at end of file diff --git a/package.json b/package.json index b3af0ae138..23db831196 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~1.0.6", - "safe-buffer": "~5.0.1", + "safe-buffer": "~5.1.0", "string_decoder": "~1.0.0", "util-deprecate": "~1.0.1" }, diff --git a/test/browser/test-stream2-readable-from-list.js b/test/browser/test-stream2-readable-from-list.js index e0f2b1b80d..7522b05692 100644 --- a/test/browser/test-stream2-readable-from-list.js +++ b/test/browser/test-stream2-readable-from-list.js @@ -1,6 +1,6 @@ // Flags: --expose_internals /**/ -var bufferShim = require('buffer-shims'); +var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var fromList = require('../../lib/_stream_readable')._fromList; diff --git a/test/common.js b/test/common.js index e564be1271..4fd2116ea2 100644 --- a/test/common.js +++ b/test/common.js @@ -1,3 +1,5 @@ +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + /**/ require('babel-polyfill'); var util = require('util'); @@ -15,6 +17,27 @@ if (!global.clearImmediate) { }; } /**/ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /* eslint-disable required-modules */ 'use strict'; @@ -33,6 +56,7 @@ var assert = require('assert'); var os = require('os'); var child_process = require('child_process'); var stream = require('../'); +var buffer = require('buffer'); /**/ var util = require('core-util-is'); @@ -42,9 +66,12 @@ util.inherits = require('inherits'); var Timer = { now: function () {} }; var execSync = require('child_process').execSync; -var testRoot = process.env.NODE_TEST_DIR ? fs.realpathSync(process.env.NODE_TEST_DIR) : __dirname; +var testRoot = process.env.NODE_TEST_DIR ? fs.realpathSync(process.env.NODE_TEST_DIR) : path.resolve(__dirname, '..'); -exports.fixturesDir = path.join(__dirname, 'fixtures'); +var noop = function () {}; + +exports.noop = noop; +exports.fixturesDir = path.join(__dirname, '..', 'fixtures'); exports.tmpDirName = 'tmp'; // PORT should match the definition in test/testpy/__init__.py. exports.PORT = +process.env.NODE_COMMON_PORT || 12346; @@ -58,7 +85,7 @@ exports.isLinux = process.platform === 'linux'; exports.isOSX = process.platform === 'darwin'; exports.enoughTestMem = os.totalmem() > 0x40000000; /* 1 Gb */ - +exports.bufferMaxSizeMsg = new RegExp('^RangeError: "size" argument must not be larger than ' + buffer.kMaxLength + '$'); var cpus = os.cpus(); /*exports.enoughTestCpu = Array.isArray(cpus) && (cpus.length > 1 || cpus[0].speed > 999);*/ @@ -66,6 +93,51 @@ var cpus = os.cpus(); exports.rootDir = exports.isWindows ? 'c:\\' : '/'; //exports.buildType = process.config.target_defaults.default_configuration; +// If env var is set then enable async_hook hooks for all tests. +if (process.env.NODE_TEST_WITH_ASYNC_HOOKS) { + var destroydIdsList = {}; + var destroyListList = {}; + var initHandles = {}; + //const async_wrap = process.binding('async_wrap'); + + process.on('exit', function () { + // itterate through handles to make sure nothing crashes + for (var k in initHandles) { + util.inspect(initHandles[k]); + } + }); + + var _addIdToDestroyList = async_wrap.addIdToDestroyList; + async_wrap.addIdToDestroyList = function addIdToDestroyList(id) { + if (destroyListList[id] !== undefined) { + process._rawDebug(destroyListList[id]); + process._rawDebug(); + throw new Error('same id added twice (' + id + ')'); + } + destroyListList[id] = new Error().stack; + _addIdToDestroyList(id); + }; + + /*require('async_hooks').createHook({ + init(id, ty, tr, h) { + if (initHandles[id]) { + throw new Error(`init called twice for same id (${id})`); + } + initHandles[id] = h; + }, + before() { }, + after() { }, + destroy(id) { + if (destroydIdsList[id] !== undefined) { + process._rawDebug(destroydIdsList[id]); + process._rawDebug(); + throw new Error(`destroy called for same id (${id})`); + } + destroydIdsList[id] = new Error().stack; + }, + }).enable();*/ +} + function rimrafSync(p) { var st = void 0; try { @@ -239,8 +311,8 @@ exports.childShouldThrowAndAbort = function () { // continuous testing and developers' machines testCmd += 'ulimit -c 0 && '; } - testCmd += process.argv[0] + ' --abort-on-uncaught-exception '; - testCmd += process.argv[1] + ' child'; + testCmd += '"' + process.argv[0] + '" --abort-on-uncaught-exception '; + testCmd += '"' + process.argv[1] + '" child'; var child = child_process.exec(testCmd); child.on('exit', function onExit(exitCode, signal) { var errMsg = 'Test should have aborted ' + ('but instead exited with exit code ' + exitCode) + (' and signal ' + signal); @@ -397,7 +469,7 @@ process.on('exit', function () { if (!exports.globalCheck) return; var leaked = leakedGlobals(); if (leaked.length > 0) { - fail('Unexpected global(s) found: ' + leaked.join(', ')); + assert.fail('Unexpected global(s) found: ' + leaked.join(', ')); } }); @@ -407,26 +479,44 @@ function runCallChecks(exitCode) { if (exitCode !== 0) return; var failed = mustCallChecks.filter(function (context) { - return context.actual !== context.expected; + if ('minimum' in context) { + context.messageSegment = 'at least ' + context.minimum; + return context.actual < context.minimum; + } else { + context.messageSegment = 'exactly ' + context.exact; + return context.actual !== context.exact; + } }); forEach(failed, function (context) { - console.log('Mismatched %s function calls. Expected %d, actual %d.', context.name, context.expected, context.actual); + console.log('Mismatched %s function calls. Expected %s, actual %d.', context.name, context.messageSegment, context.actual); console.log(context.stack.split('\n').slice(2).join('\n')); }); if (failed.length) process.exit(1); } -exports.mustCall = function (fn, expected) { - if (expected === undefined) expected = 1;else if (typeof expected !== 'number') throw new TypeError('Invalid expected value: ' + expected); +exports.mustCall = function (fn, exact) { + return _mustCallInner(fn, exact, 'exact'); +}; + +exports.mustCallAtLeast = function (fn, minimum) { + return _mustCallInner(fn, minimum, 'minimum'); +}; + +function _mustCallInner(fn, criteria, field) { + var _context; - var context = { - expected: expected, - actual: 0, - stack: new Error().stack, - name: fn.name || '' - }; + if (typeof fn === 'number') { + criteria = fn; + fn = noop; + } else if (fn === undefined) { + fn = noop; + } + + if (criteria === undefined) criteria = 1;else if (typeof criteria !== 'number') throw new TypeError('Invalid ' + field + ' value: ' + criteria); + + var context = (_context = {}, _defineProperty(_context, field, criteria), _defineProperty(_context, 'actual', 0), _defineProperty(_context, 'stack', new Error().stack), _defineProperty(_context, 'name', fn.name || ''), _context); // add the exit listener only once to avoid listener leak warnings if (mustCallChecks.length === 0) process.on('exit', runCallChecks); @@ -437,7 +527,7 @@ exports.mustCall = function (fn, expected) { context.actual++; return fn.apply(this, arguments); }; -}; +} exports.hasMultiLocalhost = function hasMultiLocalhost() { var TCP = process.binding('tcp_wrap').TCP; @@ -483,14 +573,9 @@ exports.canCreateSymLink = function () { return true; }; -function fail(msg) { - assert.fail(null, null, msg); -} -exports.fail = fail; - exports.mustNotCall = function (msg) { return function mustNotCall() { - fail(msg || 'function should not have been called'); + assert.fail(msg || 'function should not have been called'); }; }; @@ -513,9 +598,9 @@ util.inherits(ArrayStream, stream.Stream); exports.ArrayStream = ArrayStream; ArrayStream.prototype.readable = true; ArrayStream.prototype.writable = true; -ArrayStream.prototype.pause = function () {}; -ArrayStream.prototype.resume = function () {}; -ArrayStream.prototype.write = function () {}; +ArrayStream.prototype.pause = noop; +ArrayStream.prototype.resume = noop; +ArrayStream.prototype.write = noop; // Returns true if the exit code "exitCode" and/or signal name "signal" // represent the exit code and/or signal name of a node process that aborted, @@ -532,9 +617,12 @@ exports.nodeProcessAborted = function nodeProcessAborted(exitCode, signal) { // or SIGABRT (depending on the compiler). var expectedSignals = ['SIGILL', 'SIGTRAP', 'SIGABRT']; - // On Windows, v8's base::OS::Abort triggers an access violation, + // On Windows, 'aborts' are of 2 types, depending on the context: + // (i) Forced access violation, if --abort-on-uncaught-exception is on // which corresponds to exit code 3221225477 (0xC0000005) - if (exports.isWindows) expectedExitCodes = [3221225477]; + // (ii) raise(SIGABRT) or abort(), which lands up in CRT library calls + // which corresponds to exit code 3. + if (exports.isWindows) expectedExitCodes = [3221225477, 3]; // When using --abort-on-uncaught-exception, V8 will use // base::OS::Abort to terminate the process. @@ -615,34 +703,6 @@ exports.expectWarning = function (nameOrMap, expected) { }); } /**/ -// https://github.com/w3c/testharness.js/blob/master/testharness.js -exports.WPT = { - test: function (fn, desc) { - try { - fn(); - } catch (err) { - if (err instanceof Error) err.message = 'In ' + desc + ':\n ' + err.message; - throw err; - } - }, - assert_equals: assert.strictEqual, - assert_true: function (value, message) { - return assert.strictEqual(value, true, message); - }, - assert_false: function (value, message) { - return assert.strictEqual(value, false, message); - }, - assert_throws: function (code, func, desc) { - assert.throws(func, function (err) { - return typeof err === 'object' && 'name' in err && err.name === code.name; - }, desc); - }, - assert_array_equals: assert.deepStrictEqual, - assert_unreached: function (desc) { - assert.fail(undefined, undefined, 'Reached unreachable code: ' + desc); - } -}; - // Useful for testing expected internal/error objects exports.expectsError = function expectsError(_ref) { var code = _ref.code, @@ -661,6 +721,75 @@ exports.expectsError = function expectsError(_ref) { }; }; +exports.skipIfInspectorDisabled = function skipIfInspectorDisabled() { + if (process.config.variables.v8_enable_inspector === 0) { + exports.skip('V8 inspector is disabled'); + process.exit(0); + } +}; + +var arrayBufferViews = [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, DataView]; + +exports.getArrayBufferViews = function getArrayBufferViews(buf) { + var buffer = buf.buffer, + byteOffset = buf.byteOffset, + byteLength = buf.byteLength; + + + var out = []; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = arrayBufferViews[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var type = _step.value; + var _type$BYTES_PER_ELEME = type.BYTES_PER_ELEMENT, + BYTES_PER_ELEMENT = _type$BYTES_PER_ELEME === undefined ? 1 : _type$BYTES_PER_ELEME; + + if (byteLength % BYTES_PER_ELEMENT === 0) { + out.push(new type(buffer, byteOffset, byteLength / BYTES_PER_ELEMENT)); + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return out; +}; + +// Crash the process on unhandled rejections. +exports.crashOnUnhandledRejection = function () { + process.on('unhandledRejection', function (err) { + return process.nextTick(function () { + throw err; + }); + }); +}; + +exports.getTTYfd = function getTTYfd() { + var tty = require('tty'); + var tty_fd = 0; + if (!tty.isatty(tty_fd)) tty_fd++;else if (!tty.isatty(tty_fd)) tty_fd++;else if (!tty.isatty(tty_fd)) tty_fd++;else try { + tty_fd = require('fs').openSync('/dev/tty'); + } catch (e) { + // There aren't any tty fd's available to use. + return -1; + } + return tty_fd; +}; + function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); diff --git a/test/parallel/test-stream-big-packet.js b/test/parallel/test-stream-big-packet.js index ca02ee3340..cebf5fece2 100644 --- a/test/parallel/test-stream-big-packet.js +++ b/test/parallel/test-stream-big-packet.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -24,7 +45,7 @@ util.inherits(TestStream, stream.Transform); TestStream.prototype._transform = function (chunk, encoding, done) { if (!passed) { // Char 'a' only exists in the last write - passed = indexOf(chunk.toString(), 'a') >= 0; + passed = chunk.toString().includes('a'); } done(); }; diff --git a/test/parallel/test-stream-big-push.js b/test/parallel/test-stream-big-push.js index 3403688639..68835fe5fb 100644 --- a/test/parallel/test-stream-big-push.js +++ b/test/parallel/test-stream-big-push.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -30,7 +51,7 @@ function _read() { r._read = common.mustCall(_read, 3); -r.on('end', common.mustCall(function () {})); +r.on('end', common.mustCall()); // push some data in to start. // we've never gotten any read event at this point. diff --git a/test/parallel/test-stream-decoder-objectmode.js b/test/parallel/test-stream-decoder-objectmode.js index 34ce104445..52f9cde046 100644 --- a/test/parallel/test-stream-decoder-objectmode.js +++ b/test/parallel/test-stream-decoder-objectmode.js @@ -1,12 +1,13 @@ /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -require('../common'); + +var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); var readable = new stream.Readable({ - read: function () {}, + read: common.noop, encoding: 'utf16le', objectMode: true }); diff --git a/test/parallel/test-stream-duplex-destroy.js b/test/parallel/test-stream-duplex-destroy.js new file mode 100644 index 0000000000..2ac6fcba27 --- /dev/null +++ b/test/parallel/test-stream-duplex-destroy.js @@ -0,0 +1,223 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ + +var common = require('../common'); + +var _require = require('../../'), + Duplex = _require.Duplex; + +var assert = require('assert/'); + +var _require2 = require('util'), + inherits = _require2.inherits; + +{ + var duplex = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {} + }); + + duplex.resume(); + + duplex.on('end', common.mustCall()); + duplex.on('finish', common.mustCall()); + + duplex.destroy(); + assert.strictEqual(duplex.destroyed, true); +} + +{ + var _duplex = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {} + }); + _duplex.resume(); + + var expected = new Error('kaboom'); + + _duplex.on('end', common.mustCall()); + _duplex.on('finish', common.mustCall()); + _duplex.on('error', common.mustCall(function (err) { + assert.strictEqual(err, expected); + })); + + _duplex.destroy(expected); + assert.strictEqual(_duplex.destroyed, true); +} + +{ + var _duplex2 = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {} + }); + + _duplex2._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, _expected); + cb(err); + }); + + var _expected = new Error('kaboom'); + + _duplex2.on('finish', common.mustNotCall('no finish event')); + _duplex2.on('error', common.mustCall(function (err) { + assert.strictEqual(err, _expected); + })); + + _duplex2.destroy(_expected); + assert.strictEqual(_duplex2.destroyed, true); +} + +{ + var _expected2 = new Error('kaboom'); + var _duplex3 = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {}, + + destroy: common.mustCall(function (err, cb) { + assert.strictEqual(err, _expected2); + cb(); + }) + }); + _duplex3.resume(); + + _duplex3.on('end', common.mustNotCall('no end event')); + _duplex3.on('finish', common.mustNotCall('no finish event')); + + // error is swallowed by the custom _destroy + _duplex3.on('error', common.mustNotCall('no error event')); + + _duplex3.destroy(_expected2); + assert.strictEqual(_duplex3.destroyed, true); +} + +{ + var _duplex4 = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {} + }); + + _duplex4._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, null); + cb(); + }); + + _duplex4.destroy(); + assert.strictEqual(_duplex4.destroyed, true); +} + +{ + var _duplex5 = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {} + }); + _duplex5.resume(); + + _duplex5._destroy = common.mustCall(function (err, cb) { + var _this = this; + + assert.strictEqual(err, null); + process.nextTick(function () { + _this.push(null); + _this.end(); + cb(); + }); + }); + + var fail = common.mustNotCall('no finish or end event'); + + _duplex5.on('finish', fail); + _duplex5.on('end', fail); + + _duplex5.destroy(); + + _duplex5.removeListener('end', fail); + _duplex5.removeListener('finish', fail); + _duplex5.on('end', common.mustCall()); + _duplex5.on('finish', common.mustCall()); + assert.strictEqual(_duplex5.destroyed, true); +} + +{ + var _duplex6 = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {} + }); + + var _expected3 = new Error('kaboom'); + + _duplex6._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, null); + cb(_expected3); + }); + + _duplex6.on('finish', common.mustNotCall('no finish event')); + _duplex6.on('end', common.mustNotCall('no end event')); + _duplex6.on('error', common.mustCall(function (err) { + assert.strictEqual(err, _expected3); + })); + + _duplex6.destroy(); + assert.strictEqual(_duplex6.destroyed, true); +} + +{ + var _duplex7 = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {}, + + allowHalfOpen: true + }); + _duplex7.resume(); + + _duplex7.on('finish', common.mustCall()); + _duplex7.on('end', common.mustCall()); + + _duplex7.destroy(); + assert.strictEqual(_duplex7.destroyed, true); +} + +{ + var _duplex8 = new Duplex({ + write: function (chunk, enc, cb) { + cb(); + }, + read: function () {} + }); + + _duplex8.destroyed = true; + assert.strictEqual(_duplex8.destroyed, true); + + // the internal destroy() mechanism should not be triggered + _duplex8.on('finish', common.mustNotCall()); + _duplex8.on('end', common.mustNotCall()); + _duplex8.destroy(); +} + +{ + function MyDuplex() { + assert.strictEqual(this.destroyed, false); + this.destroyed = false; + Duplex.call(this); + } + + inherits(MyDuplex, Duplex); + + new MyDuplex(); +} \ No newline at end of file diff --git a/test/parallel/test-stream-duplex.js b/test/parallel/test-stream-duplex.js index 7fa28eff69..8491111986 100644 --- a/test/parallel/test-stream-duplex.js +++ b/test/parallel/test-stream-duplex.js @@ -1,7 +1,28 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -require('../common'); + +var common = require('../common'); var assert = require('assert/'); var Duplex = require('../../').Duplex; @@ -19,7 +40,7 @@ stream._write = function (obj, _, cb) { cb(); }; -stream._read = function () {}; +stream._read = common.noop; stream.on('data', function (obj) { read = obj; diff --git a/test/parallel/test-stream-end-paused.js b/test/parallel/test-stream-end-paused.js index ad575e5d53..eeea575920 100644 --- a/test/parallel/test-stream-end-paused.js +++ b/test/parallel/test-stream-end-paused.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -21,7 +42,7 @@ stream.on('data', function () { stream.pause(); setTimeout(common.mustCall(function () { - stream.on('end', common.mustCall(function () {})); + stream.on('end', common.mustCall()); stream.resume(); }), 1); diff --git a/test/parallel/test-stream-events-prepend.js b/test/parallel/test-stream-events-prepend.js index c5041ed0e7..097ae2ad69 100644 --- a/test/parallel/test-stream-events-prepend.js +++ b/test/parallel/test-stream-events-prepend.js @@ -25,7 +25,7 @@ Readable.prototype._read = function () { }; var w = new Writable(); -w.on('pipe', common.mustCall(function () {})); +w.on('pipe', common.mustCall()); var r = new Readable(); r.pipe(w); \ No newline at end of file diff --git a/test/parallel/test-stream-ispaused.js b/test/parallel/test-stream-ispaused.js index ea7eaf1a9b..6abb10fc13 100644 --- a/test/parallel/test-stream-ispaused.js +++ b/test/parallel/test-stream-ispaused.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-pipe-after-end.js b/test/parallel/test-stream-pipe-after-end.js index 3ab6a66a5e..6bbd0bd823 100644 --- a/test/parallel/test-stream-pipe-after-end.js +++ b/test/parallel/test-stream-pipe-after-end.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -41,11 +62,11 @@ var piper = new TestReadable(); piper.read(); setTimeout(common.mustCall(function () { - ender.on('end', common.mustCall(function () {})); + ender.on('end', common.mustCall()); var c = ender.read(); assert.strictEqual(c, null); var w = new TestWritable(); - w.on('finish', common.mustCall(function () {})); + w.on('finish', common.mustCall()); piper.pipe(w); }), 1); \ No newline at end of file diff --git a/test/parallel/test-stream-pipe-await-drain.js b/test/parallel/test-stream-pipe-await-drain.js index e1b3daeaa6..5becd4c1c8 100644 --- a/test/parallel/test-stream-pipe-await-drain.js +++ b/test/parallel/test-stream-pipe-await-drain.js @@ -17,7 +17,7 @@ var writer3 = new stream.Writable(); // See: https://github.com/nodejs/node/issues/5820 var buffer = bufferShim.allocUnsafe(560000); -reader._read = function (n) {}; +reader._read = common.noop; writer1._write = common.mustCall(function (chunk, encoding, cb) { this.emit('chunk-received'); diff --git a/test/parallel/test-stream-pipe-cleanup-pause.js b/test/parallel/test-stream-pipe-cleanup-pause.js index c64b0853eb..b5cc25bbbc 100644 --- a/test/parallel/test-stream-pipe-cleanup-pause.js +++ b/test/parallel/test-stream-pipe-cleanup-pause.js @@ -13,7 +13,7 @@ var writer2 = new stream.Writable(); // See: https://github.com/nodejs/node/issues/2323 var buffer = bufferShim.allocUnsafe(560000); -reader._read = function (n) {}; +reader._read = common.noop; writer1._write = common.mustCall(function (chunk, encoding, cb) { this.emit('chunk-received'); diff --git a/test/parallel/test-stream-pipe-cleanup.js b/test/parallel/test-stream-pipe-cleanup.js index a40b8274ef..e7151796f4 100644 --- a/test/parallel/test-stream-pipe-cleanup.js +++ b/test/parallel/test-stream-pipe-cleanup.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-pipe-error-handling.js b/test/parallel/test-stream-pipe-error-handling.js index 936e2dcc69..80a4ff2aae 100644 --- a/test/parallel/test-stream-pipe-error-handling.js +++ b/test/parallel/test-stream-pipe-error-handling.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -81,11 +102,11 @@ var Stream = require('stream').Stream; }), 1); }); - _w.on('error', common.mustCall(function () {})); - _w._write = function () {}; + _w.on('error', common.mustCall()); + _w._write = common.noop; _r.pipe(_w); // Removing some OTHER random listener should not do anything - _w.removeListener('error', function () {}); + _w.removeListener('error', common.noop); _removed = true; } \ No newline at end of file diff --git a/test/parallel/test-stream-pipe-event.js b/test/parallel/test-stream-pipe-event.js index 38967b701d..ebe373e7d6 100644 --- a/test/parallel/test-stream-pipe-event.js +++ b/test/parallel/test-stream-pipe-event.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-pipe-multiple-pipes.js b/test/parallel/test-stream-pipe-multiple-pipes.js index db530120e2..d0bb949165 100644 --- a/test/parallel/test-stream-pipe-multiple-pipes.js +++ b/test/parallel/test-stream-pipe-multiple-pipes.js @@ -6,7 +6,7 @@ var stream = require('../../'); var assert = require('assert/'); var readable = new stream.Readable({ - read: function () {} + read: common.noop }); var writables = []; @@ -20,7 +20,7 @@ var _loop = function (i) { }); target.output = []; - target.on('pipe', common.mustCall(function () {})); + target.on('pipe', common.mustCall()); readable.pipe(target); writables.push(target); @@ -47,7 +47,7 @@ process.nextTick(common.mustCall(function () { assert.deepStrictEqual(_target.output, [input]); - _target.on('unpipe', common.mustCall(function () {})); + _target.on('unpipe', common.mustCall()); readable.unpipe(_target); } } catch (err) { diff --git a/test/parallel/test-stream-pipe-same-destination-twice.js b/test/parallel/test-stream-pipe-same-destination-twice.js new file mode 100644 index 0000000000..f3c0c895b3 --- /dev/null +++ b/test/parallel/test-stream-pipe-same-destination-twice.js @@ -0,0 +1,83 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ +var common = require('../common'); + +// Regression test for https://github.com/nodejs/node/issues/12718. +// Tests that piping a source stream twice to the same destination stream +// works, and that a subsequent unpipe() call only removes the pipe *once*. +var assert = require('assert/'); + +var _require = require('../../'), + PassThrough = _require.PassThrough, + Writable = _require.Writable; + +{ + var passThrough = new PassThrough(); + var dest = new Writable({ + write: common.mustCall(function (chunk, encoding, cb) { + assert.strictEqual('' + chunk, 'foobar'); + cb(); + }) + }); + + passThrough.pipe(dest); + passThrough.pipe(dest); + + assert.strictEqual(passThrough._events.data.length, 2); + assert.strictEqual(passThrough._readableState.pipesCount, 2); + assert.strictEqual(passThrough._readableState.pipes[0], dest); + assert.strictEqual(passThrough._readableState.pipes[1], dest); + + passThrough.unpipe(dest); + + assert.strictEqual(passThrough._events.data.length, 1); + assert.strictEqual(passThrough._readableState.pipesCount, 1); + assert.strictEqual(passThrough._readableState.pipes, dest); + + passThrough.write('foobar'); + passThrough.pipe(dest); +} + +{ + var _passThrough = new PassThrough(); + var _dest = new Writable({ + write: common.mustCall(function (chunk, encoding, cb) { + assert.strictEqual('' + chunk, 'foobar'); + cb(); + }, 2) + }); + + _passThrough.pipe(_dest); + _passThrough.pipe(_dest); + + assert.strictEqual(_passThrough._events.data.length, 2); + assert.strictEqual(_passThrough._readableState.pipesCount, 2); + assert.strictEqual(_passThrough._readableState.pipes[0], _dest); + assert.strictEqual(_passThrough._readableState.pipes[1], _dest); + + _passThrough.write('foobar'); +} + +{ + var _passThrough2 = new PassThrough(); + var _dest2 = new Writable({ + write: common.mustNotCall() + }); + + _passThrough2.pipe(_dest2); + _passThrough2.pipe(_dest2); + + assert.strictEqual(_passThrough2._events.data.length, 2); + assert.strictEqual(_passThrough2._readableState.pipesCount, 2); + assert.strictEqual(_passThrough2._readableState.pipes[0], _dest2); + assert.strictEqual(_passThrough2._readableState.pipes[1], _dest2); + + _passThrough2.unpipe(_dest2); + _passThrough2.unpipe(_dest2); + + assert.strictEqual(_passThrough2._events.data, undefined); + assert.strictEqual(_passThrough2._readableState.pipesCount, 0); + + _passThrough2.write('foobar'); +} \ No newline at end of file diff --git a/test/parallel/test-stream-pipe-unpipe-streams.js b/test/parallel/test-stream-pipe-unpipe-streams.js index 18216aec0b..0e9ff3367e 100644 --- a/test/parallel/test-stream-pipe-unpipe-streams.js +++ b/test/parallel/test-stream-pipe-unpipe-streams.js @@ -8,15 +8,15 @@ var _require = require('../../'), Readable = _require.Readable, Writable = _require.Writable; -var source = Readable({ read: function () {} }); -var dest1 = Writable({ write: function () {} }); -var dest2 = Writable({ write: function () {} }); +var source = Readable({ read: common.noop }); +var dest1 = Writable({ write: common.noop }); +var dest2 = Writable({ write: common.noop }); source.pipe(dest1); source.pipe(dest2); -dest1.on('unpipe', common.mustCall(function () {})); -dest2.on('unpipe', common.mustCall(function () {})); +dest1.on('unpipe', common.mustCall()); +dest2.on('unpipe', common.mustCall()); assert.strictEqual(source._readableState.pipes[0], dest1); assert.strictEqual(source._readableState.pipes[1], dest2); diff --git a/test/parallel/test-stream-pipe-without-listenerCount.js b/test/parallel/test-stream-pipe-without-listenerCount.js index 62fcf8a152..3bb5a9e4ef 100644 --- a/test/parallel/test-stream-pipe-without-listenerCount.js +++ b/test/parallel/test-stream-pipe-without-listenerCount.js @@ -14,8 +14,6 @@ w.on('pipe', function () { r.emit('error', new Error('Readable Error')); w.emit('error', new Error('Writable Error')); }); -r.on('error', common.mustCall(noop)); -w.on('error', common.mustCall(noop)); -r.pipe(w); - -function noop() {} \ No newline at end of file +r.on('error', common.mustCall()); +w.on('error', common.mustCall()); +r.pipe(w); \ No newline at end of file diff --git a/test/parallel/test-stream-push-order.js b/test/parallel/test-stream-push-order.js index ba3d312634..166d51d6b9 100644 --- a/test/parallel/test-stream-push-order.js +++ b/test/parallel/test-stream-push-order.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-push-strings.js b/test/parallel/test-stream-push-strings.js index 1c4731e976..33b5630813 100644 --- a/test/parallel/test-stream-push-strings.js +++ b/test/parallel/test-stream-push-strings.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -37,7 +58,7 @@ var results = []; ms.on('readable', function () { var chunk = void 0; while (null !== (chunk = ms.read())) { - results.push(chunk + ''); + results.push(String(chunk)); } }); diff --git a/test/parallel/test-stream-readable-constructor-set-methods.js b/test/parallel/test-stream-readable-constructor-set-methods.js index 42d0b4c706..7974f9c290 100644 --- a/test/parallel/test-stream-readable-constructor-set-methods.js +++ b/test/parallel/test-stream-readable-constructor-set-methods.js @@ -1,21 +1,13 @@ /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -require('../common'); -var assert = require('assert/'); +var common = require('../common'); var Readable = require('../../').Readable; -var _readCalled = false; -function _read(n) { - _readCalled = true; +var _read = common.mustCall(function _read(n) { this.push(null); -} +}); var r = new Readable({ read: _read }); -r.resume(); - -process.on('exit', function () { - assert.strictEqual(r._read, _read); - assert(_readCalled); -}); \ No newline at end of file +r.resume(); \ No newline at end of file diff --git a/test/parallel/test-stream-readable-destroy.js b/test/parallel/test-stream-readable-destroy.js new file mode 100644 index 0000000000..3df1e2a180 --- /dev/null +++ b/test/parallel/test-stream-readable-destroy.js @@ -0,0 +1,186 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ + +var common = require('../common'); + +var _require = require('../../'), + Readable = _require.Readable; + +var assert = require('assert/'); + +var _require2 = require('util'), + inherits = _require2.inherits; + +{ + var read = new Readable({ + read: function () {} + }); + read.resume(); + + read.on('end', common.mustCall()); + + read.destroy(); + assert.strictEqual(read.destroyed, true); +} + +{ + var _read = new Readable({ + read: function () {} + }); + _read.resume(); + + var expected = new Error('kaboom'); + + _read.on('end', common.mustCall()); + _read.on('error', common.mustCall(function (err) { + assert.strictEqual(err, expected); + })); + + _read.destroy(expected); + assert.strictEqual(_read.destroyed, true); +} + +{ + var _read2 = new Readable({ + read: function () {} + }); + + _read2._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, _expected); + cb(err); + }); + + var _expected = new Error('kaboom'); + + _read2.on('end', common.mustNotCall('no end event')); + _read2.on('error', common.mustCall(function (err) { + assert.strictEqual(err, _expected); + })); + + _read2.destroy(_expected); + assert.strictEqual(_read2.destroyed, true); +} + +{ + var _read3 = new Readable({ + read: function () {}, + + destroy: common.mustCall(function (err, cb) { + assert.strictEqual(err, _expected2); + cb(); + }) + }); + + var _expected2 = new Error('kaboom'); + + _read3.on('end', common.mustNotCall('no end event')); + + // error is swallowed by the custom _destroy + _read3.on('error', common.mustNotCall('no error event')); + + _read3.destroy(_expected2); + assert.strictEqual(_read3.destroyed, true); +} + +{ + var _read4 = new Readable({ + read: function () {} + }); + + _read4._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, null); + cb(); + }); + + _read4.destroy(); + assert.strictEqual(_read4.destroyed, true); +} + +{ + var _read5 = new Readable({ + read: function () {} + }); + _read5.resume(); + + _read5._destroy = common.mustCall(function (err, cb) { + var _this = this; + + assert.strictEqual(err, null); + process.nextTick(function () { + _this.push(null); + cb(); + }); + }); + + var fail = common.mustNotCall('no end event'); + + _read5.on('end', fail); + + _read5.destroy(); + + _read5.removeListener('end', fail); + _read5.on('end', common.mustCall()); + assert.strictEqual(_read5.destroyed, true); +} + +{ + var _read6 = new Readable({ + read: function () {} + }); + + var _expected3 = new Error('kaboom'); + + _read6._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, null); + cb(_expected3); + }); + + _read6.on('end', common.mustNotCall('no end event')); + _read6.on('error', common.mustCall(function (err) { + assert.strictEqual(err, _expected3); + })); + + _read6.destroy(); + assert.strictEqual(_read6.destroyed, true); +} + +{ + var _read7 = new Readable({ + read: function () {} + }); + _read7.resume(); + + _read7.destroyed = true; + assert.strictEqual(_read7.destroyed, true); + + // the internal destroy() mechanism should not be triggered + _read7.on('end', common.mustNotCall()); + _read7.destroy(); +} + +{ + function MyReadable() { + assert.strictEqual(this.destroyed, false); + this.destroyed = false; + Readable.call(this); + } + + inherits(MyReadable, Readable); + + new MyReadable(); +} + +{ + // destroy and destroy callback + var _read8 = new Readable({ + read: function () {} + }); + _read8.resume(); + + var _expected4 = new Error('kaboom'); + + _read8.destroy(_expected4, common.mustCall(function (err) { + assert.strictEqual(_expected4, err); + })); +} \ No newline at end of file diff --git a/test/parallel/test-stream-readable-emittedReadable.js b/test/parallel/test-stream-readable-emittedReadable.js index 13695547f7..f25a41b00b 100644 --- a/test/parallel/test-stream-readable-emittedReadable.js +++ b/test/parallel/test-stream-readable-emittedReadable.js @@ -6,7 +6,7 @@ var assert = require('assert/'); var Readable = require('../../').Readable; var readable = new Readable({ - read: function () {} + read: common.noop }); // Initialized to false. @@ -39,7 +39,7 @@ process.nextTick(common.mustCall(function () { })); var noRead = new Readable({ - read: function () {} + read: common.noop }); noRead.on('readable', common.mustCall(function () { @@ -54,7 +54,7 @@ noRead.push('foo'); noRead.push(null); var flowing = new Readable({ - read: function () {} + read: common.noop }); flowing.on('data', common.mustCall(function () { diff --git a/test/parallel/test-stream-readable-event.js b/test/parallel/test-stream-readable-event.js index cf8eb5c8a6..587f1acbef 100644 --- a/test/parallel/test-stream-readable-event.js +++ b/test/parallel/test-stream-readable-event.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -21,7 +42,7 @@ var Readable = require('../../').Readable; setTimeout(function () { // we're testing what we think we are assert(!r._readableState.reading); - r.on('readable', common.mustCall(function () {})); + r.on('readable', common.mustCall()); }, 1); } @@ -33,7 +54,7 @@ var Readable = require('../../').Readable; highWaterMark: 3 }); - _r._read = common.mustCall(function (n) {}); + _r._read = common.mustCall(); // This triggers a 'readable' event, which is lost. _r.push(bufferShim.from('bl')); @@ -41,7 +62,7 @@ var Readable = require('../../').Readable; setTimeout(function () { // assert we're testing what we think we are assert(_r._readableState.reading); - _r.on('readable', common.mustCall(function () {})); + _r.on('readable', common.mustCall()); }, 1); } @@ -61,6 +82,6 @@ var Readable = require('../../').Readable; setTimeout(function () { // assert we're testing what we think we are assert(!_r2._readableState.reading); - _r2.on('readable', common.mustCall(function () {})); + _r2.on('readable', common.mustCall()); }, 1); } \ No newline at end of file diff --git a/test/parallel/test-stream-readable-flow-recursion.js b/test/parallel/test-stream-readable-flow-recursion.js index 80518f0dfc..b14fa65a50 100644 --- a/test/parallel/test-stream-readable-flow-recursion.js +++ b/test/parallel/test-stream-readable-flow-recursion.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-readable-invalid-chunk.js b/test/parallel/test-stream-readable-invalid-chunk.js index e10ef9dcfc..c116acd392 100644 --- a/test/parallel/test-stream-readable-invalid-chunk.js +++ b/test/parallel/test-stream-readable-invalid-chunk.js @@ -1,12 +1,13 @@ /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -require('../common'); + +var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); var readable = new stream.Readable({ - read: function () {} + read: common.noop }); assert.throws(function () { diff --git a/test/parallel/test-stream-readable-needReadable.js b/test/parallel/test-stream-readable-needReadable.js index b7e1d5ec7f..d837c9445d 100644 --- a/test/parallel/test-stream-readable-needReadable.js +++ b/test/parallel/test-stream-readable-needReadable.js @@ -6,7 +6,7 @@ var assert = require('assert/'); var Readable = require('../../').Readable; var readable = new Readable({ - read: function () {} + read: common.noop }); // Initialized to false. @@ -30,7 +30,7 @@ readable.on('end', common.mustCall(function () { })); var asyncReadable = new Readable({ - read: function () {} + read: common.noop }); asyncReadable.on('readable', common.mustCall(function () { @@ -53,7 +53,7 @@ process.nextTick(common.mustCall(function () { })); var flowing = new Readable({ - read: function () {} + read: common.noop }); // Notice this must be above the on('data') call. @@ -71,7 +71,7 @@ flowing.on('data', common.mustCall(function (data) { }, 3)); var slowProducer = new Readable({ - read: function () {} + read: common.noop }); slowProducer.on('readable', common.mustCall(function () { diff --git a/test/parallel/test-stream-readableListening-state.js b/test/parallel/test-stream-readableListening-state.js index 08e552145f..ae42e8711e 100644 --- a/test/parallel/test-stream-readableListening-state.js +++ b/test/parallel/test-stream-readableListening-state.js @@ -7,7 +7,7 @@ var assert = require('assert/'); var stream = require('../../'); var r = new stream.Readable({ - read: function () {} + read: common.noop }); // readableListening state should start in `false`. @@ -21,7 +21,7 @@ r.on('readable', common.mustCall(function () { r.push(bufferShim.from('Testing readableListening state')); var r2 = new stream.Readable({ - read: function () {} + read: common.noop }); // readableListening state should start in `false`. diff --git a/test/parallel/test-stream-transform-callback-twice.js b/test/parallel/test-stream-transform-callback-twice.js new file mode 100644 index 0000000000..cd8cdc668c --- /dev/null +++ b/test/parallel/test-stream-transform-callback-twice.js @@ -0,0 +1,20 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ +var common = require('../common'); +var assert = require('assert/'); + +var _require = require('../../'), + Transform = _require.Transform; + +var stream = new Transform({ + transform: function (chunk, enc, cb) { + cb();cb(); + } +}); + +stream.on('error', common.mustCall(function (err) { + assert.strictEqual(err.toString(), 'Error: write callback called multiple times'); +})); + +stream.write('foo'); \ No newline at end of file diff --git a/test/parallel/test-stream-transform-constructor-set-methods.js b/test/parallel/test-stream-transform-constructor-set-methods.js index 7fccacd178..ed4858b3cd 100644 --- a/test/parallel/test-stream-transform-constructor-set-methods.js +++ b/test/parallel/test-stream-transform-constructor-set-methods.js @@ -1,26 +1,27 @@ /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -require('../common'); +var common = require('../common'); var assert = require('assert/'); var Transform = require('../../').Transform; -var _transformCalled = false; -function _transform(d, e, n) { - _transformCalled = true; +var _transform = common.mustCall(function _transform(d, e, n) { n(); -} +}); -var _flushCalled = false; -function _flush(n) { - _flushCalled = true; +var _final = common.mustCall(function _final(n) { n(); -} +}); + +var _flush = common.mustCall(function _flush(n) { + n(); +}); var t = new Transform({ transform: _transform, - flush: _flush + flush: _flush, + final: _final }); var t2 = new Transform({}); @@ -35,6 +36,5 @@ assert.throws(function () { process.on('exit', function () { assert.strictEqual(t._transform, _transform); assert.strictEqual(t._flush, _flush); - assert.strictEqual(_transformCalled, true); - assert.strictEqual(_flushCalled, true); + assert.strictEqual(t._final, _final); }); \ No newline at end of file diff --git a/test/parallel/test-stream-transform-destroy.js b/test/parallel/test-stream-transform-destroy.js new file mode 100644 index 0000000000..1d30d6f512 --- /dev/null +++ b/test/parallel/test-stream-transform-destroy.js @@ -0,0 +1,151 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ + +var common = require('../common'); + +var _require = require('../../'), + Transform = _require.Transform; + +var assert = require('assert/'); + +{ + var transform = new Transform({ + transform: function (chunk, enc, cb) {} + }); + + transform.resume(); + + transform.on('end', common.mustCall()); + transform.on('close', common.mustCall()); + transform.on('finish', common.mustCall()); + + transform.destroy(); +} + +{ + var _transform = new Transform({ + transform: function (chunk, enc, cb) {} + }); + _transform.resume(); + + var expected = new Error('kaboom'); + + _transform.on('end', common.mustCall()); + _transform.on('finish', common.mustCall()); + _transform.on('close', common.mustCall()); + _transform.on('error', common.mustCall(function (err) { + assert.strictEqual(err, expected); + })); + + _transform.destroy(expected); +} + +{ + var _transform2 = new Transform({ + transform: function (chunk, enc, cb) {} + }); + + _transform2._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, _expected); + cb(err); + }, 1); + + var _expected = new Error('kaboom'); + + _transform2.on('finish', common.mustNotCall('no finish event')); + _transform2.on('close', common.mustNotCall('no close event')); + _transform2.on('error', common.mustCall(function (err) { + assert.strictEqual(err, _expected); + })); + + _transform2.destroy(_expected); +} + +{ + var _expected2 = new Error('kaboom'); + var _transform3 = new Transform({ + transform: function (chunk, enc, cb) {}, + + destroy: common.mustCall(function (err, cb) { + assert.strictEqual(err, _expected2); + cb(); + }, 1) + }); + _transform3.resume(); + + _transform3.on('end', common.mustNotCall('no end event')); + _transform3.on('close', common.mustNotCall('no close event')); + _transform3.on('finish', common.mustNotCall('no finish event')); + + // error is swallowed by the custom _destroy + _transform3.on('error', common.mustNotCall('no error event')); + + _transform3.destroy(_expected2); +} + +{ + var _transform4 = new Transform({ + transform: function (chunk, enc, cb) {} + }); + + _transform4._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, null); + cb(); + }, 1); + + _transform4.destroy(); +} + +{ + var _transform5 = new Transform({ + transform: function (chunk, enc, cb) {} + }); + _transform5.resume(); + + _transform5._destroy = common.mustCall(function (err, cb) { + var _this = this; + + assert.strictEqual(err, null); + process.nextTick(function () { + _this.push(null); + _this.end(); + cb(); + }); + }, 1); + + var fail = common.mustNotCall('no event'); + + _transform5.on('finish', fail); + _transform5.on('end', fail); + _transform5.on('close', fail); + + _transform5.destroy(); + + _transform5.removeListener('end', fail); + _transform5.removeListener('finish', fail); + _transform5.on('end', common.mustCall()); + _transform5.on('finish', common.mustCall()); +} + +{ + var _transform6 = new Transform({ + transform: function (chunk, enc, cb) {} + }); + + var _expected3 = new Error('kaboom'); + + _transform6._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, null); + cb(_expected3); + }, 1); + + _transform6.on('close', common.mustNotCall('no close event')); + _transform6.on('finish', common.mustNotCall('no finish event')); + _transform6.on('end', common.mustNotCall('no end event')); + _transform6.on('error', common.mustCall(function (err) { + assert.strictEqual(err, _expected3); + })); + + _transform6.destroy(); +} \ No newline at end of file diff --git a/test/parallel/test-stream-transform-final-sync.js b/test/parallel/test-stream-transform-final-sync.js new file mode 100644 index 0000000000..8667612bca --- /dev/null +++ b/test/parallel/test-stream-transform-final-sync.js @@ -0,0 +1,102 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ +var common = require('../common'); +var assert = require('assert/'); + +var stream = require('../../'); +var state = 0; + +/* +What you do +var stream = new tream.Transform({ + transform: function transformCallback(chunk, _, next) { + // part 1 + this.push(chunk); + //part 2 + next(); + }, + final: function endCallback(done) { + // part 1 + process.nextTick(function () { + // part 2 + done(); + }); + }, + flush: function flushCallback(done) { + // part 1 + process.nextTick(function () { + // part 2 + done(); + }); + } +}); +t.on('data', dataListener); +t.on('end', endListener); +t.on('finish', finishListener); +t.write(1); +t.write(4); +t.end(7, endMethodCallback); + +The order things are called + +1. transformCallback part 1 +2. dataListener +3. transformCallback part 2 +4. transformCallback part 1 +5. dataListener +6. transformCallback part 2 +7. transformCallback part 1 +8. dataListener +9. transformCallback part 2 +10. finalCallback part 1 +11. finalCallback part 2 +12. flushCallback part 1 +13. finishListener +14. endMethodCallback +15. flushCallback part 2 +16. endListener +*/ + +var t = new stream.Transform({ + objectMode: true, + transform: common.mustCall(function (chunk, _, next) { + assert.strictEqual(++state, chunk, 'transformCallback part 1'); + this.push(state); + assert.strictEqual(++state, chunk + 2, 'transformCallback part 2'); + process.nextTick(next); + }, 3), + final: common.mustCall(function (done) { + state++; + assert.strictEqual(state, 10, 'finalCallback part 1'); + state++; + assert.strictEqual(state, 11, 'finalCallback part 2'); + done(); + }, 1), + flush: common.mustCall(function (done) { + state++; + assert.strictEqual(state, 12, 'flushCallback part 1'); + process.nextTick(function () { + state++; + assert.strictEqual(state, 15, 'flushCallback part 2'); + done(); + }); + }, 1) +}); +t.on('finish', common.mustCall(function () { + state++; + assert.strictEqual(state, 13, 'finishListener'); +}, 1)); +t.on('end', common.mustCall(function () { + state++; + assert.strictEqual(state, 16, 'end event'); +}, 1)); +t.on('data', common.mustCall(function (d) { + assert.strictEqual(++state, d + 1, 'dataListener'); +}, 3)); +t.write(1); +t.write(4); +t.end(7, common.mustCall(function () { + state++; + assert.strictEqual(state, 14, 'endMethodCallback'); +}, 1)); \ No newline at end of file diff --git a/test/parallel/test-stream-transform-final.js b/test/parallel/test-stream-transform-final.js new file mode 100644 index 0000000000..50e0ce8a1d --- /dev/null +++ b/test/parallel/test-stream-transform-final.js @@ -0,0 +1,104 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ +var common = require('../common'); +var assert = require('assert/'); + +var stream = require('../../'); +var state = 0; + +/* +What you do +var stream = new tream.Transform({ + transform: function transformCallback(chunk, _, next) { + // part 1 + this.push(chunk); + //part 2 + next(); + }, + final: function endCallback(done) { + // part 1 + process.nextTick(function () { + // part 2 + done(); + }); + }, + flush: function flushCallback(done) { + // part 1 + process.nextTick(function () { + // part 2 + done(); + }); + } +}); +t.on('data', dataListener); +t.on('end', endListener); +t.on('finish', finishListener); +t.write(1); +t.write(4); +t.end(7, endMethodCallback); + +The order things are called + +1. transformCallback part 1 +2. dataListener +3. transformCallback part 2 +4. transformCallback part 1 +5. dataListener +6. transformCallback part 2 +7. transformCallback part 1 +8. dataListener +9. transformCallback part 2 +10. finalCallback part 1 +11. finalCallback part 2 +12. flushCallback part 1 +13. finishListener +14. endMethodCallback +15. flushCallback part 2 +16. endListener +*/ + +var t = new stream.Transform({ + objectMode: true, + transform: common.mustCall(function (chunk, _, next) { + assert.strictEqual(++state, chunk, 'transformCallback part 1'); + this.push(state); + assert.strictEqual(++state, chunk + 2, 'transformCallback part 2'); + process.nextTick(next); + }, 3), + final: common.mustCall(function (done) { + state++; + assert.strictEqual(state, 10, 'finalCallback part 1'); + setTimeout(function () { + state++; + assert.strictEqual(state, 11, 'finalCallback part 2'); + done(); + }, 100); + }, 1), + flush: common.mustCall(function (done) { + state++; + assert.strictEqual(state, 12, 'flushCallback part 1'); + process.nextTick(function () { + state++; + assert.strictEqual(state, 15, 'flushCallback part 2'); + done(); + }); + }, 1) +}); +t.on('finish', common.mustCall(function () { + state++; + assert.strictEqual(state, 13, 'finishListener'); +}, 1)); +t.on('end', common.mustCall(function () { + state++; + assert.strictEqual(state, 16, 'end event'); +}, 1)); +t.on('data', common.mustCall(function (d) { + assert.strictEqual(++state, d + 1, 'dataListener'); +}, 3)); +t.write(1); +t.write(4); +t.end(7, common.mustCall(function () { + state++; + assert.strictEqual(state, 14, 'endMethodCallback'); +}, 1)); \ No newline at end of file diff --git a/test/parallel/test-stream-transform-objectmode-falsey-value.js b/test/parallel/test-stream-transform-objectmode-falsey-value.js index 60eae5b4a2..0e95c48d0e 100644 --- a/test/parallel/test-stream-transform-objectmode-falsey-value.js +++ b/test/parallel/test-stream-transform-objectmode-falsey-value.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-transform-split-objectmode.js b/test/parallel/test-stream-transform-split-objectmode.js index 0b7efeb9b3..0bec5bbf1c 100644 --- a/test/parallel/test-stream-transform-split-objectmode.js +++ b/test/parallel/test-stream-transform-split-objectmode.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-uint8array.js b/test/parallel/test-stream-uint8array.js new file mode 100644 index 0000000000..9351aa3794 --- /dev/null +++ b/test/parallel/test-stream-uint8array.js @@ -0,0 +1,108 @@ +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ +var common = require('../common'); +var assert = require('assert/'); +var Buffer = require('buffer').Buffer; + +var _require = require('../../'), + Readable = _require.Readable, + Writable = _require.Writable; + +var ABC = new Uint8Array([0x41, 0x42, 0x43]); +var DEF = new Uint8Array([0x44, 0x45, 0x46]); +var GHI = new Uint8Array([0x47, 0x48, 0x49]); + +{ + // Simple Writable test. + + var n = 0; + var writable = new Writable({ + write: common.mustCall(function (chunk, encoding, cb) { + assert(chunk instanceof Buffer); + if (n++ === 0) { + assert.strictEqual(String(chunk), 'ABC'); + } else { + assert.strictEqual(String(chunk), 'DEF'); + } + + cb(); + }, 2) + }); + + writable.write(ABC); + writable.end(DEF); +} + +{ + // Writable test, pass in Uint8Array in object mode. + + var _writable = new Writable({ + objectMode: true, + write: common.mustCall(function (chunk, encoding, cb) { + assert(!(chunk instanceof Buffer)); + assert(chunk instanceof Uint8Array); + assert.strictEqual(chunk, ABC); + assert.strictEqual(encoding, 'utf8'); + cb(); + }) + }); + + _writable.end(ABC); +} + +{ + // Writable test, multiple writes carried out via writev. + var callback = void 0; + + var _writable2 = new Writable({ + write: common.mustCall(function (chunk, encoding, cb) { + assert(chunk instanceof Buffer); + assert.strictEqual(encoding, 'buffer'); + assert.strictEqual(String(chunk), 'ABC'); + callback = cb; + }), + writev: common.mustCall(function (chunks, cb) { + assert.strictEqual(chunks.length, 2); + assert.strictEqual(chunks[0].encoding, 'buffer'); + assert.strictEqual(chunks[1].encoding, 'buffer'); + assert.strictEqual(chunks[0].chunk + chunks[1].chunk, 'DEFGHI'); + }) + }); + + _writable2.write(ABC); + _writable2.write(DEF); + _writable2.end(GHI); + callback(); +} + +{ + // Simple Readable test. + var readable = new Readable({ + read: function () {} + }); + + readable.push(DEF); + readable.unshift(ABC); + + var buf = readable.read(); + assert(buf instanceof Buffer); + assert.deepStrictEqual([].concat(_toConsumableArray(buf)), [].concat(_toConsumableArray(ABC), _toConsumableArray(DEF))); +} + +{ + // Readable test, setEncoding. + var _readable = new Readable({ + read: function () {} + }); + + _readable.setEncoding('utf8'); + + _readable.push(DEF); + _readable.unshift(ABC); + + var out = _readable.read(); + assert.strictEqual(out, 'ABCDEF'); +} \ No newline at end of file diff --git a/test/parallel/test-stream-unpipe-event.js b/test/parallel/test-stream-unpipe-event.js index 71098af93f..3eb8b28591 100644 --- a/test/parallel/test-stream-unpipe-event.js +++ b/test/parallel/test-stream-unpipe-event.js @@ -74,13 +74,11 @@ var NeverEndReadable = function (_Readable2) { return NeverEndReadable; }(Readable); -function noop() {} - { var dest = new NullWriteable(); var src = new QuickEndReadable(); - dest.on('pipe', common.mustCall(noop)); - dest.on('unpipe', common.mustCall(noop)); + dest.on('pipe', common.mustCall()); + dest.on('unpipe', common.mustCall()); src.pipe(dest); setImmediate(function () { assert.strictEqual(src._readableState.pipesCount, 0); @@ -90,7 +88,7 @@ function noop() {} { var _dest = new NullWriteable(); var _src = new NeverEndReadable(); - _dest.on('pipe', common.mustCall(noop)); + _dest.on('pipe', common.mustCall()); _dest.on('unpipe', common.mustNotCall('unpipe should not have been emitted')); _src.pipe(_dest); setImmediate(function () { @@ -101,8 +99,8 @@ function noop() {} { var _dest2 = new NullWriteable(); var _src2 = new NeverEndReadable(); - _dest2.on('pipe', common.mustCall(noop)); - _dest2.on('unpipe', common.mustCall(noop)); + _dest2.on('pipe', common.mustCall()); + _dest2.on('unpipe', common.mustCall()); _src2.pipe(_dest2); _src2.unpipe(_dest2); setImmediate(function () { @@ -113,8 +111,8 @@ function noop() {} { var _dest3 = new NullWriteable(); var _src3 = new QuickEndReadable(); - _dest3.on('pipe', common.mustCall(noop)); - _dest3.on('unpipe', common.mustCall(noop)); + _dest3.on('pipe', common.mustCall()); + _dest3.on('unpipe', common.mustCall()); _src3.pipe(_dest3, { end: false }); setImmediate(function () { assert.strictEqual(_src3._readableState.pipesCount, 0); @@ -124,7 +122,7 @@ function noop() {} { var _dest4 = new NullWriteable(); var _src4 = new NeverEndReadable(); - _dest4.on('pipe', common.mustCall(noop)); + _dest4.on('pipe', common.mustCall()); _dest4.on('unpipe', common.mustNotCall('unpipe should not have been emitted')); _src4.pipe(_dest4, { end: false }); setImmediate(function () { @@ -135,8 +133,8 @@ function noop() {} { var _dest5 = new NullWriteable(); var _src5 = new NeverEndReadable(); - _dest5.on('pipe', common.mustCall(noop)); - _dest5.on('unpipe', common.mustCall(noop)); + _dest5.on('pipe', common.mustCall()); + _dest5.on('unpipe', common.mustCall()); _src5.pipe(_dest5, { end: false }); _src5.unpipe(_dest5); setImmediate(function () { diff --git a/test/parallel/test-stream-unshift-empty-chunk.js b/test/parallel/test-stream-unshift-empty-chunk.js index 294c519a89..fcc5457ddd 100644 --- a/test/parallel/test-stream-unshift-empty-chunk.js +++ b/test/parallel/test-stream-unshift-empty-chunk.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-unshift-read-race.js b/test/parallel/test-stream-unshift-read-race.js index 3fa5d05c83..89272ccf19 100644 --- a/test/parallel/test-stream-unshift-read-race.js +++ b/test/parallel/test-stream-unshift-read-race.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -51,7 +72,7 @@ r._read = function (n) { function pushError() { assert.throws(function () { r.push(bufferShim.allocUnsafe(1)); - }, /^Error: stream.push\(\) after EOF$/); + }, /^Error: stream\.push\(\) after EOF$/); } var w = stream.Writable(); @@ -64,7 +85,7 @@ w._write = function (chunk, encoding, cb) { r.on('end', common.mustCall(function () { assert.throws(function () { r.unshift(bufferShim.allocUnsafe(1)); - }, /^Error: stream.unshift\(\) after end event$/); + }, /^Error: stream\.unshift\(\) after end event$/); w.end(); })); diff --git a/test/parallel/test-stream-writable-change-default-encoding.js b/test/parallel/test-stream-writable-change-default-encoding.js index 773a344148..9b555ee854 100644 --- a/test/parallel/test-stream-writable-change-default-encoding.js +++ b/test/parallel/test-stream-writable-change-default-encoding.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-writable-decoded-encoding.js b/test/parallel/test-stream-writable-decoded-encoding.js index 72788acd73..85912beaec 100644 --- a/test/parallel/test-stream-writable-decoded-encoding.js +++ b/test/parallel/test-stream-writable-decoded-encoding.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream-writable-destroy.js b/test/parallel/test-stream-writable-destroy.js new file mode 100644 index 0000000000..3aeff6c445 --- /dev/null +++ b/test/parallel/test-stream-writable-destroy.js @@ -0,0 +1,217 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ + +var common = require('../common'); + +var _require = require('../../'), + Writable = _require.Writable; + +var assert = require('assert/'); + +var _require2 = require('util'), + inherits = _require2.inherits; + +{ + var write = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + write.on('finish', common.mustCall()); + + write.destroy(); + assert.strictEqual(write.destroyed, true); +} + +{ + var _write = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + var expected = new Error('kaboom'); + + _write.on('finish', common.mustCall()); + _write.on('error', common.mustCall(function (err) { + assert.strictEqual(err, expected); + })); + + _write.destroy(expected); + assert.strictEqual(_write.destroyed, true); +} + +{ + var _write2 = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + _write2._destroy = function (err, cb) { + assert.strictEqual(err, _expected); + cb(err); + }; + + var _expected = new Error('kaboom'); + + _write2.on('finish', common.mustNotCall('no finish event')); + _write2.on('error', common.mustCall(function (err) { + assert.strictEqual(err, _expected); + })); + + _write2.destroy(_expected); + assert.strictEqual(_write2.destroyed, true); +} + +{ + var _write3 = new Writable({ + write: function (chunk, enc, cb) { + cb(); + }, + + destroy: common.mustCall(function (err, cb) { + assert.strictEqual(err, _expected2); + cb(); + }) + }); + + var _expected2 = new Error('kaboom'); + + _write3.on('finish', common.mustNotCall('no finish event')); + + // error is swallowed by the custom _destroy + _write3.on('error', common.mustNotCall('no error event')); + + _write3.destroy(_expected2); + assert.strictEqual(_write3.destroyed, true); +} + +{ + var _write4 = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + _write4._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, null); + cb(); + }); + + _write4.destroy(); + assert.strictEqual(_write4.destroyed, true); +} + +{ + var _write5 = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + _write5._destroy = common.mustCall(function (err, cb) { + var _this = this; + + assert.strictEqual(err, null); + process.nextTick(function () { + _this.end(); + cb(); + }); + }); + + var fail = common.mustNotCall('no finish event'); + + _write5.on('finish', fail); + + _write5.destroy(); + + _write5.removeListener('finish', fail); + _write5.on('finish', common.mustCall()); + assert.strictEqual(_write5.destroyed, true); +} + +{ + var _write6 = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + var _expected3 = new Error('kaboom'); + + _write6._destroy = common.mustCall(function (err, cb) { + assert.strictEqual(err, null); + cb(_expected3); + }); + + _write6.on('finish', common.mustNotCall('no finish event')); + _write6.on('error', common.mustCall(function (err) { + assert.strictEqual(err, _expected3); + })); + + _write6.destroy(); + assert.strictEqual(_write6.destroyed, true); +} + +{ + // double error case + var _write7 = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + _write7.on('error', common.mustCall()); + + _write7.destroy(new Error('kaboom 1')); + _write7.destroy(new Error('kaboom 2')); + assert.strictEqual(_write7._writableState.errorEmitted, true); + assert.strictEqual(_write7.destroyed, true); +} + +{ + var _write8 = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + _write8.destroyed = true; + assert.strictEqual(_write8.destroyed, true); + + // the internal destroy() mechanism should not be triggered + _write8.on('finish', common.mustNotCall()); + _write8.destroy(); +} + +{ + function MyWritable() { + assert.strictEqual(this.destroyed, false); + this.destroyed = false; + Writable.call(this); + } + + inherits(MyWritable, Writable); + + new MyWritable(); +} + +{ + // destroy and destroy callback + var _write9 = new Writable({ + write: function (chunk, enc, cb) { + cb(); + } + }); + + _write9.destroy(); + + var _expected4 = new Error('kaboom'); + + _write9.destroy(_expected4, common.mustCall(function (err) { + assert.strictEqual(_expected4, err); + })); +} \ No newline at end of file diff --git a/test/parallel/test-stream-writable-writev-finish.js b/test/parallel/test-stream-writable-writev-finish.js new file mode 100644 index 0000000000..9562cb9bf3 --- /dev/null +++ b/test/parallel/test-stream-writable-writev-finish.js @@ -0,0 +1,55 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ + +var common = require('../common'); +var assert = require('assert/'); +var stream = require('../../'); + +// ensure consistency between the finish event when using cork() +// and writev and when not using them + +{ + var writable = new stream.Writable(); + + writable._write = function (chunks, encoding, cb) { + cb(new Error('write test error')); + }; + + writable.on('finish', common.mustCall()); + + writable.on('prefinish', common.mustCall()); + + writable.on('error', common.mustCall(function (er) { + assert.strictEqual(er.message, 'write test error'); + })); + + writable.end('test'); +} + +{ + var _writable = new stream.Writable(); + + _writable._write = function (chunks, encoding, cb) { + cb(new Error('write test error')); + }; + + _writable._writev = function (chunks, cb) { + cb(new Error('writev test error')); + }; + + _writable.on('finish', common.mustCall()); + + _writable.on('prefinish', common.mustCall()); + + _writable.on('error', common.mustCall(function (er) { + assert.strictEqual(er.message, 'writev test error'); + })); + + _writable.cork(); + _writable.write('test'); + + setImmediate(function () { + _writable.end('test'); + }); +} \ No newline at end of file diff --git a/test/parallel/test-stream-write-final.js b/test/parallel/test-stream-write-final.js new file mode 100644 index 0000000000..bd3dafecfb --- /dev/null +++ b/test/parallel/test-stream-write-final.js @@ -0,0 +1,26 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ +var common = require('../common'); +var assert = require('assert/'); + +var stream = require('../../'); +var shutdown = false; + +var w = new stream.Writable({ + final: common.mustCall(function (cb) { + assert.strictEqual(this, w); + setTimeout(function () { + shutdown = true; + cb(); + }, 100); + }), + write: function (chunk, e, cb) { + process.nextTick(cb); + } +}); +w.on('finish', common.mustCall(function () { + assert(shutdown); +})); +w.write(bufferShim.allocUnsafe(1)); +w.end(bufferShim.allocUnsafe(0)); \ No newline at end of file diff --git a/test/parallel/test-stream-writev.js b/test/parallel/test-stream-writev.js index dcd7d95fa0..c69dfad830 100644 --- a/test/parallel/test-stream-writev.js +++ b/test/parallel/test-stream-writev.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-base64-single-char-read-end.js b/test/parallel/test-stream2-base64-single-char-read-end.js index b753f559a4..cde122d3be 100644 --- a/test/parallel/test-stream2-base64-single-char-read-end.js +++ b/test/parallel/test-stream2-base64-single-char-read-end.js @@ -1,7 +1,28 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -var common = require('../common'); +require('../common'); var R = require('../../lib/_stream_readable'); var W = require('../../lib/_stream_writable'); var assert = require('assert/'); @@ -27,12 +48,12 @@ dst._write = function (chunk, enc, cb) { }; src.on('end', function () { - assert.strictEqual(Buffer.concat(accum) + '', 'MQ=='); + assert.strictEqual(String(Buffer.concat(accum)), 'MQ=='); clearTimeout(timeout); }); src.pipe(dst); var timeout = setTimeout(function () { - common.fail('timed out waiting for _write'); + assert.fail('timed out waiting for _write'); }, 100); \ No newline at end of file diff --git a/test/parallel/test-stream2-basic.js b/test/parallel/test-stream2-basic.js new file mode 100644 index 0000000000..bdf130bdbd --- /dev/null +++ b/test/parallel/test-stream2-basic.js @@ -0,0 +1,423 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ + +var common = require('../common'); +var R = require('../../lib/_stream_readable'); +var assert = require('assert/'); + +var util = require('util'); +var EE = require('events').EventEmitter; + +function TestReader(n) { + R.apply(this); + this._buffer = bufferShim.alloc(n || 100, 'x'); + this._pos = 0; + this._bufs = 10; +} + +util.inherits(TestReader, R); + +TestReader.prototype._read = function (n) { + var max = this._buffer.length - this._pos; + n = Math.max(n, 0); + var toRead = Math.min(n, max); + if (toRead === 0) { + // simulate the read buffer filling up with some more bytes some time + // in the future. + setTimeout(function () { + this._pos = 0; + this._bufs -= 1; + if (this._bufs <= 0) { + // read them all! + if (!this.ended) this.push(null); + } else { + // now we have more. + // kinda cheating by calling _read, but whatever, + // it's just fake anyway. + this._read(n); + } + }.bind(this), 10); + return; + } + + var ret = this._buffer.slice(this._pos, this._pos + toRead); + this._pos += toRead; + this.push(ret); +}; + +///// + +function TestWriter() { + EE.apply(this); + this.received = []; + this.flush = false; +} + +util.inherits(TestWriter, EE); + +TestWriter.prototype.write = function (c) { + this.received.push(c.toString()); + this.emit('write', c); + return true; +}; + +TestWriter.prototype.end = function (c) { + if (c) this.write(c); + this.emit('end', this.received); +}; + +//////// + +// tiny node-tap lookalike. +var tests = []; +var count = 0; + +function test(name, fn) { + count++; + tests.push([name, fn]); +} + +function run() { + var next = tests.shift(); + if (!next) return console.error('ok'); + + var name = next[0]; + var fn = next[1]; + console.log('# %s', name); + fn({ + end: function () { + count--; + run(); + } + }); +} + +// ensure all tests have run +process.on('exit', function () { + assert.strictEqual(count, 0); +}); + +process.nextTick(run); + +test('a most basic test', function (t) { + var r = new TestReader(20); + + var reads = []; + var expect = ['x', 'xx', 'xxx', 'xxxx', 'xxxxx', 'xxxxxxxxx', 'xxxxxxxxxx', 'xxxxxxxxxxxx', 'xxxxxxxxxxxxx', 'xxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxx']; + + r.on('end', function () { + assert.deepStrictEqual(reads, expect); + t.end(); + }); + + var readSize = 1; + function flow() { + var res = void 0; + while (null !== (res = r.read(readSize++))) { + reads.push(res.toString()); + } + r.once('readable', flow); + } + + flow(); +}); + +test('pipe', function (t) { + var r = new TestReader(5); + + var expect = ['xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx']; + + var w = new TestWriter(); + + w.on('end', function (received) { + assert.deepStrictEqual(received, expect); + t.end(); + }); + + r.pipe(w); +}); + +forEach([1, 2, 3, 4, 5, 6, 7, 8, 9], function (SPLIT) { + test('unpipe', function (t) { + var r = new TestReader(5); + + // unpipe after 3 writes, then write to another stream instead. + var expect = ['xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx']; + expect = [expect.slice(0, SPLIT), expect.slice(SPLIT)]; + + var w = [new TestWriter(), new TestWriter()]; + + var writes = SPLIT; + w[0].on('write', function () { + if (--writes === 0) { + r.unpipe(); + assert.strictEqual(r._readableState.pipes, null); + w[0].end(); + r.pipe(w[1]); + assert.strictEqual(r._readableState.pipes, w[1]); + } + }); + + var ended = 0; + + var ended0 = false; + var ended1 = false; + w[0].on('end', function (results) { + assert.strictEqual(ended0, false); + ended0 = true; + ended++; + assert.deepStrictEqual(results, expect[0]); + }); + + w[1].on('end', function (results) { + assert.strictEqual(ended1, false); + ended1 = true; + ended++; + assert.strictEqual(ended, 2); + assert.deepStrictEqual(results, expect[1]); + t.end(); + }); + + r.pipe(w[0]); + }); +}); + +// both writers should get the same exact data. +test('multipipe', function (t) { + var r = new TestReader(5); + var w = [new TestWriter(), new TestWriter()]; + + var expect = ['xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx']; + + var c = 2; + w[0].on('end', function (received) { + assert.deepStrictEqual(received, expect, 'first'); + if (--c === 0) t.end(); + }); + w[1].on('end', function (received) { + assert.deepStrictEqual(received, expect, 'second'); + if (--c === 0) t.end(); + }); + + r.pipe(w[0]); + r.pipe(w[1]); +}); + +forEach([1, 2, 3, 4, 5, 6, 7, 8, 9], function (SPLIT) { + test('multi-unpipe', function (t) { + var r = new TestReader(5); + + // unpipe after 3 writes, then write to another stream instead. + var expect = ['xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx']; + expect = [expect.slice(0, SPLIT), expect.slice(SPLIT)]; + + var w = [new TestWriter(), new TestWriter(), new TestWriter()]; + + var writes = SPLIT; + w[0].on('write', function () { + if (--writes === 0) { + r.unpipe(); + w[0].end(); + r.pipe(w[1]); + } + }); + + var ended = 0; + + w[0].on('end', function (results) { + ended++; + assert.deepStrictEqual(results, expect[0]); + }); + + w[1].on('end', function (results) { + ended++; + assert.strictEqual(ended, 2); + assert.deepStrictEqual(results, expect[1]); + t.end(); + }); + + r.pipe(w[0]); + r.pipe(w[2]); + }); +}); + +test('back pressure respected', function (t) { + var r = new R({ objectMode: true }); + r._read = common.mustNotCall(); + var counter = 0; + r.push(['one']); + r.push(['two']); + r.push(['three']); + r.push(['four']); + r.push(null); + + var w1 = new R(); + w1.write = function (chunk) { + console.error('w1.emit("close")'); + assert.strictEqual(chunk[0], 'one'); + w1.emit('close'); + process.nextTick(function () { + r.pipe(w2); + r.pipe(w3); + }); + }; + w1.end = common.mustNotCall(); + + r.pipe(w1); + + var expected = ['two', 'two', 'three', 'three', 'four', 'four']; + + var w2 = new R(); + w2.write = function (chunk) { + console.error('w2 write', chunk, counter); + assert.strictEqual(chunk[0], expected.shift()); + assert.strictEqual(counter, 0); + + counter++; + + if (chunk[0] === 'four') { + return true; + } + + setTimeout(function () { + counter--; + console.error('w2 drain'); + w2.emit('drain'); + }, 10); + + return false; + }; + w2.end = common.mustCall(); + + var w3 = new R(); + w3.write = function (chunk) { + console.error('w3 write', chunk, counter); + assert.strictEqual(chunk[0], expected.shift()); + assert.strictEqual(counter, 1); + + counter++; + + if (chunk[0] === 'four') { + return true; + } + + setTimeout(function () { + counter--; + console.error('w3 drain'); + w3.emit('drain'); + }, 50); + + return false; + }; + w3.end = function () { + assert.strictEqual(counter, 2); + assert.strictEqual(expected.length, 0); + t.end(); + }; +}); + +test('read(0) for ended streams', function (t) { + var r = new R(); + var written = false; + var ended = false; + r._read = common.mustNotCall(); + + r.push(bufferShim.from('foo')); + r.push(null); + + var v = r.read(0); + + assert.strictEqual(v, null); + + var w = new R(); + + w.write = function (buffer) { + written = true; + assert.strictEqual(ended, false); + assert.strictEqual(buffer.toString(), 'foo'); + }; + + w.end = function () { + ended = true; + assert.strictEqual(written, true); + t.end(); + }; + + r.pipe(w); +}); + +test('sync _read ending', function (t) { + var r = new R(); + var called = false; + r._read = function (n) { + r.push(null); + }; + + r.once('end', function () { + called = true; + }); + + r.read(); + + process.nextTick(function () { + assert.strictEqual(called, true); + t.end(); + }); +}); + +test('adding readable triggers data flow', function (t) { + var r = new R({ highWaterMark: 5 }); + var onReadable = false; + var readCalled = 0; + + r._read = function (n) { + if (readCalled++ === 2) r.push(null);else r.push(bufferShim.from('asdf')); + }; + + r.on('readable', function () { + onReadable = true; + r.read(); + }); + + r.on('end', function () { + assert.strictEqual(readCalled, 3); + assert.ok(onReadable); + t.end(); + }); +}); + +test('chainable', function (t) { + var r = new R(); + r._read = common.mustCall(); + var r2 = r.setEncoding('utf8').pause().resume().pause(); + assert.strictEqual(r, r2); + t.end(); +}); + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} \ No newline at end of file diff --git a/test/parallel/test-stream2-compatibility.js b/test/parallel/test-stream2-compatibility.js index e37ac1275b..2debe5b206 100644 --- a/test/parallel/test-stream2-compatibility.js +++ b/test/parallel/test-stream2-compatibility.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-finish-pipe.js b/test/parallel/test-stream2-finish-pipe.js index 6f20be857e..5f0490f4c2 100644 --- a/test/parallel/test-stream2-finish-pipe.js +++ b/test/parallel/test-stream2-finish-pipe.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-large-read-stall.js b/test/parallel/test-stream2-large-read-stall.js index 75364a8a6a..a9dd386169 100644 --- a/test/parallel/test-stream2-large-read-stall.js +++ b/test/parallel/test-stream2-large-read-stall.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-objects.js b/test/parallel/test-stream2-objects.js index 3fcf351a42..145e320ae1 100644 --- a/test/parallel/test-stream2-objects.js +++ b/test/parallel/test-stream2-objects.js @@ -1,7 +1,29 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -require('../common'); + +var common = require('../common'); var Readable = require('../../lib/_stream_readable'); var Writable = require('../../lib/_stream_writable'); var assert = require('assert/'); @@ -55,7 +77,7 @@ function toArray(callback) { function fromArray(list) { var r = new Readable({ objectMode: true }); - r._read = noop; + r._read = common.mustNotCall(); forEach(list, function (chunk) { r.push(chunk); }); @@ -64,8 +86,6 @@ function fromArray(list) { return r; } -function noop() {} - test('can read objects from stream', function (t) { var r = fromArray([{ one: '1' }, { two: '2' }]); @@ -136,7 +156,7 @@ test('can read strings as objects', function (t) { var r = new Readable({ objectMode: true }); - r._read = noop; + r._read = common.mustNotCall(); var list = ['one', 'two', 'three']; forEach(list, function (str) { r.push(str); @@ -154,7 +174,7 @@ test('read(0) for object streams', function (t) { var r = new Readable({ objectMode: true }); - r._read = noop; + r._read = common.mustNotCall(); r.push('foobar'); r.push(null); @@ -170,7 +190,7 @@ test('falsey values', function (t) { var r = new Readable({ objectMode: true }); - r._read = noop; + r._read = common.mustNotCall(); r.push(false); r.push(0); @@ -221,7 +241,7 @@ test('high watermark push', function (t) { highWaterMark: 6, objectMode: true }); - r._read = function (n) {}; + r._read = common.mustNotCall(); for (var i = 0; i < 6; i++) { var bool = r.push(i); assert.strictEqual(bool, i !== 5); diff --git a/test/parallel/test-stream2-pipe-error-handling.js b/test/parallel/test-stream2-pipe-error-handling.js index f04b97e2f7..4ccad3dfe2 100644 --- a/test/parallel/test-stream2-pipe-error-handling.js +++ b/test/parallel/test-stream2-pipe-error-handling.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-pipe-error-once-listener.js b/test/parallel/test-stream2-pipe-error-once-listener.js index 64afdf11b9..83f05b769b 100644 --- a/test/parallel/test-stream2-pipe-error-once-listener.js +++ b/test/parallel/test-stream2-pipe-error-once-listener.js @@ -1,14 +1,35 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -require('../common'); +var common = require('../common'); var util = require('util'); var stream = require('../../'); -var Read = function () { +function Read() { stream.Readable.call(this); -}; +} util.inherits(Read, stream.Readable); Read.prototype._read = function (size) { @@ -16,9 +37,9 @@ Read.prototype._read = function (size) { this.push(null); }; -var Write = function () { +function Write() { stream.Writable.call(this); -}; +} util.inherits(Write, stream.Writable); Write.prototype._write = function (buffer, encoding, cb) { @@ -29,7 +50,7 @@ Write.prototype._write = function (buffer, encoding, cb) { var read = new Read(); var write = new Write(); -write.once('error', function (err) {}); +write.once('error', common.noop); write.once('alldone', function (err) { console.log('ok'); }); diff --git a/test/parallel/test-stream2-push.js b/test/parallel/test-stream2-push.js index b34268d87a..4c0bc87594 100644 --- a/test/parallel/test-stream2-push.js +++ b/test/parallel/test-stream2-push.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-read-sync-stack.js b/test/parallel/test-stream2-read-sync-stack.js index d8389cfadb..d0400d52d3 100644 --- a/test/parallel/test-stream2-read-sync-stack.js +++ b/test/parallel/test-stream2-read-sync-stack.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -21,6 +42,6 @@ r.on('readable', function onReadable() { r.read(N * 2); }); -r.on('end', common.mustCall(function () {})); +r.on('end', common.mustCall()); r.read(0); \ No newline at end of file diff --git a/test/parallel/test-stream2-readable-empty-buffer-no-eof.js b/test/parallel/test-stream2-readable-empty-buffer-no-eof.js index 54b5e24d9b..8371ac1133 100644 --- a/test/parallel/test-stream2-readable-empty-buffer-no-eof.js +++ b/test/parallel/test-stream2-readable-empty-buffer-no-eof.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -56,7 +77,7 @@ function test1() { function flow() { var chunk = void 0; while (null !== (chunk = r.read())) { - results.push(chunk + ''); + results.push(String(chunk)); } } r.on('readable', flow); @@ -83,7 +104,7 @@ function test2() { function flow() { var chunk = void 0; while (null !== (chunk = r.read())) { - results.push(chunk + ''); + results.push(String(chunk)); } } r.on('readable', flow); diff --git a/test/parallel/test-stream2-readable-from-list.js b/test/parallel/test-stream2-readable-from-list.js index 2c87a82b19..57af17a446 100644 --- a/test/parallel/test-stream2-readable-from-list.js +++ b/test/parallel/test-stream2-readable-from-list.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + // Flags: --expose_internals /**/ var bufferShim = require('safe-buffer').Buffer; diff --git a/test/parallel/test-stream2-readable-legacy-drain.js b/test/parallel/test-stream2-readable-legacy-drain.js index 47bf0ae256..8c249c1f3a 100644 --- a/test/parallel/test-stream2-readable-legacy-drain.js +++ b/test/parallel/test-stream2-readable-legacy-drain.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -14,7 +35,7 @@ r._read = function (n) { return r.push(++reads === N ? null : bufferShim.allocUnsafe(1)); }; -r.on('end', common.mustCall(function () {})); +r.on('end', common.mustCall()); var w = new Stream(); w.writable = true; @@ -31,7 +52,7 @@ function drain() { w.emit('drain'); } -w.end = common.mustCall(function () {}); +w.end = common.mustCall(); // Just for kicks, let's mess with the drain count. // This verifies that even if it gets negative in the diff --git a/test/parallel/test-stream2-readable-non-empty-end.js b/test/parallel/test-stream2-readable-non-empty-end.js index d42791df61..d062e60258 100644 --- a/test/parallel/test-stream2-readable-non-empty-end.js +++ b/test/parallel/test-stream2-readable-non-empty-end.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -42,7 +63,7 @@ test.read(0); function next() { // now let's make 'end' happen test.removeListener('end', thrower); - test.on('end', common.mustCall(function () {})); + test.on('end', common.mustCall()); // one to get the last byte var r = test.read(); diff --git a/test/parallel/test-stream2-readable-wrap-empty.js b/test/parallel/test-stream2-readable-wrap-empty.js index 988c4e4117..be5daf5386 100644 --- a/test/parallel/test-stream2-readable-wrap-empty.js +++ b/test/parallel/test-stream2-readable-wrap-empty.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -7,11 +28,11 @@ var Readable = require('../../lib/_stream_readable'); var EE = require('events').EventEmitter; var oldStream = new EE(); -oldStream.pause = function () {}; -oldStream.resume = function () {}; +oldStream.pause = common.noop; +oldStream.resume = common.noop; var newStream = new Readable().wrap(oldStream); -newStream.on('readable', function () {}).on('end', common.mustCall(function () {})); +newStream.on('readable', common.noop).on('end', common.mustCall()); oldStream.emit('end'); \ No newline at end of file diff --git a/test/parallel/test-stream2-set-encoding.js b/test/parallel/test-stream2-set-encoding.js index 2c8396f40b..3c39298ac6 100644 --- a/test/parallel/test-stream2-set-encoding.js +++ b/test/parallel/test-stream2-set-encoding.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-transform.js b/test/parallel/test-stream2-transform.js index 84cae1ad69..017b515221 100644 --- a/test/parallel/test-stream2-transform.js +++ b/test/parallel/test-stream2-transform.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ @@ -320,7 +341,7 @@ test('passthrough event emission', function (t) { t.equal(emits, 1); t.equal(pt.read(5).toString(), 'foogb'); - t.equal(pt.read(5) + '', 'null'); + t.equal(String(pt.read(5)), 'null'); console.error('need emit 1'); diff --git a/test/parallel/test-stream2-unpipe-drain.js b/test/parallel/test-stream2-unpipe-drain.js index 8a4da12e54..07ea71ef3d 100644 --- a/test/parallel/test-stream2-unpipe-drain.js +++ b/test/parallel/test-stream2-unpipe-drain.js @@ -1,4 +1,25 @@ (function () { + // Copyright Joyent, Inc. and other Node contributors. + // + // Permission is hereby granted, free of charge, to any person obtaining a + // copy of this software and associated documentation files (the + // "Software"), to deal in the Software without restriction, including + // without limitation the rights to use, copy, modify, merge, publish, + // distribute, sublicense, and/or sell copies of the Software, and to permit + // persons to whom the Software is furnished to do so, subject to the + // following conditions: + // + // The above copyright notice and this permission notice shall be included + // in all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-unpipe-leak.js b/test/parallel/test-stream2-unpipe-leak.js index 87eb6c52ee..fae8ece7c0 100644 --- a/test/parallel/test-stream2-unpipe-leak.js +++ b/test/parallel/test-stream2-unpipe-leak.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-stream2-writable.js b/test/parallel/test-stream2-writable.js index 5d15da1e73..418c7c82cb 100644 --- a/test/parallel/test-stream2-writable.js +++ b/test/parallel/test-stream2-writable.js @@ -1,7 +1,29 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ -require('../common'); + +var common = require('../common'); var W = require('../../lib/_stream_writable'); var D = require('../../lib/_stream_duplex'); var assert = require('assert/'); @@ -257,7 +279,7 @@ test('encoding should be ignored for buffers', function (t) { test('writables are not pipable', function (t) { var w = new W(); - w._write = function () {}; + w._write = common.noop; var gotError = false; w.on('error', function () { gotError = true; @@ -269,8 +291,8 @@ test('writables are not pipable', function (t) { test('duplexes are pipable', function (t) { var d = new D(); - d._read = function () {}; - d._write = function () {}; + d._read = common.noop; + d._write = common.noop; var gotError = false; d.on('error', function () { gotError = true; @@ -282,7 +304,7 @@ test('duplexes are pipable', function (t) { test('end(chunk) two times is an error', function (t) { var w = new W(); - w._write = function () {}; + w._write = common.noop; var gotError = false; w.on('error', function (er) { gotError = true; @@ -361,6 +383,28 @@ test('finish is emitted if last chunk is empty', function (t) { w.end(bufferShim.alloc(0)); }); +test('finish is emitted after shutdown', function (t) { + var w = new W(); + var shutdown = false; + + w._final = common.mustCall(function (cb) { + assert.strictEqual(this, w); + setTimeout(function () { + shutdown = true; + cb(); + }, 100); + }); + w._write = function (chunk, e, cb) { + process.nextTick(cb); + }; + w.on('finish', common.mustCall(function () { + assert(shutdown); + t.end(); + })); + w.write(bufferShim.allocUnsafe(1)); + w.end(bufferShim.allocUnsafe(0)); +}); + function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); diff --git a/test/parallel/test-stream3-pause-then-read.js b/test/parallel/test-stream3-pause-then-read.js index 9fbabd2097..8afc1e65a3 100644 --- a/test/parallel/test-stream3-pause-then-read.js +++ b/test/parallel/test-stream3-pause-then-read.js @@ -1,3 +1,24 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ var bufferShim = require('safe-buffer').Buffer; /**/ diff --git a/test/parallel/test-streams-highwatermark.js b/test/parallel/test-streams-highwatermark.js new file mode 100644 index 0000000000..789af9448b --- /dev/null +++ b/test/parallel/test-streams-highwatermark.js @@ -0,0 +1,20 @@ +/**/ +var bufferShim = require('safe-buffer').Buffer; +/**/ +require('../common'); + +// This test ensures that the stream implementation correctly handles values +// for highWaterMark which exceed the range of signed 32 bit integers. + +var assert = require('assert/'); +var stream = require('../../'); + +// This number exceeds the range of 32 bit integer arithmetic but should still +// be handled correctly. +var ovfl = Number.MAX_SAFE_INTEGER; + +var readable = stream.Readable({ highWaterMark: ovfl }); +assert.strictEqual(readable._readableState.highWaterMark, ovfl); + +var writable = stream.Writable({ highWaterMark: ovfl }); +assert.strictEqual(writable._writableState.highWaterMark, ovfl); \ No newline at end of file