pax_global_header00006660000000000000000000000064131252060010014500gustar00rootroot0000000000000052 comment=cd59995050105b946884ee20e3bcadc252feda8c readable-stream-2.3.3/000077500000000000000000000000001312520600100145355ustar00rootroot00000000000000readable-stream-2.3.3/.gitignore000066400000000000000000000000771312520600100165310ustar00rootroot00000000000000node_modules/ .zuul.yml .nyc_output coverage package-lock.json readable-stream-2.3.3/.npmignore000066400000000000000000000001121312520600100165260ustar00rootroot00000000000000build/ test/ examples/ fs.js zlib.js .zuul.yml .nyc_output coverage docs/ readable-stream-2.3.3/.travis.yml000066400000000000000000000033711312520600100166520ustar00rootroot00000000000000sudo: false language: node_js before_install: - npm install -g npm@2 - test $NPM_LEGACY && npm install -g npm@latest-3 || npm install npm -g notifications: email: false matrix: fast_finish: true include: - node_js: '0.8' env: - TASK=test - NPM_LEGACY=true - node_js: '0.10' env: - TASK=test - NPM_LEGACY=true - node_js: '0.11' env: - TASK=test - NPM_LEGACY=true - node_js: '0.12' env: - TASK=test - NPM_LEGACY=true - node_js: 1 env: - TASK=test - NPM_LEGACY=true - node_js: 2 env: - TASK=test - NPM_LEGACY=true - node_js: 3 env: - TASK=test - NPM_LEGACY=true - node_js: 4 env: TASK=test - node_js: 5 env: TASK=test - node_js: 6 env: TASK=test - node_js: 7 env: TASK=test - node_js: 8 env: TASK=test - node_js: 6 env: TASK=browser BROWSER_NAME=ie BROWSER_VERSION="9..latest" - node_js: 6 env: TASK=browser BROWSER_NAME=opera BROWSER_VERSION="11..latest" - node_js: 6 env: TASK=browser BROWSER_NAME=chrome BROWSER_VERSION="-3..latest" - node_js: 6 env: TASK=browser BROWSER_NAME=firefox BROWSER_VERSION="-3..latest" - node_js: 6 env: TASK=browser BROWSER_NAME=safari BROWSER_VERSION="5..latest" - node_js: 6 env: TASK=browser BROWSER_NAME=microsoftedge BROWSER_VERSION=latest script: "npm run $TASK" env: global: - secure: rE2Vvo7vnjabYNULNyLFxOyt98BoJexDqsiOnfiD6kLYYsiQGfr/sbZkPMOFm9qfQG7pjqx+zZWZjGSswhTt+626C0t/njXqug7Yps4c3dFblzGfreQHp7wNX5TFsvrxd6dAowVasMp61sJcRnB2w8cUzoe3RAYUDHyiHktwqMc= - secure: g9YINaKAdMatsJ28G9jCGbSaguXCyxSTy+pBO6Ch0Cf57ZLOTka3HqDj8p3nV28LUIHZ3ut5WO43CeYKwt4AUtLpBS3a0dndHdY6D83uY6b2qh5hXlrcbeQTq2cvw2y95F7hm4D1kwrgZ7ViqaKggRcEupAL69YbJnxeUDKWEdI= readable-stream-2.3.3/CONTRIBUTING.md000066400000000000000000000026431312520600100167730ustar00rootroot00000000000000# Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: * (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or * (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or * (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. * (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ## Moderation Policy The [Node.js Moderation Policy] applies to this WG. ## Code of Conduct The [Node.js Code of Conduct][] applies to this WG. [Node.js Code of Conduct]: https://github.com/nodejs/node/blob/master/CODE_OF_CONDUCT.md [Node.js Moderation Policy]: https://github.com/nodejs/TSC/blob/master/Moderation-Policy.md readable-stream-2.3.3/GOVERNANCE.md000066400000000000000000000126561312520600100165200ustar00rootroot00000000000000### Streams Working Group The Node.js Streams is jointly governed by a Working Group (WG) that is responsible for high-level guidance of the project. The WG has final authority over this project including: * Technical direction * Project governance and process (including this policy) * Contribution policy * GitHub repository hosting * Conduct guidelines * Maintaining the list of additional Collaborators For the current list of WG members, see the project [README.md](./README.md#current-project-team-members). ### Collaborators The readable-stream GitHub repository is maintained by the WG and additional Collaborators who are added by the WG on an ongoing basis. Individuals making significant and valuable contributions are made Collaborators and given commit-access to the project. These individuals are identified by the WG and their addition as Collaborators is discussed during the WG meeting. _Note:_ If you make a significant contribution and are not considered for commit-access log an issue or contact a WG member directly and it will be brought up in the next WG meeting. Modifications of the contents of the readable-stream repository are made on a collaborative basis. Anybody with a GitHub account may propose a modification via pull request and it will be considered by the project Collaborators. All pull requests must be reviewed and accepted by a Collaborator with sufficient expertise who is able to take full responsibility for the change. In the case of pull requests proposed by an existing Collaborator, an additional Collaborator is required for sign-off. Consensus should be sought if additional Collaborators participate and there is disagreement around a particular modification. See _Consensus Seeking Process_ below for further detail on the consensus model used for governance. Collaborators may opt to elevate significant or controversial modifications, or modifications that have not found consensus to the WG for discussion by assigning the ***WG-agenda*** tag to a pull request or issue. The WG should serve as the final arbiter where required. For the current list of Collaborators, see the project [README.md](./README.md#members). ### WG Membership WG seats are not time-limited. There is no fixed size of the WG. However, the expected target is between 6 and 12, to ensure adequate coverage of important areas of expertise, balanced with the ability to make decisions efficiently. There is no specific set of requirements or qualifications for WG membership beyond these rules. The WG may add additional members to the WG by unanimous consensus. A WG member may be removed from the WG by voluntary resignation, or by unanimous consensus of all other WG members. Changes to WG membership should be posted in the agenda, and may be suggested as any other agenda item (see "WG Meetings" below). If an addition or removal is proposed during a meeting, and the full WG is not in attendance to participate, then the addition or removal is added to the agenda for the subsequent meeting. This is to ensure that all members are given the opportunity to participate in all membership decisions. If a WG member is unable to attend a meeting where a planned membership decision is being made, then their consent is assumed. No more than 1/3 of the WG members may be affiliated with the same employer. If removal or resignation of a WG member, or a change of employment by a WG member, creates a situation where more than 1/3 of the WG membership shares an employer, then the situation must be immediately remedied by the resignation or removal of one or more WG members affiliated with the over-represented employer(s). ### WG Meetings The WG meets occasionally on a Google Hangout On Air. A designated moderator approved by the WG runs the meeting. Each meeting should be published to YouTube. Items are added to the WG agenda that are considered contentious or are modifications of governance, contribution policy, WG membership, or release process. The intention of the agenda is not to approve or review all patches; that should happen continuously on GitHub and be handled by the larger group of Collaborators. Any community member or contributor can ask that something be added to the next meeting's agenda by logging a GitHub Issue. Any Collaborator, WG member or the moderator can add the item to the agenda by adding the ***WG-agenda*** tag to the issue. Prior to each WG meeting the moderator will share the Agenda with members of the WG. WG members can add any items they like to the agenda at the beginning of each meeting. The moderator and the WG cannot veto or remove items. The WG may invite persons or representatives from certain projects to participate in a non-voting capacity. The moderator is responsible for summarizing the discussion of each agenda item and sends it as a pull request after the meeting. ### Consensus Seeking Process The WG follows a [Consensus Seeking](http://en.wikipedia.org/wiki/Consensus-seeking_decision-making) decision-making model. When an agenda item has appeared to reach a consensus the moderator will ask "Does anyone object?" as a final call for dissent from the consensus. If an agenda item cannot reach a consensus a WG member can call for either a closing vote or a vote to table the issue to the next meeting. The call for a vote must be seconded by a majority of the WG or else the discussion will continue. Simple majority wins. Note that changes to WG membership require a majority consensus. See "WG Membership" above. readable-stream-2.3.3/LICENSE000066400000000000000000000044411312520600100155450ustar00rootroot00000000000000Node.js is licensed for use as follows: """ Copyright Node.js contributors. All rights reserved. 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. """ This license applies to parts of Node.js originating from the https://github.com/joyent/node repository: """ Copyright Joyent, Inc. and other Node contributors. All rights reserved. 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. """ readable-stream-2.3.3/README.md000066400000000000000000000055341312520600100160230ustar00rootroot00000000000000# readable-stream ***Node-core v8.1.3 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/) [![NPM](https://nodei.co/npm-dl/readable-stream.png?&months=6&height=3)](https://nodei.co/npm/readable-stream/) [![Sauce Test Status](https://saucelabs.com/browser-matrix/readable-stream.svg)](https://saucelabs.com/u/readable-stream) ```bash npm install --save readable-stream ``` ***Node-core streams for userland*** 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/v8.1.3/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). As of version 2.0.0 **readable-stream** uses semantic versioning. # Streams Working Group `readable-stream` is maintained by the Streams Working Group, which oversees the development and maintenance of the Streams API within Node.js. The responsibilities of the Streams Working Group include: * Addressing stream issues on the Node.js issue tracker. * Authoring and editing stream documentation within the Node.js project. * Reviewing changes to stream subclasses within the Node.js project. * Redirecting changes to streams from the Node.js project to this project. * Assisting in the implementation of stream providers within Node.js. * Recommending versions of `readable-stream` to be included in Node.js. * Messaging about the future of streams to give the community advance notice of changes. ## Team Members * **Chris Dickinson** ([@chrisdickinson](https://github.com/chrisdickinson)) <christopher.s.dickinson@gmail.com> - Release GPG key: 9554F04D7259F04124DE6B476D5A82AC7E37093B * **Calvin Metcalf** ([@calvinmetcalf](https://github.com/calvinmetcalf)) <calvin.metcalf@gmail.com> - Release GPG key: F3EF5F62A87FC27A22E643F714CE4FF5015AA242 * **Rod Vagg** ([@rvagg](https://github.com/rvagg)) <rod@vagg.org> - Release GPG key: DD8F2338BAE7501E3DD5AC78C273792F7D83545D * **Sam Newman** ([@sonewman](https://github.com/sonewman)) <newmansam@outlook.com> * **Mathias Buus** ([@mafintosh](https://github.com/mafintosh)) <mathiasbuus@gmail.com> * **Domenic Denicola** ([@domenic](https://github.com/domenic)) <d@domenic.me> * **Matteo Collina** ([@mcollina](https://github.com/mcollina)) <matteo.collina@gmail.com> - Release GPG key: 3ABC01543F22DD2239285CDD818674489FBC127E readable-stream-2.3.3/build/000077500000000000000000000000001312520600100156345ustar00rootroot00000000000000readable-stream-2.3.3/build/.gitignore000066400000000000000000000000151312520600100176200ustar00rootroot00000000000000node_modules readable-stream-2.3.3/build/build.js000066400000000000000000000126251312520600100172770ustar00rootroot00000000000000#!/usr/bin/env node const hyperquest = require('hyperquest') , bl = require('bl') , fs = require('fs') , path = require('path') , tar = require('tar-fs') , gunzip = require('gunzip-maybe') , babel = require('babel-core') , glob = require('glob') , pump = require('pump') , rimraf = require('rimraf') , encoding = 'utf8' , urlRegex = /^https?:\/\// , nodeVersion = process.argv[2] , nodeVersionRegexString = '\\d+\\.\\d+\\.\\d+' , usageVersionRegex = RegExp('^' + nodeVersionRegexString + '$') , readmeVersionRegex = RegExp('((?:(?:Node-core )|(?:https\:\/\/nodejs\.org\/dist\/))v)' + nodeVersionRegexString, 'g') , readmePath = path.join(__dirname, '..', 'README.md') , files = require('./files') , testReplace = require('./test-replacements') , downloadurl = `https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}.tar.gz` , src = path.join(__dirname, `node-v${nodeVersion}`) , libsrcurl = path.join(src, 'lib/') , testsrcurl = path.join(src, 'test/parallel/') , libourroot = path.join(__dirname, '../lib/') , testourroot = path.join(__dirname, '../test/parallel/') if (!usageVersionRegex.test(nodeVersion)) { console.error('Usage: build.js xx.yy.zz') return process.exit(1); } // `inputLoc`: URL or local path. function processFile (inputLoc, out, replacements) { var file = fs.createReadStream(inputLoc, encoding) file.pipe(bl(function (err, data) { if (err) throw err console.log('Processing', inputLoc) data = data.toString() replacements.forEach(function (replacement) { const regexp = replacement[0] var arg2 = replacement[1] if (typeof arg2 === 'function') arg2 = arg2.bind(data) if (arg2 === undefined) { console.error('missing second arg for file', inputLoc, replacement) throw new Error('missing second arg in replacement') } data = data.replace(regexp, arg2) }) if (inputLoc.slice(-3) === '.js') { const transformed = babel.transform(data, { plugins: [ 'transform-es2015-parameters', 'transform-es2015-arrow-functions', 'transform-es2015-block-scoping', 'transform-es2015-template-literals', 'transform-es2015-shorthand-properties', 'transform-es2015-for-of', ['transform-es2015-classes', { loose: true }], 'transform-es2015-destructuring', 'transform-es2015-computed-properties', 'transform-es2015-spread' ] }) data = transformed.code } fs.writeFile(out, data, encoding, function (err) { if (err) throw err console.log('Wrote', out) }) })) } function deleteOldTests(){ const files = fs.readdirSync(path.join(__dirname, '..', 'test', 'parallel')); for (let file of files) { let name = path.join(__dirname, '..', 'test', 'parallel', file); console.log('Removing', name); fs.unlinkSync(name); } } function processLibFile (file) { var replacements = files[file] , url = libsrcurl + file , out = path.join(libourroot, file) processFile(url, out, replacements) } function processTestFile (file) { var replacements = testReplace.all , url = testsrcurl + file , out = path.join(testourroot, file) if (testReplace[file]) replacements = replacements.concat(testReplace[file]) processFile(url, out, replacements) } //-------------------------------------------------------------------- // Download the release from nodejs.org console.log(`Downloading ${downloadurl}`) pump( hyperquest(downloadurl), gunzip(), tar.extract(__dirname), function (err) { if (err) { throw err } //-------------------------------------------------------------------- // Grab & process files in ../lib/ Object.keys(files).forEach(processLibFile) //-------------------------------------------------------------------- // Discover, grab and process all test-stream* files on the given release glob(path.join(testsrcurl, 'test-stream*.js'), function (err, list) { if (err) { throw err } list.forEach(function (file) { file = path.basename(file) if (!/-wrap(?:-encoding)?\.js$/.test(file) && 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-base-typechecking.js') { processTestFile(file) } }) }) //-------------------------------------------------------------------- // Grab the nodejs/node test/common.js processFile( 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] ]) } ) // delete the current contents of test/parallel so if node removes any tests // they are removed here deleteOldTests(); process.once('beforeExit', function () { rimraf(src, function (err) { if (err) { throw err } console.log('Removed', src) }) }) readable-stream-2.3.3/build/common-replacements.js000066400000000000000000000026101312520600100221410ustar00rootroot00000000000000module.exports.altForEachImplReplacement = [ /$/ , '\nfunction forEach (xs, f) {\n' + ' for (var i = 0, l = xs.length; i < l; i++) {\n' + ' f(xs[i], i);\n' + ' }\n' + '}\n' ] module.exports.altForEachUseReplacement = [ /(\W)([\w\.\(\),\[\]]+)(\.forEach\()/gm , '$1forEach($2, ' ] module.exports.specialForEachReplacment = [ /(\W)(\[(?:\d\,\s)+\d\])(\.forEach\()/gm , '$1forEach($2, ' ] module.exports.altIndexOfImplReplacement = [ /$/ , '\nfunction indexOf (xs, x) {\n' + ' for (var i = 0, l = xs.length; i < l; i++) {\n' + ' if (xs[i] === x) return i;\n' + ' }\n' + ' return -1;\n' + '}\n' ] module.exports.altIndexOfUseReplacement = [ /(\W)([\w\.\(\),\[\]]+)(\.indexOf\()/gm , '$1indexOf($2, ' ] module.exports.objectKeysDefine = [ /^('use strict';)$/m , '$1\n\n/**/\nvar objectKeys = Object.keys || function (obj) {\n' + ' var keys = [];\n' + ' for (var key in obj) keys.push(key);\n' + ' return keys;\n' + '}\n/**/\n' ] module.exports.objectKeysReplacement = [ /Object\.keys/g , 'objectKeys' ] module.exports.bufferShimFix = [ /^('use strict';)$/m, `/**/ const bufferShim = require('safe-buffer').Buffer; /**/` ] module.exports.bufferStaticMethods = [ /Buffer\.((?:alloc)|(?:allocUnsafe)|(?:from))/g, `bufferShim.$1` ] readable-stream-2.3.3/build/files.js000066400000000000000000000223241312520600100172770ustar00rootroot00000000000000/* This file lists the files to be fetched from the node repo * in the /lib/ directory which will be placed in the ../lib/ * directory after having each of the "replacements" in the * array for that file applied to it. The replacements are * simply the arguments to String#replace, so they can be * strings, regexes, functions. */ const headRegexp = /(^module.exports = \w+;?)/m , requireReplacement = [ /(require\(['"])(_stream_)/g , '$1./$2' ] , instanceofReplacement = [ /instanceof Stream\.(\w+)/g , function (match, streamType) { return 'instanceof ' + streamType } ] // use the string_decoder in node_modules rather than core , stringDecoderReplacement = [ /(require\(['"])(string_decoder)(['"]\))/g , '$1$2/$3' ] // The browser build ends up with a circular dependency, so the require is // done lazily, but cached. , addDuplexDec = [ headRegexp , '$1\n\n/**/\nvar Duplex;\n/**/\n' ] , addDuplexRequire = [ /^(function (?:Writable|Readable)(?:State)?.*{)/gm , '\n$1\n Duplex = Duplex || require(\'./_stream_duplex\');\n' ] , altForEachImplReplacement = require('./common-replacements').altForEachImplReplacement , altForEachUseReplacement = require('./common-replacements').altForEachUseReplacement , altIndexOfImplReplacement = require('./common-replacements').altIndexOfImplReplacement , altIndexOfUseReplacement = require('./common-replacements').altIndexOfUseReplacement , utilReplacement = [ /^const util = require\('util'\);/m , '\n/**/\nconst util = require(\'core-util-is\');\n' + 'util.inherits = require(\'inherits\');\n/**/\n' ] , debugLogReplacement = [ /const debug = util.debuglog\('stream'\);/ , '\n\n/**/\nconst debugUtil = require(\'util\');\n' + 'let debug;\n' + 'if (debugUtil && debugUtil.debuglog) {\n' + ' debug = debugUtil.debuglog(\'stream\');\n' + '} else {\n' + ' debug = function () {};\n' + '}\n/**/\n' ] , deprecateReplacement = [ /util.deprecate/ , 'require(\'util-deprecate\')' ] , objectDefinePropertyReplacement = [ /(Object\.defineProperties)/ , 'if (Object.defineProperties) $1' ] , objectDefinePropertySingReplacement = [ /Object\.defineProperty\(([\w\W]+?)\}\);/ , '(function (){try {\n' + 'Object.defineProperty\($1});\n' + '}catch(_){}}());\n' ] , isArrayDefine = [ headRegexp , '$1\n\n/**/\nvar isArray = require(\'isarray\');\n/**/\n' ] , isArrayReplacement = [ /Array\.isArray/g , 'isArray' ] , objectKeysDefine = require('./common-replacements').objectKeysDefine , objectKeysReplacement = require('./common-replacements').objectKeysReplacement , eventEmittterReplacement = [ /^(const EE = require\('events'\));$/m , '/**/\n$1.EventEmitter;\n\n' + 'var EElistenerCount = function(emitter, type) {\n' + ' return emitter.listeners(type).length;\n' + '};\n/**/\n' ] , eventEmittterListenerCountReplacement = [ /(EE\.listenerCount)/g , 'EElistenerCount' ] , bufferIsEncodingReplacement = [ /Buffer.isEncoding\((\w+)\)/ , '([\'hex\', \'utf8\', \'utf-8\', \'ascii\', \'binary\', \'base64\',\n' + '\'ucs2\', \'ucs-2\',\'utf16le\', \'utf-16le\', \'raw\']\n' + '.indexOf(($1 + \'\').toLowerCase()) > -1)' ] , requireStreamReplacement = [ /const Stream = require\('stream'\);/ , '\n\n/**/\n' + 'var Stream = require(\'./internal/streams/stream\')' + '\n/**/\n' ] , isBufferReplacement = [ /(\w+) instanceof Buffer/g , 'Buffer.isBuffer($1)' ] , processNextTickImport = [ /^('use strict';)$/m , `$1 /**/ var processNextTick = require(\'process-nextick-args\'); /**/ ` ] , processNextTickReplacement = [ /process.nextTick\(/g , 'processNextTick(' ] , internalUtilReplacement = [ /^const internalUtil = require\('internal\/util'\);/m , '\n/**/\nconst internalUtil = {\n deprecate: require(\'util-deprecate\')\n};\n' + '/**/\n' ] , isNode10 = [ headRegexp , `$1 /**/ var asyncWrite = !process.browser && ['v0.10' , 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; /**/ ` ] , fixSyncWrite = [ /if \(sync\) {\n\s+processNextTick\(afterWrite, stream, state, finished, cb\);\n\s+}/ , `if (sync) { /**/ asyncWrite(afterWrite, stream, state, finished, cb); /**/ } ` ] , safeBufferFix = [ /(?:var|const) Buffer = require\('buffer'\)\.Buffer;/, `/**/ var Buffer = require('safe-buffer').Buffer /**/` ] , internalDirectory = [ /require\('internal\/streams\/([a-zA-z]+)'\)/g, 'require(\'./internal/streams/$1\')' ] , fixInstanceCheck = [ /if \(typeof Symbol === 'function' && Symbol\.hasInstance\) \{/, `if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {` ] , removeOnWriteBind = [ /onwrite\.bind\([^)]+?\)/ , `function(er) { onwrite(stream, er); }` ] , addUintStuff = [ /(?:var|const) Buffer = require\('buffer'\)\.Buffer;/ , `/**/ const Buffer = require('safe-buffer').Buffer const OurUint8Array = global.Uint8Array || function () {} function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } /**/ ` ] , addConstructors = [ headRegexp , `$1 /* */ function WriteReq(chunk, encoding, cb) { this.chunk = chunk; this.encoding = encoding; this.callback = cb; this.next = null; } // It seems a linked list but it is not // there will be only 2 of these for each stream function CorkedRequest(state) { this.next = null; this.entry = null; this.finish = () => { onCorkedFinish(this, state) }; } /* */ ` ] , useWriteReq = [ /state\.lastBufferedRequest = \{.+?\}/g , `state.lastBufferedRequest = new WriteReq(chunk, encoding, cb)` ] , useCorkedRequest = [ /var corkReq = [\s\S]+?(.+?)\.corkedRequestsFree = corkReq/g , `$1.corkedRequestsFree = new CorkedRequest($1)` ] , 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 , utilReplacement , stringDecoderReplacement , altForEachImplReplacement , altForEachUseReplacement , objectKeysReplacement , objectKeysDefine , processNextTickImport , processNextTickReplacement ] module.exports['_stream_passthrough.js'] = [ requireReplacement , instanceofReplacement , utilReplacement , stringDecoderReplacement ] module.exports['_stream_readable.js'] = [ addDuplexRequire , addDuplexDec , requireReplacement , instanceofReplacement , altForEachImplReplacement , altForEachUseReplacement , altIndexOfImplReplacement , altIndexOfUseReplacement , instanceofReplacement , stringDecoderReplacement , isArrayReplacement , isArrayDefine , debugLogReplacement , utilReplacement , stringDecoderReplacement , eventEmittterReplacement , requireStreamReplacement , isBufferReplacement , processNextTickImport , processNextTickReplacement , eventEmittterListenerCountReplacement , internalDirectory , fixUintStuff , addUintStuff ] module.exports['_stream_transform.js'] = [ requireReplacement , instanceofReplacement , utilReplacement , stringDecoderReplacement ] module.exports['_stream_writable.js'] = [ addDuplexRequire , addDuplexDec , requireReplacement , instanceofReplacement , utilReplacement , stringDecoderReplacement , debugLogReplacement , deprecateReplacement , objectDefinePropertyReplacement , objectDefinePropertySingReplacement , bufferIsEncodingReplacement , [ /^var assert = require\('assert'\);$/m, '' ] , requireStreamReplacement , isBufferReplacement , isNode10 , processNextTickImport , processNextTickReplacement , internalUtilReplacement , fixSyncWrite , fixInstanceCheck , removeOnWriteBind , internalDirectory , fixUintStuff , addUintStuff , fixBufferCheck , useWriteReq , useCorkedRequest , addConstructors ] module.exports['internal/streams/BufferList.js'] = [ safeBufferFix , fixCopyBuffer ] module.exports['internal/streams/destroy.js'] = [ processNextTickImport , processNextTickReplacement ] readable-stream-2.3.3/build/package.json000066400000000000000000000016541312520600100201300ustar00rootroot00000000000000{ "name": "readable-stream-build", "version": "0.0.0", "description": "", "main": "build.js", "dependencies": { "babel-core": "^6.24.1", "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", "gunzip-maybe": "^1.4.0", "hyperquest": "^2.1.2", "pump": "^1.0.2", "rimraf": "^2.6.1", "tar-fs": "^1.15.2" } } readable-stream-2.3.3/build/test-replacements.js000066400000000000000000000213211312520600100216300ustar00rootroot00000000000000const altForEachImplReplacement = require('./common-replacements').altForEachImplReplacement , altForEachUseReplacement = require('./common-replacements').altForEachUseReplacement , altIndexOfImplReplacement = require('./common-replacements').altIndexOfImplReplacement , altIndexOfUseReplacement = require('./common-replacements').altIndexOfUseReplacement , objectKeysDefine = require('./common-replacements').objectKeysDefine , objectKeysReplacement = require('./common-replacements').objectKeysReplacement , bufferShimFix = require('./common-replacements').bufferShimFix , bufferStaticMethods = require('./common-replacements').bufferStaticMethods , specialForEachReplacment = require('./common-replacements').specialForEachReplacment module.exports.all = [ [ /require\(['"]stream['"]\)/g , 'require(\'../../\')' ] // some tests need stream.Stream but readable.js doesn't offer that // and we've undone it with the previous replacement , [ /stream\.Stream|require\('\.\.\/\.\.\/'\)\.Stream/g , 'require(\'stream\').Stream' ] , [ /require\(['"](_stream_\w+)['"]\)/g , 'require(\'../../lib/$1\')' ] , [ /Stream.(Readable|Writable|Duplex|Transform|PassThrough)/g , 'require(\'../../\').$1' ] , bufferShimFix , bufferStaticMethods , [ /require\(['"]assert['"]\)/g , 'require(\'assert/\')' ] ] module.exports['test-stream2-basic.js'] = [ altForEachImplReplacement , specialForEachReplacment ] module.exports['test-stream2-objects.js'] = [ altForEachImplReplacement , altForEachUseReplacement ] module.exports['test-stream2-transform.js'] = [ altForEachImplReplacement , altForEachUseReplacement ] module.exports['test-stream2-writable.js'] = [ altForEachImplReplacement , altForEachUseReplacement , [ /'latin1',/g, '\'binary\',' ] ] module.exports['test-stream-big-packet.js'] = [ altIndexOfImplReplacement , altIndexOfUseReplacement ] module.exports['common.js'] = [ objectKeysDefine , objectKeysReplacement , altForEachImplReplacement , altForEachUseReplacement , [ /(exports.mustCall[\s\S]*)/m , '$1\n' + 'if (!util._errnoException) {\n' + ' var uv;\n' + ' util._errnoException = function(err, syscall) {\n' + ' if (util.isUndefined(uv)) try { uv = process.binding(\'uv\'); } catch (e) {}\n' + ' var errname = uv ? uv.errname(err) : \'\';\n' + ' var e = new Error(syscall + \' \' + errname);\n' + ' e.code = errname;\n' + ' e.errno = errname;\n' + ' e.syscall = syscall;\n' + ' return e;\n' + ' };\n' + '}\n' ] // for streams2 on node 0.11 // and dtrace in 0.10 // and coverage in all , [ /^( for \(var x in global\) \{|function leakedGlobals\(\) \{)$/m , ' /**/\n' + ' if (typeof constructor == \'function\')\n' + ' knownGlobals.push(constructor);\n' + ' if (typeof DTRACE_NET_SOCKET_READ == \'function\')\n' + ' knownGlobals.push(DTRACE_NET_SOCKET_READ);\n' + ' if (typeof DTRACE_NET_SOCKET_WRITE == \'function\')\n' + ' knownGlobals.push(DTRACE_NET_SOCKET_WRITE);\n' + ' if (global.__coverage__)\n' + ' knownGlobals.push(__coverage__);\n' + '\'core,__core-js_shared__,Promise,Map,Set,WeakMap,WeakSet,Reflect,System,asap,Observable,regeneratorRuntime,_babelPolyfill\'.split(\',\').filter(function (item) { return typeof global[item] !== undefined}).forEach(function (item) {knownGlobals.push(global[item])})' + ' /**/\n\n$1' ] // for node 0.8 , [ /^/ , '/**/' + '\nif (!global.setImmediate) {\n' + ' global.setImmediate = function setImmediate(fn) {\n' + ' return setTimeout(fn.bind.apply(fn, arguments), 4);\n' + ' };\n' + '}\n' + 'if (!global.clearImmediate) {\n' + ' global.clearImmediate = function clearImmediate(i) {\n' + ' return clearTimeout(i);\n' + ' };\n' + '}\n' + '/**/\n' ] , [ /^if \(global\.ArrayBuffer\) \{([^\}]+)\}$/m , '/**/if (!process.browser) {' + '\nif \(global\.ArrayBuffer\) {$1}\n' + '}/**/\n' ] , [ /^Object\.defineProperty\(([\w\W]+?)\}\)\;/mg , '/**/if (!process.browser) {' + '\nObject\.defineProperty($1});\n' + '}/**/\n' ] , [ /if \(!process\.send\)/ , 'if (!process.send && !process.browser)' ] , [ /^/, `/**/ require('babel-polyfill'); var util = require('util'); for (var i in util) exports[i] = util[i]; /**/` ], [ /var regexp = `\^\(\\\\w\+\)\\\\s\+\\\\s\$\{port\}\/\$\{protocol\}\\\\s`;/, `var regexp = '^(\\w+)\\s+\\s' + port + '/' + protocol + '\\s';` ], [ /require\(['"]stream['"]\)/g , 'require(\'../\')' ], [ /^var util = require\('util'\);/m , '\n/**/\nvar util = require(\'core-util-is\');\n' + 'util.inherits = require(\'inherits\');\n/**/\n' ], [ /^const util = require\('util'\);/m , '\n/**/\nvar util = require(\'core-util-is\');\n' + 'util.inherits = require(\'inherits\');\n/**/\n' ] , [ /process\.binding\('timer_wrap'\)\.Timer;/, '{now: function (){}}' ], [ /(exports\.enoughTestCpu[^;]+;)/, '/*$1*/' ], [ /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\');' ] ] // this test has some trouble with the nextTick depth when run // to stdout, it's also very noisy so we'll quiet it module.exports['test-stream-pipe-multi.js'] = [ altForEachImplReplacement , altForEachUseReplacement , [ /console\.error/g , '//console.error' ] , [ /process\.nextTick/g , 'setImmediate' ] ] // just noisy module.exports['test-stream2-large-read-stall.js'] = [ [ /console\.error/g , ';false && console.error' ] ] module.exports['test-stream-pipe-cleanup.js'] = [ [ /(function Writable\(\) \{)/ , '(function (){\nif (/^v0\\.8\\./.test(process.version))\n return\n\n$1' ] , [ /$/ ,'}())' ] ] module.exports['test-stream2-stderr-sync.js'] = [ altForEachImplReplacement , altForEachUseReplacement , [ // 'tty_wrap' is too different across node versions. // this bypasses it and replicates a console.error() test /(function child0\(\) \{)/ , '$1\n' + ' return console.error(\'child 0\\nfoo\\nbar\\nbaz\');\n' ] ] module.exports['test-stream-unshift-read-race.js'] = [ [ /data\.slice\(pos, pos \+ n\)/g, 'data.slice(pos, Math.min(pos + n, data.length))' ] ] module.exports['test-stream-pipe-without-listenerCount.js'] = [ [ /require\(\'stream\'\)/g, 'stream' ] ] module.exports['test-stream2-readable-empty-buffer-no-eof.js'] = [ [ `const buf = Buffer(5).fill('x');`, `const buf = new Buffer(5); buf.fill('x');` ] ] module.exports['test-stream2-unpipe-drain.js'] = [ [ /^/, `(function () {\n` ], [ /$/ ,'}())' ] ] module.exports['test-stream2-decode-partial.js'] = [ [ /readable\.push\(source\.slice\(4, 6\)\)/ ,`readable.push(source.slice(4, source.length));` ] ] module.exports['test-stream3-cork-uncork.js'] = module.exports['test-stream3-cork-end.js'] = [ [ /assert\.ok\(seen\.equals\(expected\)\);/, 'assert.deepEqual(seen, expected);' ] ] module.exports['test-stream2-readable-from-list.js'] = [ [ /require\('internal\/streams\/BufferList'\)/, 'require(\'../../lib/internal/streams/BufferList\')' ] ] module.exports['test-stream-writev.js'] = [ [ /'latin1'/g, `'binary'` ] ] module.exports['test-stream2-readable-empty-buffer-no-eof.js'] = [ [ /case 3:\n(\s+)setImmediate\(r\.read\.bind\(r, 0\)\);/, 'case 3:\n$1setTimeout(r.read.bind(r, 0), 50);' ] ] module.exports['test-stream-buffer-list.js'] = [ [ /require\('internal\/streams\/BufferList'\);/, 'require(\'../../lib/internal/streams/BufferList\');' ] ] module.exports['test-stream-transform-constructor-set-methods.js'] = [ [ /Error: _transform\\\(\\\) is n/, 'Error: .*[Nn]' ] ] module.exports['test-stream-unpipe-event.js'] = [ [ /^/, 'if (process.version.indexOf(\'v0.8\') === 0) { process.exit(0) }\n' ] ] readable-stream-2.3.3/doc/000077500000000000000000000000001312520600100153025ustar00rootroot00000000000000readable-stream-2.3.3/doc/wg-meetings/000077500000000000000000000000001312520600100175305ustar00rootroot00000000000000readable-stream-2.3.3/doc/wg-meetings/2015-01-30.md000066400000000000000000000043501312520600100211010ustar00rootroot00000000000000# streams WG Meeting 2015-01-30 ## Links * **Google Hangouts Video**: http://www.youtube.com/watch?v=I9nDOSGfwZg * **GitHub Issue**: https://github.com/iojs/readable-stream/issues/106 * **Original Minutes Google Doc**: https://docs.google.com/document/d/17aTgLnjMXIrfjgNaTUnHQO7m3xgzHR2VXBTmi03Qii4/ ## Agenda Extracted from https://github.com/iojs/readable-stream/labels/wg-agenda prior to meeting. * adopt a charter [#105](https://github.com/iojs/readable-stream/issues/105) * release and versioning strategy [#101](https://github.com/iojs/readable-stream/issues/101) * simpler stream creation [#102](https://github.com/iojs/readable-stream/issues/102) * proposal: deprecate implicit flowing of streams [#99](https://github.com/iojs/readable-stream/issues/99) ## Minutes ### adopt a charter * group: +1's all around ### What versioning scheme should be adopted? * group: +1’s 3.0.0 * domenic+group: pulling in patches from other sources where appropriate * mikeal: version independently, suggesting versions for io.js * mikeal+domenic: work with TC to notify in advance of changes simpler stream creation ### streamline creation of streams * sam: streamline creation of streams * domenic: nice simple solution posted but, we lose the opportunity to change the model may not be backwards incompatible (double check keys) **action item:** domenic will check ### remove implicit flowing of streams on(‘data’) * add isFlowing / isPaused * mikeal: worrying that we’re documenting polyfill methods – confuses users * domenic: more reflective API is probably good, with warning labels for users * new section for mad scientists (reflective stream access) * calvin: name the “third state” * mikeal: maybe borrow the name from whatwg? * domenic: we’re missing the “third state” * consensus: kind of difficult to name the third state * mikeal: figure out differences in states / compat * mathias: always flow on data – eliminates third state * explore what it breaks **action items:** * ask isaac for ability to list packages by what public io.js APIs they use (esp. Stream) * ask rod/build for infrastructure * **chris**: explore the “flow on data” approach * add isPaused/isFlowing * add new docs section * move isPaused to that section readable-stream-2.3.3/duplex-browser.js000066400000000000000000000000651312520600100200560ustar00rootroot00000000000000module.exports = require('./lib/_stream_duplex.js'); readable-stream-2.3.3/duplex.js000066400000000000000000000000561312520600100163750ustar00rootroot00000000000000module.exports = require('./readable').Duplex readable-stream-2.3.3/examples/000077500000000000000000000000001312520600100163535ustar00rootroot00000000000000readable-stream-2.3.3/examples/CAPSLOCKTYPER.JS000066400000000000000000000013361312520600100206370ustar00rootroot00000000000000var Transform = require('../transform'); var inherits = require('util').inherits; // subclass function MyStream () { Transform.call(this, { lowWaterMark: 0, encoding: 'utf8' }); } inherits(MyStream, Transform); MyStream.prototype._transform = function (chunk, outputFn, callback) { outputFn(new Buffer(String(chunk).toUpperCase())); callback(); }; // use it! var s = new MyStream(); process.stdin.resume(); process.stdin.pipe(s).pipe(process.stdout); if (process.stdin.setRawMode) process.stdin.setRawMode(true); process.stdin.on('data', function (c) { c = c.toString(); if (c === '\u0003' || c === '\u0004') { process.stdin.pause(); s.end(); } if (c === '\r') process.stdout.write('\n'); }); readable-stream-2.3.3/examples/typer.js000066400000000000000000000006231312520600100200550ustar00rootroot00000000000000var fs = require('fs'); var fst = fs.createReadStream(__filename); var Readable = require('../readable.js'); var rst = new Readable(); rst.wrap(fst); rst.on('end', function() { process.stdin.pause(); }); process.stdin.setRawMode(true); process.stdin.on('data', function() { var c = rst.read(3); if (!c) return setTimeout(process.exit, 500) process.stdout.write(c); }); process.stdin.resume(); readable-stream-2.3.3/lib/000077500000000000000000000000001312520600100153035ustar00rootroot00000000000000readable-stream-2.3.3/lib/_stream_duplex.js000066400000000000000000000072361312520600100206640ustar00rootroot00000000000000// 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 // Writable. 'use strict'; /**/ var processNextTick = require('process-nextick-args'); /**/ /**/ var objectKeys = Object.keys || function (obj) { var keys = []; for (var key in obj) { keys.push(key); }return keys; }; /**/ module.exports = Duplex; /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ var Readable = require('./_stream_readable'); var Writable = require('./_stream_writable'); util.inherits(Duplex, Readable); var keys = objectKeys(Writable.prototype); for (var v = 0; v < keys.length; v++) { var method = keys[v]; if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; } function Duplex(options) { if (!(this instanceof Duplex)) return new Duplex(options); Readable.call(this, options); Writable.call(this, options); if (options && options.readable === false) this.readable = false; if (options && options.writable === false) this.writable = false; this.allowHalfOpen = true; if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; this.once('end', onend); } // the no-half-open enforcer function onend() { // if we allow half-open state, or if the writable side ended, // then we're ok. if (this.allowHalfOpen || this._writableState.ended) return; // no more data can be written. // But allow more writes to happen in this tick. processNextTick(onEndNT, this); } 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); } }readable-stream-2.3.3/lib/_stream_passthrough.js000066400000000000000000000033121312520600100217210ustar00rootroot00000000000000// 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. 'use strict'; module.exports = PassThrough; var Transform = require('./_stream_transform'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ util.inherits(PassThrough, Transform); function PassThrough(options) { if (!(this instanceof PassThrough)) return new PassThrough(options); Transform.call(this, options); } PassThrough.prototype._transform = function (chunk, encoding, cb) { cb(null, chunk); };readable-stream-2.3.3/lib/_stream_readable.js000066400000000000000000000740701312520600100211220ustar00rootroot00000000000000// 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. 'use strict'; /**/ var processNextTick = require('process-nextick-args'); /**/ module.exports = Readable; /**/ var isArray = require('isarray'); /**/ /**/ var Duplex; /**/ Readable.ReadableState = ReadableState; /**/ var EE = require('events').EventEmitter; var EElistenerCount = function (emitter, type) { return emitter.listeners(type).length; }; /**/ /**/ var Stream = require('./internal/streams/stream'); /**/ // TODO(bmeurer): Change this back to const once hole checks are // properly optimized away early in Ignition+TurboFan. /**/ var Buffer = require('safe-buffer').Buffer; var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } /**/ /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ /**/ var debugUtil = require('util'); var debug = void 0; if (debugUtil && debugUtil.debuglog) { debug = debugUtil.debuglog('stream'); } else { debug = function () {}; } /**/ var BufferList = require('./internal/streams/BufferList'); var destroyImpl = require('./internal/streams/destroy'); var StringDecoder; util.inherits(Readable, Stream); var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; function prependListener(emitter, event, fn) { // Sadly this is not cacheable as some libraries bundle their own // event emitter implementation with them. if (typeof emitter.prependListener === 'function') { return emitter.prependListener(event, fn); } else { // This is a hack to make sure that our error handler is attached before any // userland ones. NEVER DO THIS. This is here only because this code needs // to continue to work with older versions of Node.js that do not include // the prependListener() method. The goal is to eventually remove this hack. if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; } } function ReadableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); options = options || {}; // object stream flag. Used to make read(n) ignore n and to // make all the buffer merging and length checks go away this.objectMode = !!options.objectMode; if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" var hwm = options.highWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. 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 // array.shift() this.buffer = new BufferList(); this.length = 0; this.pipes = null; this.pipesCount = 0; this.flowing = null; this.ended = false; this.endEmitted = false; this.reading = false; // 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 // that we're awaiting a 'readable' event emission. this.needReadable = false; this.emittedReadable = false; 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'; // the number of writers that are awaiting a drain event in .pipe()s this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled this.readingMore = false; this.decoder = null; this.encoding = null; if (options.encoding) { if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; this.decoder = new StringDecoder(options.encoding); this.encoding = options.encoding; } } function Readable(options) { Duplex = Duplex || require('./_stream_duplex'); if (!(this instanceof Readable)) return new Readable(options); this._readableState = new ReadableState(options, this); // legacy this.readable = true; 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; 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, chunk, encoding, false, skipChunkCheck); }; // Unshift should *always* be something directly out of read() Readable.prototype.unshift = function (chunk) { return readableAddChunk(this, chunk, null, true, false); }; function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { var state = stream._readableState; if (chunk === null) { state.reading = false; onEofChunk(stream, state); } 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' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { chunk = _uint8ArrayToBuffer(chunk); } 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 { addChunk(stream, state, chunk, 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, // such as the repl. Also, if the push() triggered a // readable event, and the user called read(largeNumber) such that // needReadable was set, then we ought to push more, so that another // 'readable' event will be triggered. 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; this._readableState.decoder = new StringDecoder(enc); this._readableState.encoding = enc; return this; }; // Don't raise the hwm > 8MB var MAX_HWM = 0x800000; function computeNewHighWaterMark(n) { if (n >= MAX_HWM) { n = MAX_HWM; } else { // Get the next highest power of 2 to prevent increasing hwm excessively in // tiny amounts n--; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; n++; } return n; } // This function is designed to be inlinable, so please take care when making // changes to the function body. function howMuchToRead(n, state) { if (n <= 0 || state.length === 0 && state.ended) return 0; if (state.objectMode) return 1; if (n !== n) { // Only flow one buffer at a time if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; } // If we're asking for more than the current hwm, then raise the hwm. if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); if (n <= state.length) return n; // Don't have enough if (!state.ended) { state.needReadable = true; return 0; } return state.length; } // you can override either this method, or the async _read(n) below. Readable.prototype.read = function (n) { debug('read', n); n = parseInt(n, 10); var state = this._readableState; var nOrig = n; if (n !== 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we // already have a bunch of data in the buffer, then just trigger // the 'readable' event and move on. if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { debug('read: emitReadable', state.length, state.ended); if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); return null; } n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up. if (n === 0 && state.ended) { if (state.length === 0) endReadable(this); return null; } // All the actual chunk generation logic needs to be // *below* the call to _read. The reason is that in certain // synthetic stream cases, such as passthrough streams, _read // may be a completely synchronous operation which may change // the state of the read buffer, providing enough data when // before there was *not* enough. // // So, the steps are: // 1. Figure out what the state of things will be after we do // a read from the buffer. // // 2. If that resulting state will trigger a _read, then call _read. // Note that this may be asynchronous, or synchronous. Yes, it is // deeply ugly to write APIs this way, but that still doesn't mean // that the Readable class should behave improperly, as streams are // designed to be sync/async agnostic. // Take note if the _read call is sync or async (ie, if the read call // has returned yet), so that we know whether or not it's safe to emit // 'readable' etc. // // 3. Actually pull the requested chunks out of the buffer and return. // if we need a readable event, then we need to do some reading. var doRead = state.needReadable; debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some if (state.length === 0 || state.length - n < state.highWaterMark) { doRead = true; debug('length less than watermark', doRead); } // however, if we've ended, then there's no point, and if we're already // reading, then it's unnecessary. if (state.ended || state.reading) { doRead = false; debug('reading or ended', doRead); } else if (doRead) { debug('do read'); state.reading = true; state.sync = true; // if the length is currently zero, then we *need* a readable event. if (state.length === 0) state.needReadable = true; // call internal read method this._read(state.highWaterMark); state.sync = false; // If _read pushed data synchronously, then `reading` will be false, // and we need to re-evaluate how much data we can return to the user. if (!state.reading) n = howMuchToRead(nOrig, state); } var ret; if (n > 0) ret = fromList(n, state);else ret = null; if (ret === null) { state.needReadable = true; n = 0; } else { state.length -= n; } if (state.length === 0) { // If we have nothing in the buffer, then we want to know // as soon as we *do* get something into the buffer. if (!state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick. if (nOrig !== n && state.ended) endReadable(this); } if (ret !== null) this.emit('data', ret); return ret; }; function onEofChunk(stream, state) { if (state.ended) return; if (state.decoder) { var chunk = state.decoder.end(); if (chunk && chunk.length) { state.buffer.push(chunk); state.length += state.objectMode ? 1 : chunk.length; } } state.ended = true; // emit 'readable' now to make sure it gets picked up. emitReadable(stream); } // Don't emit readable right away in sync mode, because this can trigger // another read() call => stack overflow. This way, it might trigger // a nextTick recursion warning, but that's not so bad. function emitReadable(stream) { var state = stream._readableState; state.needReadable = false; if (!state.emittedReadable) { debug('emitReadable', state.flowing); state.emittedReadable = true; if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); } } function emitReadable_(stream) { debug('emit readable'); stream.emit('readable'); flow(stream); } // at this point, the user has presumably seen the 'readable' event, // and called read() to consume some data. that may have triggered // in turn another _read(n) call, in which case reading = true if // it's in progress. // However, if we're not ended, or reading, and the length < hwm, // then go ahead and try to read some more preemptively. function maybeReadMore(stream, state) { if (!state.readingMore) { state.readingMore = true; processNextTick(maybeReadMore_, stream, state); } } function maybeReadMore_(stream, state) { var len = state.length; while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { debug('maybeReadMore read 0'); stream.read(0); if (len === state.length) // didn't get any data, stop spinning. break;else len = state.length; } state.readingMore = false; } // abstract method. to be overridden in specific implementation classes. // call cb(er, data) where data is <= n in length. // for virtual (non-string, non-buffer) streams, "length" is somewhat // arbitrary, and perhaps not very meaningful. Readable.prototype._read = function (n) { this.emit('error', new Error('_read() is not implemented')); }; Readable.prototype.pipe = function (dest, pipeOpts) { var src = this; var state = this._readableState; switch (state.pipesCount) { case 0: state.pipes = dest; break; case 1: state.pipes = [state.pipes, dest]; break; default: state.pipes.push(dest); break; } state.pipesCount += 1; debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; var endFn = doEnd ? onend : unpipe; if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); function onunpipe(readable, unpipeInfo) { debug('onunpipe'); if (readable === src) { if (unpipeInfo && unpipeInfo.hasUnpiped === false) { unpipeInfo.hasUnpiped = true; cleanup(); } } } function onend() { debug('onend'); dest.end(); } // when the dest drains, it reduces the awaitDrain counter // on the source. This would be more elegant with a .once() // handler in flow(), but adding and removing repeatedly is // too slow. var ondrain = pipeOnDrain(src); dest.on('drain', ondrain); var cleanedUp = false; function cleanup() { debug('cleanup'); // cleanup event handlers once the pipe is broken dest.removeListener('close', onclose); dest.removeListener('finish', onfinish); dest.removeListener('drain', ondrain); dest.removeListener('error', onerror); dest.removeListener('unpipe', onunpipe); src.removeListener('end', onend); src.removeListener('end', unpipe); src.removeListener('data', ondata); cleanedUp = true; // if the reader is waiting for a drain event from this // specific writer, then it would cause it to never start // flowing again. // So, if this is awaiting a drain, then we just call it now. // If we don't know, then assume that we are waiting for one. if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); } // If the user pushes more data while we're writing to dest then we'll end up // in ondata again. However, we only want to increase awaitDrain once because // dest will only emit one 'drain' event for the multiple writes. // => Introduce a guard on increasing awaitDrain. var increasedAwaitDrain = false; src.on('data', ondata); function ondata(chunk) { debug('ondata'); increasedAwaitDrain = false; var ret = dest.write(chunk); if (false === ret && !increasedAwaitDrain) { // If the user unpiped during `dest.write()`, it is possible // to get stuck in a permanently paused state if that write // also returned false. // => Check whether `dest` is still a piping destination. if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { debug('false write response, pause', src._readableState.awaitDrain); src._readableState.awaitDrain++; increasedAwaitDrain = true; } src.pause(); } } // if the dest has an error, then stop piping into it. // however, don't suppress the throwing behavior for this. function onerror(er) { debug('onerror', er); unpipe(); dest.removeListener('error', onerror); if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); } // Make sure our error handler is attached before userland ones. prependListener(dest, 'error', onerror); // Both close and finish should trigger unpipe, but only once. function onclose() { dest.removeListener('finish', onfinish); unpipe(); } dest.once('close', onclose); function onfinish() { debug('onfinish'); dest.removeListener('close', onclose); unpipe(); } dest.once('finish', onfinish); function unpipe() { debug('unpipe'); src.unpipe(dest); } // tell the dest that it's being piped to dest.emit('pipe', src); // start the flow if it hasn't been started already. if (!state.flowing) { debug('pipe resume'); src.resume(); } return dest; }; function pipeOnDrain(src) { return function () { var state = src._readableState; debug('pipeOnDrain', state.awaitDrain); if (state.awaitDrain) state.awaitDrain--; if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { state.flowing = true; flow(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; // just one destination. most common case. if (state.pipesCount === 1) { // passed in one, but it's not the right one. if (dest && dest !== state.pipes) return this; if (!dest) dest = state.pipes; // got a match. state.pipes = null; state.pipesCount = 0; state.flowing = false; if (dest) dest.emit('unpipe', this, unpipeInfo); return this; } // slow case. multiple pipe destinations. if (!dest) { // remove all. var dests = state.pipes; var len = state.pipesCount; state.pipes = null; state.pipesCount = 0; state.flowing = false; for (var i = 0; i < len; i++) { dests[i].emit('unpipe', this, unpipeInfo); }return this; } // try to find the right one. var index = indexOf(state.pipes, dest); if (index === -1) return this; state.pipes.splice(index, 1); state.pipesCount -= 1; if (state.pipesCount === 1) state.pipes = state.pipes[0]; dest.emit('unpipe', this, unpipeInfo); return this; }; // set up data events if they are asked for // Ensure readable listeners eventually get something Readable.prototype.on = function (ev, fn) { var res = Stream.prototype.on.call(this, ev, fn); if (ev === 'data') { // Start flowing on next tick if stream isn't explicitly paused if (this._readableState.flowing !== false) this.resume(); } else if (ev === 'readable') { var state = this._readableState; if (!state.endEmitted && !state.readableListening) { state.readableListening = state.needReadable = true; state.emittedReadable = false; if (!state.reading) { processNextTick(nReadingNextTick, this); } else if (state.length) { emitReadable(this); } } } return res; }; Readable.prototype.addListener = Readable.prototype.on; function nReadingNextTick(self) { debug('readable nexttick read 0'); self.read(0); } // pause() and resume() are remnants of the legacy readable stream API // If the user uses them, then switch into old mode. Readable.prototype.resume = function () { var state = this._readableState; if (!state.flowing) { debug('resume'); state.flowing = true; resume(this, state); } return this; }; function resume(stream, state) { if (!state.resumeScheduled) { state.resumeScheduled = true; processNextTick(resume_, stream, state); } } function resume_(stream, state) { if (!state.reading) { debug('resume read 0'); stream.read(0); } state.resumeScheduled = false; state.awaitDrain = 0; stream.emit('resume'); flow(stream); if (state.flowing && !state.reading) stream.read(0); } Readable.prototype.pause = function () { debug('call pause flowing=%j', this._readableState.flowing); if (false !== this._readableState.flowing) { debug('pause'); this._readableState.flowing = false; this.emit('pause'); } return this; }; function flow(stream) { var state = stream._readableState; debug('flow', state.flowing); while (state.flowing && stream.read() !== null) {} } // wrap an old-style stream as the async data source. // This is *not* part of the readable stream interface. // It is an ugly unfortunate mess of history. Readable.prototype.wrap = function (stream) { var state = this._readableState; var paused = false; var self = this; stream.on('end', function () { debug('wrapped end'); if (state.decoder && !state.ended) { var chunk = state.decoder.end(); if (chunk && chunk.length) self.push(chunk); } self.push(null); }); stream.on('data', function (chunk) { debug('wrapped data'); if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; var ret = self.push(chunk); if (!ret) { paused = true; stream.pause(); } }); // proxy all the other methods. // important when wrapping filters and duplexes. for (var i in stream) { if (this[i] === undefined && typeof stream[i] === 'function') { this[i] = function (method) { return function () { return stream[method].apply(stream, arguments); }; }(i); } } // proxy certain important events. for (var n = 0; n < kProxyEvents.length; n++) { stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); } // when we try to consume some more bytes, simply unpause the // underlying stream. self._read = function (n) { debug('wrapped _read', n); if (paused) { paused = false; stream.resume(); } }; return self; }; // exposed for testing purposes only. Readable._fromList = fromList; // Pluck off n bytes from an array of buffers. // Length is the combined lengths of all the buffers in the list. // This function is designed to be inlinable, so please take care when making // changes to the function body. function fromList(n, state) { // nothing buffered if (state.length === 0) return null; var ret; if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { // read it all, truncate the list if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); state.buffer.clear(); } else { // read part of list ret = fromListPartial(n, state.buffer, state.decoder); } return ret; } // Extracts only enough buffered data to satisfy the amount requested. // This function is designed to be inlinable, so please take care when making // changes to the function body. function fromListPartial(n, list, hasStrings) { var ret; if (n < list.head.data.length) { // slice is the same for buffers and strings ret = list.head.data.slice(0, n); list.head.data = list.head.data.slice(n); } else if (n === list.head.data.length) { // first chunk is a perfect match ret = list.shift(); } else { // result spans more than one buffer ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); } return ret; } // Copies a specified amount of characters from the list of buffered data // chunks. // This function is designed to be inlinable, so please take care when making // changes to the function body. function copyFromBufferString(n, list) { var p = list.head; var c = 1; var ret = p.data; n -= ret.length; while (p = p.next) { var str = p.data; var nb = n > str.length ? str.length : n; if (nb === str.length) ret += str;else ret += str.slice(0, n); n -= nb; if (n === 0) { if (nb === str.length) { ++c; if (p.next) list.head = p.next;else list.head = list.tail = null; } else { list.head = p; p.data = str.slice(nb); } break; } ++c; } list.length -= c; return ret; } // Copies a specified amount of bytes from the list of buffered data chunks. // This function is designed to be inlinable, so please take care when making // changes to the function body. function copyFromBuffer(n, list) { var ret = Buffer.allocUnsafe(n); var p = list.head; var c = 1; p.data.copy(ret); n -= p.data.length; while (p = p.next) { var buf = p.data; var nb = n > buf.length ? buf.length : n; buf.copy(ret, ret.length - n, 0, nb); n -= nb; if (n === 0) { if (nb === buf.length) { ++c; if (p.next) list.head = p.next;else list.head = list.tail = null; } else { list.head = p; p.data = buf.slice(nb); } break; } ++c; } list.length -= c; return ret; } function endReadable(stream) { var state = stream._readableState; // If we get here before consuming all the bytes, then that is a // bug in node. Should never happen. if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); if (!state.endEmitted) { state.ended = true; processNextTick(endReadableNT, state, stream); } } function endReadableNT(state, stream) { // Check that we didn't get one last unshift. if (!state.endEmitted && state.length === 0) { state.endEmitted = true; stream.readable = false; stream.emit('end'); } } function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } function indexOf(xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; } return -1; }readable-stream-2.3.3/lib/_stream_transform.js000066400000000000000000000171521312520600100213740ustar00rootroot00000000000000// 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 // some bits pass through, and others are simply ignored. (That would // be a valid example of a transform, of course.) // // While the output is causally related to the input, it's not a // necessarily symmetric or synchronous transformation. For example, // a zlib stream might take multiple plain-text writes(), and then // emit a single compressed chunk some time in the future. // // Here's how this works: // // The Transform stream has all the aspects of the readable and writable // stream classes. When you write(chunk), that calls _write(chunk,cb) // internally, and returns false if there's a lot of pending writes // buffered up. When you call read(), that calls _read(n) until // there's enough pending readable data buffered up. // // In a transform stream, the written data is placed in a buffer. When // _read(n) is called, it transforms the queued up data, calling the // buffered _write cb's as it consumes chunks. If consuming a single // written chunk would result in multiple output chunks, then the first // outputted bit calls the readcb, and subsequent chunks just go into // the read buffer, and will cause it to emit 'readable' if necessary. // // This way, back-pressure is actually determined by the reading side, // since _read has to be called to start processing a new chunk. However, // a pathological inflate type of transform can cause excessive buffering // here. For example, imagine a stream where every byte of input is // interpreted as an integer from 0-255, and then results in that many // bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in // 1kb of data being output. In this case, you could write a very small // amount of input, and end up with a very large amount of output. In // such a pathological inflating mechanism, there'd be no way to tell // the system to stop doing the transform. A single 4MB write could // cause the system to run out of memory. // // However, even in such a pathological case, only a single written chunk // would be consumed, and then the rest would wait (un-transformed) until // the results of the previous transformed chunk were consumed. 'use strict'; module.exports = Transform; var Duplex = require('./_stream_duplex'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ util.inherits(Transform, Duplex); function TransformState(stream) { this.afterTransform = function (er, data) { return afterTransform(stream, er, data); }; this.needTransform = false; this.transforming = false; this.writecb = null; this.writechunk = null; this.writeencoding = null; } function afterTransform(stream, er, data) { var ts = stream._transformState; ts.transforming = false; var cb = ts.writecb; if (!cb) { return stream.emit('error', new Error('write callback called multiple times')); } ts.writechunk = null; ts.writecb = null; if (data !== null && data !== undefined) stream.push(data); cb(er); var rs = stream._readableState; rs.reading = false; if (rs.needReadable || rs.length < rs.highWaterMark) { stream._read(rs.highWaterMark); } } function Transform(options) { if (!(this instanceof Transform)) return new Transform(options); Duplex.call(this, options); this._transformState = new TransformState(this); var stream = this; // start out asking for a readable event once data is transformed. this._readableState.needReadable = true; // we have implemented the _read method, and done the other things // that Readable wants before the first _read call, so unset the // sync guard flag. this._readableState.sync = false; if (options) { if (typeof options.transform === 'function') this._transform = options.transform; if (typeof options.flush === 'function') this._flush = options.flush; } // When the writable side finishes, then flush out anything remaining. this.once('prefinish', function () { if (typeof this._flush === 'function') this._flush(function (er, data) { done(stream, er, data); });else done(stream); }); } Transform.prototype.push = function (chunk, encoding) { this._transformState.needTransform = false; return Duplex.prototype.push.call(this, chunk, encoding); }; // This is the part where you do stuff! // override this function in implementation classes. // 'chunk' is an input chunk. // // Call `push(newChunk)` to pass along transformed output // to the readable side. You may call 'push' zero or more times. // // Call `cb(err)` when you are done with this chunk. If you pass // an error, then that'll put the hurt on the whole operation. If you // never call cb(), then you'll never get another chunk. Transform.prototype._transform = function (chunk, encoding, cb) { throw new Error('_transform() is not implemented'); }; Transform.prototype._write = function (chunk, encoding, cb) { var ts = this._transformState; ts.writecb = cb; ts.writechunk = chunk; ts.writeencoding = encoding; if (!ts.transforming) { var rs = this._readableState; if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); } }; // Doesn't matter what the args are here. // _transform does all the work. // That we got here means that the readable side wants more data. Transform.prototype._read = function (n) { var ts = this._transformState; if (ts.writechunk !== null && ts.writecb && !ts.transforming) { ts.transforming = true; this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); } else { // mark that we need a transform, so that any data that comes in // will get processed, now that we've asked for it. ts.needTransform = true; } }; 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); if (data !== null && data !== undefined) stream.push(data); // if there's nothing in the write buffer, then that means // that nothing more will ever be provided var ws = stream._writableState; var ts = stream._transformState; if (ws.length) throw new Error('Calling transform done when ws.length != 0'); if (ts.transforming) throw new Error('Calling transform done when still transforming'); return stream.push(null); }readable-stream-2.3.3/lib/_stream_writable.js000066400000000000000000000457711312520600100212020ustar00rootroot00000000000000// 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'; /**/ var processNextTick = require('process-nextick-args'); /**/ module.exports = Writable; /* */ function WriteReq(chunk, encoding, cb) { this.chunk = chunk; this.encoding = encoding; this.callback = cb; this.next = null; } // 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; this.next = null; this.entry = null; this.finish = function () { onCorkedFinish(_this, state); }; } /* */ /**/ var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; /**/ /**/ var Duplex; /**/ Writable.WritableState = WritableState; /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ /**/ var internalUtil = { deprecate: require('util-deprecate') }; /**/ /**/ var Stream = require('./internal/streams/stream'); /**/ /**/ var Buffer = require('safe-buffer').Buffer; var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } /**/ var destroyImpl = require('./internal/streams/destroy'); util.inherits(Writable, Stream); function nop() {} function WritableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); options = options || {}; // object stream flag to indicate whether or not this stream // contains buffers or objects. this.objectMode = !!options.objectMode; if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write() var hwm = options.highWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. this.highWaterMark = Math.floor(this.highWaterMark); // if _final has been called this.finalCalled = false; // drain event flag. this.needDrain = false; // at the start of calling end() this.ending = false; // when end() has been called, and returned this.ended = false; // 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. var noDecode = options.decodeStrings === false; this.decodeStrings = !noDecode; // 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'; // not an actual buffer we keep track of, but a measurement // of how much we're waiting to get pushed to some underlying // socket or file. this.length = 0; // a flag to see when we're in the middle of a write. this.writing = false; // when true all writes will be buffered until .uncork() call this.corked = 0; // 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. this.sync = true; // a flag to know if we're processing previously buffered items, which // may call the _write() callback in the same tick, so that we don't // end up in an overlapped onwrite situation. this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb) this.onwrite = function (er) { onwrite(stream, er); }; // the callback that the user supplies to write(chunk,encoding,cb) this.writecb = null; // the amount that is being written when _write is called. this.writelen = 0; this.bufferedRequest = null; this.lastBufferedRequest = null; // number of pending user-supplied write callbacks // this must be 0 before 'finish' can be emitted this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs // This is relevant for synchronous Transform streams this.prefinished = false; // True if the error was already emitted and should not be thrown again this.errorEmitted = false; // count buffered requests this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always // one allocated and free to use, and we maintain at most two this.corkedRequestsFree = new CorkedRequest(this); } WritableState.prototype.getBuffer = function getBuffer() { var current = this.bufferedRequest; var out = []; while (current) { out.push(current); current = current.next; } return out; }; (function () { try { Object.defineProperty(WritableState.prototype, 'buffer', { get: internalUtil.deprecate(function () { return this.getBuffer(); }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') }); } catch (_) {} })(); // Test _writableState for inheritance to account for Duplex streams, // whose prototype chain only points to Readable. var realHasInstance; if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { realHasInstance = Function.prototype[Symbol.hasInstance]; Object.defineProperty(Writable, Symbol.hasInstance, { value: function (object) { if (realHasInstance.call(this, object)) return true; return object && object._writableState instanceof WritableState; } }); } else { realHasInstance = function (object) { return object instanceof this; }; } function Writable(options) { Duplex = Duplex || require('./_stream_duplex'); // Writable ctor is applied to Duplexes, too. // `realHasInstance` is necessary because using plain `instanceof` // would return false, as no `_writableState` property is attached. // Trying to use the custom `instanceof` for Writable here will also break the // Node.js LazyTransform implementation, which has a non-trivial getter for // `_writableState` that would lead to infinite recursion. if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { return new Writable(options); } this._writableState = new WritableState(options, this); // legacy. this.writable = true; if (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); } // Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function () { this.emit('error', new Error('Cannot pipe, not readable')); }; function writeAfterEnd(stream, cb) { var er = new Error('write after end'); // TODO: defer error events consistently everywhere, not just the cb stream.emit('error', er); processNextTick(cb, er); } // Checks that a user-supplied chunk is valid, especially for the particular // mode the stream is in. Currently this means that `null` is never accepted // and undefined/non-string values are only allowed in object mode. function validChunk(stream, state, chunk, cb) { var valid = true; var er = false; if (chunk === null) { er = new TypeError('May not write null values to stream'); } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { er = new TypeError('Invalid non-string/buffer chunk'); } if (er) { stream.emit('error', er); processNextTick(cb, er); valid = false; } return valid; } Writable.prototype.write = function (chunk, encoding, cb) { var state = this._writableState; var ret = false; var isBuf = _isUint8Array(chunk) && !state.objectMode; if (isBuf && !Buffer.isBuffer(chunk)) { chunk = _uint8ArrayToBuffer(chunk); } if (typeof encoding === 'function') { cb = encoding; encoding = null; } if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; if (typeof cb !== 'function') cb = nop; if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { state.pendingcb++; ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); } return ret; }; Writable.prototype.cork = function () { var state = this._writableState; state.corked++; }; Writable.prototype.uncork = function () { var state = this._writableState; if (state.corked) { state.corked--; if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); } }; Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { // node::ParseEncoding() requires lower case. if (typeof encoding === 'string') encoding = encoding.toLowerCase(); if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); this._writableState.defaultEncoding = encoding; return this; }; function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { chunk = Buffer.from(chunk, encoding); } return chunk; } // if we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { if (!isBuf) { var newChunk = decodeChunk(state, chunk, encoding); if (chunk !== newChunk) { isBuf = true; encoding = 'buffer'; chunk = newChunk; } } var len = state.objectMode ? 1 : chunk.length; state.length += len; var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false. if (!ret) state.needDrain = true; if (state.writing || state.corked) { var last = state.lastBufferedRequest; state.lastBufferedRequest = { chunk: chunk, encoding: encoding, isBuf: isBuf, callback: cb, next: null }; if (last) { last.next = state.lastBufferedRequest; } else { state.bufferedRequest = state.lastBufferedRequest; } state.bufferedRequestCount += 1; } else { doWrite(stream, state, false, len, chunk, encoding, cb); } return ret; } function doWrite(stream, state, writev, len, chunk, encoding, cb) { state.writelen = len; state.writecb = cb; state.writing = true; state.sync = true; if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); state.sync = false; } function onwriteError(stream, state, sync, er, cb) { --state.pendingcb; if (sync) { // defer the callback if we are being called synchronously // to avoid piling up things on the stack processNextTick(cb, er); // this can emit finish, and it will always happen // after error processNextTick(finishMaybe, stream, state); stream._writableState.errorEmitted = true; stream.emit('error', er); } else { // the caller expect this to happen before if // it is async cb(er); stream._writableState.errorEmitted = true; stream.emit('error', er); // this can emit finish, but finish must // always follow error finishMaybe(stream, state); } } function onwriteStateUpdate(state) { state.writing = false; state.writecb = null; state.length -= state.writelen; state.writelen = 0; } function onwrite(stream, er) { var state = stream._writableState; var sync = state.sync; var cb = state.writecb; onwriteStateUpdate(state); if (er) onwriteError(stream, state, sync, er, cb);else { // Check if we're actually ready to finish, but don't emit yet var finished = needFinish(state); if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { clearBuffer(stream, state); } if (sync) { /**/ asyncWrite(afterWrite, stream, state, finished, cb); /**/ } else { afterWrite(stream, state, finished, cb); } } } function afterWrite(stream, state, finished, cb) { if (!finished) onwriteDrain(stream, state); state.pendingcb--; cb(); finishMaybe(stream, state); } // Must force callback to be called on nextTick, so that we don't // emit 'drain' before the write() consumer gets the 'false' return // value, and has a chance to attach a 'drain' listener. function onwriteDrain(stream, state) { if (state.length === 0 && state.needDrain) { state.needDrain = false; stream.emit('drain'); } } // if there's something in the buffer waiting, then process it function clearBuffer(stream, state) { state.bufferProcessing = true; var entry = state.bufferedRequest; if (stream._writev && entry && entry.next) { // Fast case, write everything using _writev() var l = state.bufferedRequestCount; var buffer = new Array(l); var holder = state.corkedRequestsFree; 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); // doWrite is almost always async, defer these to save a bit of time // as the hot path ends with doWrite state.pendingcb++; state.lastBufferedRequest = null; if (holder.next) { state.corkedRequestsFree = holder.next; holder.next = null; } else { state.corkedRequestsFree = new CorkedRequest(state); } } else { // Slow case, write chunks one-by-one while (entry) { var chunk = entry.chunk; var encoding = entry.encoding; var cb = entry.callback; var len = state.objectMode ? 1 : chunk.length; doWrite(stream, state, false, len, chunk, encoding, cb); entry = entry.next; // if we didn't call the onwrite immediately, then // it means that we need to wait until it does. // also, that means that the chunk and cb are currently // being processed, so move the buffer counter past them. if (state.writing) { break; } } if (entry === null) state.lastBufferedRequest = null; } state.bufferedRequestCount = 0; state.bufferedRequest = entry; state.bufferProcessing = false; } Writable.prototype._write = function (chunk, encoding, cb) { cb(new Error('_write() is not implemented')); }; Writable.prototype._writev = null; Writable.prototype.end = function (chunk, encoding, cb) { var state = this._writableState; if (typeof chunk === 'function') { cb = chunk; chunk = null; encoding = null; } else if (typeof encoding === 'function') { cb = encoding; encoding = null; } if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); // .end() fully uncorks if (state.corked) { state.corked = 1; this.uncork(); } // ignore unnecessary end() calls. if (!state.ending && !state.finished) endWritable(this, state, cb); }; function needFinish(state) { return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; } 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) { state.finished = true; stream.emit('finish'); } } return need; } function endWritable(stream, state, cb) { state.ending = true; finishMaybe(stream, state); if (cb) { if (state.finished) processNextTick(cb);else stream.once('finish', cb); } state.ended = true; stream.writable = false; } 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; } } Object.defineProperty(Writable.prototype, 'destroyed', { get: function () { if (this._writableState === undefined) { return false; } return this._writableState.destroyed; }, set: function (value) { // we ignore the value if the stream // has not been initialized yet if (!this._writableState) { return; } // 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); };readable-stream-2.3.3/lib/internal/000077500000000000000000000000001312520600100171175ustar00rootroot00000000000000readable-stream-2.3.3/lib/internal/streams/000077500000000000000000000000001312520600100205755ustar00rootroot00000000000000readable-stream-2.3.3/lib/internal/streams/BufferList.js000066400000000000000000000034671312520600100232120ustar00rootroot00000000000000'use strict'; /**/ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Buffer = require('safe-buffer').Buffer; /**/ function copyBuffer(src, target, offset) { src.copy(target, offset); } module.exports = function () { function BufferList() { _classCallCheck(this, BufferList); this.head = null; this.tail = null; this.length = 0; } BufferList.prototype.push = 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; }; BufferList.prototype.unshift = function unshift(v) { var entry = { data: v, next: this.head }; if (this.length === 0) this.tail = entry; this.head = entry; ++this.length; }; BufferList.prototype.shift = 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; }; BufferList.prototype.clear = function clear() { this.head = this.tail = null; this.length = 0; }; BufferList.prototype.join = 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; }; BufferList.prototype.concat = 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; }; return BufferList; }();readable-stream-2.3.3/lib/internal/streams/destroy.js000066400000000000000000000034661312520600100226350ustar00rootroot00000000000000'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 };readable-stream-2.3.3/lib/internal/streams/stream-browser.js000066400000000000000000000000611312520600100241040ustar00rootroot00000000000000module.exports = require('events').EventEmitter; readable-stream-2.3.3/lib/internal/streams/stream.js000066400000000000000000000000441312520600100224240ustar00rootroot00000000000000module.exports = require('stream'); readable-stream-2.3.3/package.json000066400000000000000000000027751312520600100170360ustar00rootroot00000000000000{ "name": "readable-stream", "version": "2.3.3", "description": "Streams3, a user-land copy of the stream library from Node.js", "main": "readable.js", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~1.0.6", "safe-buffer": "~5.1.1", "string_decoder": "~1.0.3", "util-deprecate": "~1.0.1" }, "devDependencies": { "assert": "~1.4.0", "babel-polyfill": "^6.9.1", "buffer": "^4.9.0", "nyc": "^6.4.0", "tap": "~0.7.1", "tape": "~4.5.1", "zuul": "~3.10.0" }, "scripts": { "test": "tap test/parallel/*.js test/ours/*.js && node test/verify-dependencies.js", "browser": "npm run write-zuul && zuul --browser-retries 2 -- test/browser.js", "write-zuul": "printf \"ui: tape\nbrowsers:\n - name: $BROWSER_NAME\n version: $BROWSER_VERSION\n\">.zuul.yml", "local": "zuul --local 3000 --no-coverage -- test/browser.js", "cover": "nyc npm test", "report": "nyc report --reporter=lcov" }, "repository": { "type": "git", "url": "git://github.com/nodejs/readable-stream" }, "keywords": [ "readable", "stream", "pipe" ], "browser": { "util": false, "./readable.js": "./readable-browser.js", "./writable.js": "./writable-browser.js", "./duplex.js": "./duplex-browser.js", "./lib/internal/streams/stream.js": "./lib/internal/streams/stream-browser.js" }, "nyc": { "include": [ "lib/**.js" ] }, "license": "MIT" } readable-stream-2.3.3/passthrough.js000066400000000000000000000000631312520600100174410ustar00rootroot00000000000000module.exports = require('./readable').PassThrough readable-stream-2.3.3/readable-browser.js000066400000000000000000000005371312520600100203200ustar00rootroot00000000000000exports = module.exports = require('./lib/_stream_readable.js'); exports.Stream = exports; exports.Readable = exports; exports.Writable = require('./lib/_stream_writable.js'); exports.Duplex = require('./lib/_stream_duplex.js'); exports.Transform = require('./lib/_stream_transform.js'); exports.PassThrough = require('./lib/_stream_passthrough.js'); readable-stream-2.3.3/readable.js000066400000000000000000000014031312520600100166300ustar00rootroot00000000000000var Stream = require('stream'); if (process.env.READABLE_STREAM === 'disable' && Stream) { module.exports = Stream; exports = module.exports = Stream.Readable; exports.Readable = Stream.Readable; exports.Writable = Stream.Writable; exports.Duplex = Stream.Duplex; exports.Transform = Stream.Transform; exports.PassThrough = Stream.PassThrough; exports.Stream = Stream; } else { exports = module.exports = require('./lib/_stream_readable.js'); exports.Stream = Stream || exports; exports.Readable = exports; exports.Writable = require('./lib/_stream_writable.js'); exports.Duplex = require('./lib/_stream_duplex.js'); exports.Transform = require('./lib/_stream_transform.js'); exports.PassThrough = require('./lib/_stream_passthrough.js'); } readable-stream-2.3.3/test/000077500000000000000000000000001312520600100155145ustar00rootroot00000000000000readable-stream-2.3.3/test/browser.js000066400000000000000000000054651312520600100175470ustar00rootroot00000000000000if (!global.console) { global.console = {}; } if (!global.console.log) { global.console.log = function () {}; } if (!global.console.error) { global.console.error = global.console.log; } if (!global.console.info) { global.console.info = global.console.log; } var test = require('tape'); test('streams', function (t) { require('./browser/test-stream-big-packet')(t); require('./browser/test-stream-big-push')(t); require('./browser/test-stream-duplex')(t); require('./browser/test-stream-end-paused')(t); require('./browser/test-stream-ispaused')(t); require('./browser/test-stream-pipe-after-end')(t); require('./browser/test-stream-pipe-cleanup')(t); require('./browser/test-stream-pipe-cleanup-pause')(t); require('./browser/test-stream-pipe-error-handling')(t); require('./browser/test-stream-pipe-event')(t); require('./browser/test-stream-push-order')(t); require('./browser/test-stream-push-strings')(t); require('./browser/test-stream-readable-constructor-set-methods')(t); require('./browser/test-stream-readable-event')(t); require('./browser/test-stream-transform-constructor-set-methods')(t); require('./browser/test-stream-transform-objectmode-falsey-value')(t); require('./browser/test-stream-transform-split-objectmode')(t); require('./browser/test-stream-unshift-empty-chunk')(t); require('./browser/test-stream-unshift-read-race')(t); require('./browser/test-stream-writable-change-default-encoding')(t); require('./browser/test-stream-writable-constructor-set-methods')(t); require('./browser/test-stream-writable-decoded-encoding')(t); require('./browser/test-stream-writev')(t); require('./browser/test-stream-sync-write')(t); require('./browser/test-stream-pipe-without-listenerCount'); }); test('streams 2', function (t) { require('./browser/test-stream2-base64-single-char-read-end')(t); require('./browser/test-stream2-compatibility')(t); require('./browser/test-stream2-large-read-stall')(t); require('./browser/test-stream2-objects')(t); require('./browser/test-stream2-pipe-error-handling')(t); require('./browser/test-stream2-pipe-error-once-listener')(t); require('./browser/test-stream2-push')(t); require('./browser/test-stream2-readable-empty-buffer-no-eof')(t); require('./browser/test-stream2-readable-from-list')(t); require('./browser/test-stream2-transform')(t); require('./browser/test-stream2-set-encoding')(t); require('./browser/test-stream2-readable-legacy-drain')(t); require('./browser/test-stream2-readable-wrap-empty')(t); require('./browser/test-stream2-readable-non-empty-end')(t); require('./browser/test-stream2-readable-wrap')(t); require('./browser/test-stream2-unpipe-drain')(t); require('./browser/test-stream2-writable')(t); }); test('streams 3', function (t) { require('./browser/test-stream3-pause-then-read')(t); }); readable-stream-2.3.3/test/browser/000077500000000000000000000000001312520600100171775ustar00rootroot00000000000000readable-stream-2.3.3/test/browser/test-stream-big-packet.js000066400000000000000000000033161312520600100240140ustar00rootroot00000000000000'use strict'; var common = require('../common'); var inherits = require('inherits'); var stream = require('../../'); module.exports = function (t) { t.test('big packet', function (t) { t.plan(3); var passed = false; function PassThrough() { stream.Transform.call(this); }; inherits(PassThrough, stream.Transform); PassThrough.prototype._transform = function(chunk, encoding, done) { this.push(chunk); done(); }; function TestStream() { stream.Transform.call(this); }; 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; } if (passed) { t.ok(passed); } done(); }; var s1 = new PassThrough(); var s2 = new PassThrough(); var s3 = new TestStream(); s1.pipe(s3); // Don't let s2 auto close which may close s3 s2.pipe(s3, {end: false}); // We must write a buffer larger than highWaterMark var big = new Buffer(s1._writableState.highWaterMark + 1); big.fill('x'); // Since big is larger than highWaterMark, it will be buffered internally. t.ok(!s1.write(big)); // 'tiny' is small enough to pass through internal buffer. t.ok(s2.write('tiny')); // Write some small data in next IO loop, which will never be written to s3 // Because 'drain' event is not emitted from s1 and s1 is still paused setImmediate(s1.write.bind(s1), 'later'); function indexOf (xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; } return -1; } }); } readable-stream-2.3.3/test/browser/test-stream-big-push.js000066400000000000000000000030131312520600100235160ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); module.exports = function (t) { t.test('big push', function (t) { var str = 'asdfasdfasdfasdfasdf'; var r = new stream.Readable({ highWaterMark: 5, encoding: 'utf8' }); var reads = 0; var eofed = false; var ended = false; r._read = function(n) { if (reads === 0) { setTimeout(function() { r.push(str); }); reads++; } else if (reads === 1) { var ret = r.push(str); t.equal(ret, false); reads++; } else { t.notOk(eofed); eofed = true; r.push(null); } }; r.on('end', function() { ended = true; }); // push some data in to start. // we've never gotten any read event at this point. var ret = r.push(str); // should be false. > hwm t.notOk(ret); var chunk = r.read(); t.equal(chunk, str); chunk = r.read(); t.equal(chunk, null); r.once('readable', function() { // this time, we'll get *all* the remaining data, because // it's been added synchronously, as the read WOULD take // us below the hwm, and so it triggered a _read() again, // which synchronously added more, which we then return. chunk = r.read(); t.equal(chunk, str + str); chunk = r.read(); t.equal(chunk, null); }); r.on('end', function() { t.ok(eofed); t.ok(ended); t.equal(reads, 2); t.end(); }); }); } readable-stream-2.3.3/test/browser/test-stream-duplex.js000066400000000000000000000012651312520600100233100ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Duplex = require('../../').Transform; var stream = new Duplex({ objectMode: true }); module.exports = function (t) { t.test('duplex', function (t) { t.plan(4); t.ok(stream._readableState.objectMode); t.ok(stream._writableState.objectMode); var written; var read; stream._write = function(obj, _, cb) { written = obj; cb(); }; stream._read = function() {}; stream.on('data', function(obj) { read = obj; }); stream.push({ val: 1 }); stream.end({ val: 2 }); stream.on('end', function() { t.equal(read.val, 1); t.equal(written.val, 2); }); }); } readable-stream-2.3.3/test/browser/test-stream-end-paused.js000066400000000000000000000012431312520600100240300ustar00rootroot00000000000000'use strict'; var common = require('../common'); // Make sure we don't miss the end event for paused 0-length streams var Readable = require('../../').Readable; var stream = new Readable(); module.exports = function (t) { t.test('end pause', function (t) { t.plan(2); var calledRead = false; stream._read = function() { t.notOk(calledRead); calledRead = true; this.push(null); }; stream.on('data', function() { throw new Error('should not ever get data'); }); stream.pause(); setTimeout(function() { stream.on('end', function() { t.ok(calledRead); }); stream.resume(); }); }); } readable-stream-2.3.3/test/browser/test-stream-ispaused.js000066400000000000000000000011431312520600100236170ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); module.exports = function (t) { t.test('is paused', function (t) { var readable = new stream.Readable(); // _read is a noop, here. readable._read = Function(); // default state of a stream is not "paused" t.notOk(readable.isPaused()); // make the stream start flowing... readable.on('data', Function()); // still not paused. t.notOk(readable.isPaused()); readable.pause(); t.ok(readable.isPaused()); readable.resume(); t.notOk(readable.isPaused()); t.end(); }); } readable-stream-2.3.3/test/browser/test-stream-pipe-after-end.js000066400000000000000000000032721312520600100246070ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../lib/_stream_readable'); var Writable = require('../../lib/_stream_writable'); var inherits = require('inherits'); module.exports = function (t) { t.test('pipe after end', function (t) { t.plan(4); inherits(TestReadable, Readable); function TestReadable(opt) { if (!(this instanceof TestReadable)) return new TestReadable(opt); Readable.call(this, opt); this._ended = false; } TestReadable.prototype._read = function(n) { if (this._ended) this.emit('error', new Error('_read called twice')); this._ended = true; this.push(null); }; inherits(TestWritable, Writable); function TestWritable(opt) { if (!(this instanceof TestWritable)) return new TestWritable(opt); Writable.call(this, opt); this._written = []; } TestWritable.prototype._write = function(chunk, encoding, cb) { this._written.push(chunk); cb(); }; // this one should not emit 'end' until we read() from it later. var ender = new TestReadable(); var enderEnded = false; // what happens when you pipe() a Readable that's already ended? var piper = new TestReadable(); // pushes EOF null, and length=0, so this will trigger 'end' piper.read(); setTimeout(function() { ender.on('end', function() { enderEnded = true; t.ok(true, 'enderEnded'); }); t.notOk(enderEnded); var c = ender.read(); t.equal(c, null); var w = new TestWritable(); w.on('finish', function() { t.ok(true, 'writableFinished'); }); piper.pipe(w); }); }); } readable-stream-2.3.3/test/browser/test-stream-pipe-cleanup-pause.js000066400000000000000000000021451312520600100255020ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); module.exports = function (t) { t.test('pipe cleanup pause', function (t) { t.plan(3); var reader = new stream.Readable(); var writer1 = new stream.Writable(); var writer2 = new stream.Writable(); // 560000 is chosen here because it is larger than the (default) highWaterMark // and will cause `.write()` to return false // See: https://github.com/nodejs/node/issues/2323 var buffer = new Buffer(560000); reader._read = function() {}; writer1._write = common.mustCall(function(chunk, encoding, cb) { this.emit('chunk-received'); cb(); }, 1); writer1.once('chunk-received', function() { reader.unpipe(writer1); reader.pipe(writer2); reader.push(buffer); setImmediate(function() { reader.push(buffer); setImmediate(function() { reader.push(buffer); }); }); }); writer2._write = function(chunk, encoding, cb) { t.ok(true); cb(); }; reader.pipe(writer1); reader.push(buffer); }); }; readable-stream-2.3.3/test/browser/test-stream-pipe-cleanup.js000066400000000000000000000055251312520600100243740ustar00rootroot00000000000000'use strict'; // This test asserts that Stream.prototype.pipe does not leave listeners // hanging on the source or dest. var common = require('../common'); var stream = require('../../'); var inherits = require('inherits'); module.exports = function (t) { t.test('pipe cleanup', function (t) { if (/^v0\.8\./.test(process.version)) return t.end(); function Writable() { this.writable = true; this.endCalls = 0; require('stream').Stream.call(this); } inherits(Writable, require('stream').Stream); Writable.prototype.end = function() { this.endCalls++; }; Writable.prototype.destroy = function() { this.endCalls++; }; function Readable() { this.readable = true; require('stream').Stream.call(this); } inherits(Readable, require('stream').Stream); function Duplex() { this.readable = true; Writable.call(this); } inherits(Duplex, Writable); var i = 0; var limit = 100; var w = new Writable(); var r; for (i = 0; i < limit; i++) { r = new Readable(); r.pipe(w); r.emit('end'); } t.equal(0, r.listeners('end').length); t.equal(limit, w.endCalls); w.endCalls = 0; for (i = 0; i < limit; i++) { r = new Readable(); r.pipe(w); r.emit('close'); } t.equal(0, r.listeners('close').length); t.equal(limit, w.endCalls); w.endCalls = 0; r = new Readable(); for (i = 0; i < limit; i++) { w = new Writable(); r.pipe(w); w.emit('close'); } t.equal(0, w.listeners('close').length); r = new Readable(); w = new Writable(); var d = new Duplex(); r.pipe(d); // pipeline A d.pipe(w); // pipeline B t.equal(r.listeners('end').length, 2); // A.onend, A.cleanup t.equal(r.listeners('close').length, 2); // A.onclose, A.cleanup t.equal(d.listeners('end').length, 2); // B.onend, B.cleanup t.equal(d.listeners('close').length, 3); // A.cleanup, B.onclose, B.cleanup t.equal(w.listeners('end').length, 0); t.equal(w.listeners('close').length, 1); // B.cleanup r.emit('end'); t.equal(d.endCalls, 1); t.equal(w.endCalls, 0); t.equal(r.listeners('end').length, 0); t.equal(r.listeners('close').length, 0); t.equal(d.listeners('end').length, 2); // B.onend, B.cleanup t.equal(d.listeners('close').length, 2); // B.onclose, B.cleanup t.equal(w.listeners('end').length, 0); t.equal(w.listeners('close').length, 1); // B.cleanup d.emit('end'); t.equal(d.endCalls, 1); t.equal(w.endCalls, 1); t.equal(r.listeners('end').length, 0); t.equal(r.listeners('close').length, 0); t.equal(d.listeners('end').length, 0); t.equal(d.listeners('close').length, 0); t.equal(w.listeners('end').length, 0); t.equal(w.listeners('close').length, 0); t.end(); }); } readable-stream-2.3.3/test/browser/test-stream-pipe-error-handling.js000066400000000000000000000043041312520600100256520ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Stream = require('stream').Stream; module.exports = function (t) { t.test('Error Listener Catches', function (t) { t.plan(1); var source = new Stream(); var dest = new Stream(); source.pipe(dest); var gotErr = null; source.on('error', function(err) { gotErr = err; }); var err = new Error('This stream turned into bacon.'); source.emit('error', err); t.strictEqual(gotErr, err); }); t.test('Error WithoutListener Throws', function (t) { t.plan(1); var source = new Stream(); var dest = new Stream(); source.pipe(dest); var err = new Error('This stream turned into bacon.'); var gotErr = null; try { source.emit('error', err); } catch (e) { gotErr = e; } t.strictEqual(gotErr, err); }); t.test('Error With Removed Listener Throws', function (t) { t.plan(2); var EE = require('events').EventEmitter; var R = require('../../').Readable; var W = require('../../').Writable; var r = new R(); var w = new W(); var removed = false; r._read = function() { setTimeout(function() { t.ok(removed); t.throws(function() { w.emit('error', new Error('fail')); }); }); }; w.on('error', myOnError); r.pipe(w); w.removeListener('error', myOnError); removed = true; function myOnError(er) { throw new Error('this should not happen'); } }); t.test('Error With Removed Listener Throws', function (t) { t.plan(2); var EE = require('events').EventEmitter; var R = require('../../').Readable; var W = require('../../').Writable; var r = new R(); var w = new W(); var removed = false; var caught = false; r._read = function() { setTimeout(function() { t.ok(removed); w.emit('error', new Error('fail')); }); }; w.on('error', myOnError); w._write = function() {}; r.pipe(w); // Removing some OTHER random listener should not do anything w.removeListener('error', function() {}); removed = true; function myOnError(er) { t.notOk(caught); caught = true; } }); } readable-stream-2.3.3/test/browser/test-stream-pipe-event.js000066400000000000000000000012701312520600100240570ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); var inherits = require('inherits'); module.exports = function (t) { t.test('pipe event', function (t) { t.plan(1); function Writable() { this.writable = true; require('stream').Stream.call(this); } inherits(Writable, require('stream').Stream); function Readable() { this.readable = true; require('stream').Stream.call(this); } inherits(Readable, require('stream').Stream); var passed = false; var w = new Writable(); w.on('pipe', function(src) { passed = true; }); var r = new Readable(); r.pipe(w); t.ok(passed); }); } readable-stream-2.3.3/test/browser/test-stream-pipe-without-listenerCount.js000066400000000000000000000011421312520600100272730ustar00rootroot00000000000000'use strict'; var Stream = require('../../'); module.exports = function (t) { t.tets('pipe without listenerCount', function (t) { t.plan(2); var r = new Stream({ read: function (){}}); r.listenerCount = undefined; var w = new Stream(); w.listenerCount = undefined; w.on('pipe', function() { r.emit('error', new Error('Readable Error')); w.emit('error', new Error('Writable Error')); }); r.on('error', function (e) { t.ok(e, 'readable error'); }); w.on('error', function (e) { t.ok(e, 'writable error'); }); r.pipe(w); }); } readable-stream-2.3.3/test/browser/test-stream-push-order.js000066400000000000000000000012531312520600100240740ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../').Readable; module.exports = function (t) { t.test('push order', function (t) { t.plan(1); var s = new Readable({ highWaterMark: 20, encoding: 'ascii' }); var list = ['1', '2', '3', '4', '5', '6']; s._read = function(n) { var one = list.shift(); if (!one) { s.push(null); } else { var two = list.shift(); s.push(one); s.push(two); } }; var v = s.read(0); // ACTUALLY [1, 3, 5, 6, 4, 2] setTimeout(function() { t.equals(s._readableState.buffer.join(','), '1,2,3,4,5,6'); }); }); } readable-stream-2.3.3/test/browser/test-stream-push-strings.js000066400000000000000000000023211312520600100244470ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../').Readable; var inherits = require('inherits'); module.exports = function (t) { t.test('push strings', function (t) { t.plan(2); inherits(MyStream, Readable); function MyStream(options) { Readable.call(this, options); this._chunks = 3; } MyStream.prototype._read = function(n) { switch (this._chunks--) { case 0: return this.push(null); case 1: return setTimeout(function() { this.push('last chunk'); }.bind(this), 100); case 2: return this.push('second to last chunk'); case 3: return process.nextTick(function() { this.push('first chunk'); }.bind(this)); default: throw new Error('?'); } }; var expect = [ 'first chunksecond to last chunk', 'last chunk' ]; var ms = new MyStream(); var results = []; ms.on('readable', function() { var chunk; while (null !== (chunk = ms.read())) results.push(chunk + ''); }); ms.on('end', function() { t.equal(ms._chunks, -1); t.deepEqual(results, expect); }); }); } readable-stream-2.3.3/test/browser/test-stream-readable-constructor-set-methods.js000066400000000000000000000007251312520600100303630ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../').Readable; module.exports = function (t) { t.test('readable constructor set methods', function (t) { t.plan(2); var _readCalled = false; function _read(n) { _readCalled = true; this.push(null); } var r = new Readable({ read: _read }); r.resume(); setTimeout(function() { t.equal(r._read, _read); t.ok(_readCalled); }); }); } readable-stream-2.3.3/test/browser/test-stream-readable-event.js000066400000000000000000000047061312520600100246700ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../').Readable; function first(t) { // First test, not reading when the readable is added. // make sure that on('readable', ...) triggers a readable event. var r = new Readable({ highWaterMark: 3 }); var _readCalled = false; r._read = function(n) { _readCalled = true; }; // This triggers a 'readable' event, which is lost. r.push(new Buffer('blerg')); var caughtReadable = false; setTimeout(function() { // we're testing what we think we are t.notOk(r._readableState.reading); r.on('readable', function() { caughtReadable = true; setTimeout(function() { // we're testing what we think we are t.notOk(_readCalled); t.ok(caughtReadable); t.end(); }); }); }); } function second(t) { // second test, make sure that readable is re-emitted if there's // already a length, while it IS reading. var r = new Readable({ highWaterMark: 3 }); var _readCalled = false; r._read = function(n) { _readCalled = true; }; // This triggers a 'readable' event, which is lost. r.push(new Buffer('bl')); var caughtReadable = false; setTimeout(function() { // assert we're testing what we think we are t.ok(r._readableState.reading); r.on('readable', function() { caughtReadable = true; setTimeout(function() { // we're testing what we think we are t.ok(_readCalled); t.ok(caughtReadable); t.end(); }); }); }); } function third(t) { // Third test, not reading when the stream has not passed // the highWaterMark but *has* reached EOF. var r = new Readable({ highWaterMark: 30 }); var _readCalled = false; r._read = function(n) { _readCalled = true; }; // This triggers a 'readable' event, which is lost. r.push(new Buffer('blerg')); r.push(null); var caughtReadable = false; setTimeout(function() { // assert we're testing what we think we are t.notOk(r._readableState.reading); r.on('readable', function() { caughtReadable = true; setTimeout(function() { // we're testing what we think we are t.notOk(_readCalled); t.ok(caughtReadable); t.end(); }); }); }); }; module.exports = function (t) { t.test('readable events', function (t) { t.test('first', first); t.test('second', second); t.test('third', third); }); } readable-stream-2.3.3/test/browser/test-stream-sync-write.js000066400000000000000000000017061312520600100241130ustar00rootroot00000000000000require('../common'); var inherits = require('inherits'); var stream = require('../../'); var WritableStream = stream.Writable; module.exports = function(t) { t.test('should bea ble to write sync', function(t) { var InternalStream = function() { WritableStream.call(this); }; inherits(InternalStream, WritableStream); InternalStream.prototype._write = function(chunk, encoding, callback) { callback(); }; var internalStream = new InternalStream(); var ExternalStream = function(writable) { this._writable = writable; WritableStream.call(this); }; inherits(ExternalStream, WritableStream); ExternalStream.prototype._write = function(chunk, encoding, callback) { this._writable.write(chunk, encoding, callback); }; var externalStream = new ExternalStream(internalStream); for (var i = 0; i < 2000; i++) { externalStream.write(i.toString()); } t.end(); }); } readable-stream-2.3.3/test/browser/test-stream-transform-constructor-set-methods.js000066400000000000000000000013411312520600100306320ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Transform = require('../../').Transform; module.exports = function (t) { t.test('transform constructor set methods', function (t) { var _transformCalled = false; function _transform(d, e, n) { _transformCalled = true; n(); } var _flushCalled = false; function _flush(n) { _flushCalled = true; n(); } var tr = new Transform({ transform: _transform, flush: _flush }); tr.end(new Buffer('blerg')); tr.resume(); tr.on('end', function() { t.equal(tr._transform, _transform); t.equal(tr._flush, _flush); t.ok(_transformCalled); t.ok(_flushCalled); t.end(); }); }); } readable-stream-2.3.3/test/browser/test-stream-transform-objectmode-falsey-value.js000066400000000000000000000015231312520600100305230ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); var PassThrough = stream.PassThrough; module.exports = function (t) { t.test('transform objectmode falsey value', function (t) { var src = new PassThrough({ objectMode: true }); var tx = new PassThrough({ objectMode: true }); var dest = new PassThrough({ objectMode: true }); var expect = [ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]; var results = []; dest.on('end', function() { t.deepEqual(results, expect); t.end(); }); dest.on('data', function(x) { results.push(x); }); src.pipe(tx).pipe(dest); var i = -1; var int = setInterval(function() { if (i > 10) { src.end(); clearInterval(int); } else { t.ok(true); src.write(i++); } }, 10); }); } readable-stream-2.3.3/test/browser/test-stream-transform-split-objectmode.js000066400000000000000000000031171312520600100272620ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Transform = require('../../').Transform; module.exports = function (t) { t.test('transform split objectmode', function (t) { t.plan(10); var parser = new Transform({ readableObjectMode : true }); t.ok(parser._readableState.objectMode, 'parser 1'); t.notOk(parser._writableState.objectMode, 'parser 2'); t.equals(parser._readableState.highWaterMark, 16, 'parser 3'); t.equals(parser._writableState.highWaterMark, (16 * 1024), 'parser 4'); parser._transform = function(chunk, enc, callback) { callback(null, { val : chunk[0] }); }; var parsed; parser.on('data', function(obj) { parsed = obj; }); parser.end(new Buffer([42])); parser.on('end', function() { t.equals(parsed.val, 42, 'parser ended'); }); var serializer = new Transform({ writableObjectMode : true }); t.notOk(serializer._readableState.objectMode, 'serializer 1'); t.ok(serializer._writableState.objectMode, 'serializer 2'); t.equals(serializer._readableState.highWaterMark, (16 * 1024), 'serializer 3'); t.equals(serializer._writableState.highWaterMark, 16, 'serializer 4'); serializer._transform = function(obj, _, callback) { callback(null, new Buffer([obj.val])); }; var serialized; serializer.on('data', function(chunk) { serialized = chunk; }); serializer.write({ val : 42 }); serializer.on('end', function() { t.equals(serialized[0], 42, 'searlizer ended'); }); setImmediate(function () { serializer.end(); }); }); } readable-stream-2.3.3/test/browser/test-stream-unshift-empty-chunk.js000066400000000000000000000030541312520600100257270ustar00rootroot00000000000000'use strict'; var common = require('../common'); // This test verifies that stream.unshift(Buffer(0)) or // stream.unshift('') does not set state.reading=false. var Readable = require('../../').Readable; module.exports = function (t) { t.test('unshift empty chunk', function (t) { t.plan(1); var r = new Readable(); var nChunks = 10; var chunk = new Buffer(10); chunk.fill('x'); r._read = function(n) { setTimeout(function() { r.push(--nChunks === 0 ? null : chunk); }); }; var readAll = false; var seen = []; r.on('readable', function() { var chunk; while (chunk = r.read()) { seen.push(chunk.toString()); // simulate only reading a certain amount of the data, // and then putting the rest of the chunk back into the // stream, like a parser might do. We just fill it with // 'y' so that it's easy to see which bits were touched, // and which were not. var putBack = new Buffer(readAll ? 0 : 5); putBack.fill('y'); readAll = !readAll; r.unshift(putBack); } }); var expect = [ 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy' ]; r.on('end', function() { t.deepEqual(seen, expect); }); }); } readable-stream-2.3.3/test/browser/test-stream-unshift-read-race.js000066400000000000000000000060061312520600100253060ustar00rootroot00000000000000'use strict'; var common = require('../common'); // This test verifies that: // 1. unshift() does not cause colliding _read() calls. // 2. unshift() after the 'end' event is an error, but after the EOF // signalling null, it is ok, and just creates a new readable chunk. // 3. push() after the EOF signaling null is an error. // 4. _read() is not called after pushing the EOF null chunk. var stream = require('../../'); module.exports = function (t) { t.test('unshift read race', function (tape) { var hwm = 10; var r = stream.Readable({ highWaterMark: hwm }); var chunks = 10; var t = (chunks * 5); var data = new Buffer(chunks * hwm + Math.ceil(hwm / 2)); for (var i = 0; i < data.length; i++) { var c = 'asdf'.charCodeAt(i % 4); data[i] = c; } var pos = 0; var pushedNull = false; r._read = function(n) { tape.notOk(pushedNull, '_read after null push'); // every third chunk is fast push(!(chunks % 3)); function push(fast) { tape.notOk(pushedNull, 'push() after null push'); var c = pos >= data.length ? null : data.slice(pos, Math.min(pos + n, data.length)); pushedNull = c === null; if (fast) { pos += n; r.push(c); if (c === null) pushError(); } else { setTimeout(function() { pos += n; r.push(c); if (c === null) pushError(); }); } } }; function pushError() { tape.throws(function() { r.push(new Buffer(1)); }); } var w = stream.Writable(); var written = []; w._write = function(chunk, encoding, cb) { written.push(chunk.toString()); cb(); }; var ended = false; r.on('end', function() { tape.notOk(ended, 'end emitted more than once'); tape.throws(function() { r.unshift(new Buffer(1)); }); ended = true; w.end(); }); r.on('readable', function() { var chunk; while (null !== (chunk = r.read(10))) { w.write(chunk); if (chunk.length > 4) r.unshift(new Buffer('1234')); } }); w.on('finish', function() { // each chunk should start with 1234, and then be asfdasdfasdf... // The first got pulled out before the first unshift('1234'), so it's // lacking that piece. tape.equal(written[0], 'asdfasdfas'); var asdf = 'd'; //console.error('0: %s', written[0]); for (var i = 1; i < written.length; i++) { //console.error('%s: %s', i.toString(32), written[i]); tape.equal(written[i].slice(0, 4), '1234'); for (var j = 4; j < written[i].length; j++) { var c = written[i].charAt(j); tape.equal(c, asdf); switch (asdf) { case 'a': asdf = 's'; break; case 's': asdf = 'd'; break; case 'd': asdf = 'f'; break; case 'f': asdf = 'a'; break; } } } tape.equal(written.length, 18); tape.end(); }); }); } readable-stream-2.3.3/test/browser/test-stream-writable-change-default-encoding.js000066400000000000000000000032621312520600100302500ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); var inherits = require('inherits'); function MyWritable(fn, options) { stream.Writable.call(this, options); this.fn = fn; }; inherits(MyWritable, stream.Writable); MyWritable.prototype._write = function(chunk, encoding, callback) { this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding); callback(); }; function defaultCondingIsUtf8(t) { t.plan(1); var m = new MyWritable(function(isBuffer, type, enc) { t.equal(enc, 'utf8'); }, { decodeStrings: false }); m.write('foo'); m.end(); } function changeDefaultEncodingToAscii(t) { t.plan(1); var m = new MyWritable(function(isBuffer, type, enc) { t.equal(enc, 'ascii'); }, { decodeStrings: false }); m.setDefaultEncoding('ascii'); m.write('bar'); m.end(); } function changeDefaultEncodingToInvalidValue(t) { t.plan(1); t.throws(function () { var m = new MyWritable(function(isBuffer, type, enc) { }, { decodeStrings: false }); m.setDefaultEncoding({}); m.write('bar'); m.end(); }, TypeError); } function checkVairableCaseEncoding(t) { t.plan(1); var m = new MyWritable(function(isBuffer, type, enc) { t.equal(enc, 'ascii'); }, { decodeStrings: false }); m.setDefaultEncoding('AsCii'); m.write('bar'); m.end(); } module.exports = function (t) { t.test('writable change default encoding', function (t) { t.test('defaultCondingIsUtf8', defaultCondingIsUtf8); t.test('changeDefaultEncodingToAscii', changeDefaultEncodingToAscii); t.test('changeDefaultEncodingToInvalidValue', changeDefaultEncodingToInvalidValue); t.test('checkVairableCaseEncoding', checkVairableCaseEncoding); }); } readable-stream-2.3.3/test/browser/test-stream-writable-constructor-set-methods.js000066400000000000000000000015341312520600100304340ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Writable = require('../../').Writable; module.exports = function (t) { t.test('writable constructor set methods', function (t){ var _writeCalled = false; function _write(d, e, n) { _writeCalled = true; } var w = new Writable({ write: _write }); w.end(new Buffer('blerg')); var _writevCalled = false; var dLength = 0; function _writev(d, n) { dLength = d.length; _writevCalled = true; } var w2 = new Writable({ writev: _writev }); w2.cork(); w2.write(new Buffer('blerg')); w2.write(new Buffer('blerg')); w2.end(); setImmediate(function() { t.equal(w._write, _write); t.ok(_writeCalled); t.equal(w2._writev, _writev); t.equal(dLength, 2); t.ok(_writevCalled); t.end(); }); }); } readable-stream-2.3.3/test/browser/test-stream-writable-decoded-encoding.js000066400000000000000000000022111312520600100267610ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); var inherits = require('inherits'); function MyWritable(fn, options) { stream.Writable.call(this, options); this.fn = fn; }; inherits(MyWritable, stream.Writable); MyWritable.prototype._write = function(chunk, encoding, callback) { this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding); callback(); }; function decodeStringsTrue(t) { t.plan(3); var m = new MyWritable(function(isBuffer, type, enc) { t.ok(isBuffer); t.equal(type, 'object'); t.equal(enc, 'buffer'); //console.log('ok - decoded string is decoded'); }, { decodeStrings: true }); m.write('some-text', 'utf8'); m.end(); } function decodeStringsFalse(t) { t.plan(3); var m = new MyWritable(function(isBuffer, type, enc) { t.notOk(isBuffer); t.equal(type, 'string'); t.equal(enc, 'utf8'); //console.log('ok - un-decoded string is not decoded'); }, { decodeStrings: false }); m.write('some-text', 'utf8'); m.end(); } module.exports = function (t) { t.test('decodeStringsTrue', decodeStringsTrue); t.test('decodeStringsFalse', decodeStringsFalse); } readable-stream-2.3.3/test/browser/test-stream-writev.js000066400000000000000000000053061312520600100233270ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); var queue = []; for (var decode = 0; decode < 2; decode++) { for (var uncork = 0; uncork < 2; uncork++) { for (var multi = 0; multi < 2; multi++) { queue.push([!!decode, !!uncork, !!multi]); } } } module.exports = function (t) { t.test('writev', function (t) { queue.forEach(function (tr, i){ t.test('round ' + i, test(tr[0], tr[1], tr[2])); }); }); } function test(decode, uncork, multi) { return function (t) { //console.log('# decode=%j uncork=%j multi=%j', decode, uncork, multi); var counter = 0; var expectCount = 0; function cnt(msg) { expectCount++; var expect = expectCount; var called = false; return function(er) { if (er) throw er; called = true; counter++; t.equal(counter, expect); }; } var w = new stream.Writable({ decodeStrings: decode }); w._write = function(chunk, e, cb) { t.ok(false, 'Should not call _write'); }; var expectChunks = decode ? [ { encoding: 'buffer', chunk: [104, 101, 108, 108, 111, 44, 32] }, { encoding: 'buffer', chunk: [119, 111, 114, 108, 100] }, { encoding: 'buffer', chunk: [33] }, { encoding: 'buffer', chunk: [10, 97, 110, 100, 32, 116, 104, 101, 110, 46, 46, 46] }, { encoding: 'buffer', chunk: [250, 206, 190, 167, 222, 173, 190, 239, 222, 202, 251, 173]} ] : [ { encoding: 'ascii', chunk: 'hello, ' }, { encoding: 'utf8', chunk: 'world' }, { encoding: 'buffer', chunk: [33] }, { encoding: 'binary', chunk: '\nand then...' }, { encoding: 'hex', chunk: 'facebea7deadbeefdecafbad' } ]; var actualChunks; w._writev = function(chunks, cb) { actualChunks = chunks.map(function(chunk) { return { encoding: chunk.encoding, chunk: Buffer.isBuffer(chunk.chunk) ? Array.prototype.slice.call(chunk.chunk) : chunk.chunk }; }); cb(); }; w.cork(); w.write('hello, ', 'ascii', cnt('hello')); w.write('world', 'utf8', cnt('world')); if (multi) w.cork(); w.write(new Buffer('!'), 'buffer', cnt('!')); w.write('\nand then...', 'binary', cnt('and then')); if (multi) w.uncork(); w.write('facebea7deadbeefdecafbad', 'hex', cnt('hex')); if (uncork) w.uncork(); w.end(cnt('end')); w.on('finish', function() { // make sure finish comes after all the write cb cnt('finish')(); t.deepEqual(expectChunks, actualChunks); t.end(); }); } } readable-stream-2.3.3/test/browser/test-stream2-base64-single-char-read-end.js000066400000000000000000000015351312520600100270240ustar00rootroot00000000000000'use strict'; var common = require('../common'); var R = require('../../lib/_stream_readable'); var W = require('../../lib/_stream_writable'); module.exports = function (t) { t.test('base64 single char read end', function (t) { t.plan(1); var src = new R({encoding: 'base64'}); var dst = new W(); var hasRead = false; var accum = []; var timeout; src._read = function(n) { if(!hasRead) { hasRead = true; process.nextTick(function() { src.push(new Buffer('1')); src.push(null); }); }; }; dst._write = function(chunk, enc, cb) { accum.push(chunk); cb(); }; src.on('end', function() { t.equal(Buffer.concat(accum) + '', 'MQ=='); clearTimeout(timeout); }); src.pipe(dst); timeout = setTimeout(function() { assert.fail('timed out waiting for _write'); }, 100); }) } readable-stream-2.3.3/test/browser/test-stream2-compatibility.js000066400000000000000000000013071312520600100247370ustar00rootroot00000000000000'use strict'; var R = require('../../lib/_stream_readable'); var inherits = require('inherits'); var EE = require('events').EventEmitter; module.exports = function (t) { t.test('compatibility', function (t) { t.plan(1); var ondataCalled = 0; function TestReader() { R.apply(this); this._buffer = new Buffer(100); this._buffer.fill('x'); this.on('data', function() { ondataCalled++; }); } inherits(TestReader, R); TestReader.prototype._read = function(n) { this.push(this._buffer); this._buffer = new Buffer(0); }; var reader = new TestReader(); setTimeout(function() { t.equal(ondataCalled, 1); }); }); } readable-stream-2.3.3/test/browser/test-stream2-large-read-stall.js000066400000000000000000000030141312520600100252030ustar00rootroot00000000000000'use strict'; var common = require('../common'); module.exports = function (t) { t.test('large object read stall', function (t) { // If everything aligns so that you do a read(n) of exactly the // remaining buffer, then make sure that 'end' still emits. var READSIZE = 100; var PUSHSIZE = 20; var PUSHCOUNT = 1000; var HWM = 50; var Readable = require('../../').Readable; var r = new Readable({ highWaterMark: HWM }); var rs = r._readableState; r._read = push; r.on('readable', function() { ;false && console.error('>> readable'); do { ;false && console.error(' > read(%d)', READSIZE); var ret = r.read(READSIZE); ;false && console.error(' < %j (%d remain)', ret && ret.length, rs.length); } while (ret && ret.length === READSIZE); ;false && console.error('<< after read()', ret && ret.length, rs.needReadable, rs.length); }); var endEmitted = false; r.on('end', function() { t.equal(pushes, PUSHCOUNT + 1); t.end(); ;false && console.error('end'); }); var pushes = 0; function push() { if (pushes > PUSHCOUNT) return; if (pushes++ === PUSHCOUNT) { ;false && console.error(' push(EOF)'); return r.push(null); } ;false && console.error(' push #%d', pushes); if (r.push(new Buffer(PUSHSIZE))) setTimeout(push); } // start the flow var ret = r.read(0); }); } readable-stream-2.3.3/test/browser/test-stream2-objects.js000066400000000000000000000131751312520600100235250ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../lib/_stream_readable'); var Writable = require('../../lib/_stream_writable'); module.exports = function (t) { function toArray(callback) { var stream = new Writable({ objectMode: true }); var list = []; stream.write = function(chunk) { list.push(chunk); }; stream.end = function() { callback(list); }; return stream; } function fromArray(list) { var r = new Readable({ objectMode: true }); r._read = noop; forEach(list, function(chunk) { r.push(chunk); }); r.push(null); return r; } function noop() {} t.test('can read objects from stream', function(t) { var r = fromArray([{ one: '1'}, { two: '2' }]); var v1 = r.read(); var v2 = r.read(); var v3 = r.read(); t.deepEqual(v1, { one: '1' }); t.deepEqual(v2, { two: '2' }); t.deepEqual(v3, null); t.end(); }); t.test('can pipe objects into stream', function(t) { var r = fromArray([{ one: '1'}, { two: '2' }]); r.pipe(toArray(function(list) { t.deepEqual(list, [ { one: '1' }, { two: '2' } ]); t.end(); })); }); t.test('read(n) is ignored', function(t) { var r = fromArray([{ one: '1'}, { two: '2' }]); var value = r.read(2); t.deepEqual(value, { one: '1' }); t.end(); }); t.test('can read objects from _read (sync)', function(t) { var r = new Readable({ objectMode: true }); var list = [{ one: '1'}, { two: '2' }]; r._read = function(n) { var item = list.shift(); r.push(item || null); }; r.pipe(toArray(function(list) { t.deepEqual(list, [ { one: '1' }, { two: '2' } ]); t.end(); })); }); t.test('can read objects from _read (async)', function(t) { var r = new Readable({ objectMode: true }); var list = [{ one: '1'}, { two: '2' }]; r._read = function(n) { var item = list.shift(); process.nextTick(function() { r.push(item || null); }); }; r.pipe(toArray(function(list) { t.deepEqual(list, [ { one: '1' }, { two: '2' } ]); t.end(); })); }); t.test('can read strings as objects', function(t) { var r = new Readable({ objectMode: true }); r._read = noop; var list = ['one', 'two', 'three']; forEach(list, function(str) { r.push(str); }); r.push(null); r.pipe(toArray(function(array) { t.deepEqual(array, list); t.end(); })); }); t.test('read(0) for object streams', function(t) { var r = new Readable({ objectMode: true }); r._read = noop; r.push('foobar'); r.push(null); var v = r.read(0); r.pipe(toArray(function(array) { t.deepEqual(array, ['foobar']); t.end(); })); }); t.test('falsey values', function(t) { var r = new Readable({ objectMode: true }); r._read = noop; r.push(false); r.push(0); r.push(''); r.push(null); r.pipe(toArray(function(array) { t.deepEqual(array, [false, 0, '']); t.end(); })); }); t.test('high watermark _read', function(t) { var r = new Readable({ highWaterMark: 6, objectMode: true }); var calls = 0; var list = ['1', '2', '3', '4', '5', '6', '7', '8']; r._read = function(n) { calls++; }; forEach(list, function(c) { r.push(c); }); var v = r.read(); t.equal(calls, 0); t.equal(v, '1'); var v2 = r.read(); t.equal(v2, '2'); var v3 = r.read(); t.equal(v3, '3'); t.equal(calls, 1); t.end(); }); t.test('high watermark push', function(t) { var r = new Readable({ highWaterMark: 6, objectMode: true }); r._read = function(n) {}; for (var i = 0; i < 6; i++) { var bool = r.push(i); t.equal(bool, i === 5 ? false : true); } t.end(); }); t.test('can write objects to stream', function(t) { var w = new Writable({ objectMode: true }); w._write = function(chunk, encoding, cb) { t.deepEqual(chunk, { foo: 'bar' }); cb(); }; w.on('finish', function() { t.end(); }); w.write({ foo: 'bar' }); w.end(); }); t.test('can write multiple objects to stream', function(t) { var w = new Writable({ objectMode: true }); var list = []; w._write = function(chunk, encoding, cb) { list.push(chunk); cb(); }; w.on('finish', function() { t.deepEqual(list, [0, 1, 2, 3, 4]); t.end(); }); w.write(0); w.write(1); w.write(2); w.write(3); w.write(4); w.end(); }); t.test('can write strings as objects', function(t) { var w = new Writable({ objectMode: true }); var list = []; w._write = function(chunk, encoding, cb) { list.push(chunk); process.nextTick(cb); }; w.on('finish', function() { t.deepEqual(list, ['0', '1', '2', '3', '4']); t.end(); }); w.write('0'); w.write('1'); w.write('2'); w.write('3'); w.write('4'); w.end(); }); t.test('buffers finish until cb is called', function(t) { var w = new Writable({ objectMode: true }); var called = false; w._write = function(chunk, encoding, cb) { t.equal(chunk, 'foo'); process.nextTick(function() { called = true; cb(); }); }; w.on('finish', function() { t.equal(called, true); t.end(); }); w.write('foo'); w.end(); }); function forEach (xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } }; readable-stream-2.3.3/test/browser/test-stream2-pipe-error-handling.js000066400000000000000000000037421312520600100257410ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = require('assert'); var stream = require('../../'); module.exports = function (t) { t.test('Error Listener Catches', function (t) { var count = 1000; var source = new stream.Readable(); source._read = function(n) { n = Math.min(count, n); count -= n; source.push(new Buffer(n)); }; var unpipedDest; source.unpipe = function(dest) { unpipedDest = dest; stream.Readable.prototype.unpipe.call(this, dest); }; var dest = new stream.Writable(); dest._write = function(chunk, encoding, cb) { cb(); }; source.pipe(dest); var gotErr = null; dest.on('error', function(err) { gotErr = err; }); var unpipedSource; dest.on('unpipe', function(src) { unpipedSource = src; }); var err = new Error('This stream turned into bacon.'); dest.emit('error', err); t.strictEqual(gotErr, err); t.strictEqual(unpipedSource, source); t.strictEqual(unpipedDest, dest); t.end(); }); t.test('Error Without Listener Throws', function testErrorWithoutListenerThrows(t) { var count = 1000; var source = new stream.Readable(); source._read = function(n) { n = Math.min(count, n); count -= n; source.push(new Buffer(n)); }; var unpipedDest; source.unpipe = function(dest) { unpipedDest = dest; stream.Readable.prototype.unpipe.call(this, dest); }; var dest = new stream.Writable(); dest._write = function(chunk, encoding, cb) { cb(); }; source.pipe(dest); var unpipedSource; dest.on('unpipe', function(src) { unpipedSource = src; }); var err = new Error('This stream turned into bacon.'); var gotErr = null; try { dest.emit('error', err); } catch (e) { gotErr = e; } t.strictEqual(gotErr, err); t.strictEqual(unpipedSource, source); t.strictEqual(unpipedDest, dest); t.end(); }); } readable-stream-2.3.3/test/browser/test-stream2-pipe-error-once-listener.js000066400000000000000000000015511312520600100267200ustar00rootroot00000000000000'use strict'; var common = require('../common'); var inherits = require('inherits'); var stream = require('../../'); module.exports = function (t) { t.test('pipe error once listener', function (t){ t.plan(1); var Read = function() { stream.Readable.call(this); }; inherits(Read, stream.Readable); Read.prototype._read = function(size) { this.push('x'); this.push(null); }; var Write = function() { stream.Writable.call(this); }; inherits(Write, stream.Writable); Write.prototype._write = function(buffer, encoding, cb) { this.emit('error', new Error('boom')); this.emit('alldone'); }; var read = new Read(); var write = new Write(); write.once('error', function(err) {}); write.once('alldone', function(err) { t.ok(true); }); read.pipe(write); }); } readable-stream-2.3.3/test/browser/test-stream2-push.js000066400000000000000000000047071312520600100230540ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); var Readable = stream.Readable; var Writable = stream.Writable; var inherits = require('inherits'); var EE = require('events').EventEmitter; module.exports = function (t) { // a mock thing a bit like the net.Socket/tcp_wrap.handle interaction t.test('push', function (t) { var stream = new Readable({ highWaterMark: 16, encoding: 'utf8' }); var source = new EE(); stream._read = function() { //console.error('stream._read'); readStart(); }; var ended = false; stream.on('end', function() { ended = true; }); source.on('data', function(chunk) { var ret = stream.push(chunk); //console.error('data', stream._readableState.length); if (!ret) readStop(); }); source.on('end', function() { stream.push(null); }); var reading = false; function readStart() { //console.error('readStart'); reading = true; } function readStop() { //console.error('readStop'); reading = false; process.nextTick(function() { var r = stream.read(); if (r !== null) writer.write(r); }); } var writer = new Writable({ decodeStrings: false }); var written = []; var expectWritten = [ 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg' ]; writer._write = function(chunk, encoding, cb) { //console.error('WRITE %s', chunk); written.push(chunk); process.nextTick(cb); }; writer.on('finish', finish); // now emit some chunks. var chunk = 'asdfg'; var set = 0; readStart(); data(); function data() { t.ok(reading); source.emit('data', chunk); t.ok(reading); source.emit('data', chunk); t.ok(reading); source.emit('data', chunk); t.ok(reading); source.emit('data', chunk); t.notOk(reading); if (set++ < 5) setTimeout(data, 10); else end(); } function finish() { //console.error('finish'); t.deepEqual(written, expectWritten); t.end(); } function end() { source.emit('end'); t.notOk(reading); writer.end(stream.read()); setTimeout(function() { t.ok(ended); }); } }); }; readable-stream-2.3.3/test/browser/test-stream2-readable-empty-buffer-no-eof.js000066400000000000000000000046511312520600100274160ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../').Readable; module.exports = function (t) { t.test('readable empty buffer no eof 1', function (t) { t.plan(1); var r = new Readable(); // should not end when we get a Buffer(0) or '' as the _read result // that just means that there is *temporarily* no data, but to go // ahead and try again later. // // note that this is very unusual. it only works for crypto streams // because the other side of the stream will call read(0) to cycle // data through openssl. that's why we set the timeouts to call // r.read(0) again later, otherwise there is no more work being done // and the process just exits. var buf = new Buffer(5); buf.fill('x'); var reads = 5; r._read = function(n) { switch (reads--) { case 0: return r.push(null); // EOF case 1: return r.push(buf); case 2: setTimeout(r.read.bind(r, 0), 50); return r.push(new Buffer(0)); // Not-EOF! case 3: setTimeout(r.read.bind(r, 0), 50); return process.nextTick(function() { return r.push(new Buffer(0)); }); case 4: setTimeout(r.read.bind(r, 0), 50); return setTimeout(function() { return r.push(new Buffer(0)); }); case 5: return setTimeout(function() { return r.push(buf); }); default: throw new Error('unreachable'); } }; var results = []; function flow() { var chunk; while (null !== (chunk = r.read())) results.push(chunk + ''); } r.on('readable', flow); r.on('end', function() { results.push('EOF'); t.deepEqual(results, [ 'xxxxx', 'xxxxx', 'EOF' ]); }); flow(); }); t.test('readable empty buffer no eof 2', function (t) { t.plan(1); var r = new Readable({ encoding: 'base64' }); var reads = 5; r._read = function(n) { if (!reads--) return r.push(null); // EOF else return r.push(new Buffer('x')); }; var results = []; function flow() { var chunk; while (null !== (chunk = r.read())) results.push(chunk + ''); } r.on('readable', flow); r.on('end', function() { results.push('EOF'); t.deepEqual(results, [ 'eHh4', 'eHg=', 'EOF' ]); }); flow(); }); } readable-stream-2.3.3/test/browser/test-stream2-readable-from-list.js000066400000000000000000000036631312520600100255460ustar00rootroot00000000000000// Flags: --expose_internals /**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var fromList = require('../../lib/_stream_readable')._fromList; var BufferList = require('../../lib/internal/streams/BufferList'); function bufferListFromArray(arr) { var bl = new BufferList(); for (var i = 0; i < arr.length; ++i) { bl.push(arr[i]); }return bl; } module.exports = function (t) { t.test('buffers', function (t) { var list = [bufferShim.from('foog'), bufferShim.from('bark'), bufferShim.from('bazy'), bufferShim.from('kuel')]; list = bufferListFromArray(list); // read more than the first element. var ret = fromList(6, { buffer: list, length: 16 }); t.equal(ret.toString(), 'foogba'); // read exactly the first element. ret = fromList(2, { buffer: list, length: 10 }); t.equal(ret.toString(), 'rk'); // read less than the first element. ret = fromList(2, { buffer: list, length: 8 }); t.equal(ret.toString(), 'ba'); // read more than we have. ret = fromList(100, { buffer: list, length: 6 }); t.equal(ret.toString(), 'zykuel'); // all consumed. t.same(list, new BufferList()); t.end(); }); t.test('strings', function (t) { var list = ['foog', 'bark', 'bazy', 'kuel']; list = bufferListFromArray(list); // read more than the first element. var ret = fromList(6, { buffer: list, length: 16, decoder: true }); t.equal(ret, 'foogba'); // read exactly the first element. ret = fromList(2, { buffer: list, length: 10, decoder: true }); t.equal(ret, 'rk'); // read less than the first element. ret = fromList(2, { buffer: list, length: 8, decoder: true }); t.equal(ret, 'ba'); // read more than we have. ret = fromList(100, { buffer: list, length: 6, decoder: true }); t.equal(ret, 'zykuel'); // all consumed. t.same(list, new BufferList()); t.end(); }); } readable-stream-2.3.3/test/browser/test-stream2-readable-legacy-drain.js000066400000000000000000000021741312520600100261650ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Stream = require('../../'); var Readable = require('../../').Readable; module.exports = function (t) { t.test('readable legacy drain', function (t) { var r = new Readable(); var N = 256; var reads = 0; r._read = function(n) { return r.push(++reads === N ? null : new Buffer(1)); }; t.plan(2); r.on('end', function() { t.ok(true, 'rended'); }); var w = new Stream(); w.writable = true; var writes = 0; var buffered = 0; w.write = function(c) { writes += c.length; buffered += c.length; process.nextTick(drain); return false; }; function drain() { if(buffered > 3) { t.ok(false, 'to much buffer'); } buffered = 0; w.emit('drain'); } w.end = function() { t.ok(true, 'wended'); }; // Just for kicks, let's mess with the drain count. // This verifies that even if it gets negative in the // pipe() cleanup function, we'll still function properly. r.on('readable', function() { w.emit('drain'); }); r.pipe(w); }); } readable-stream-2.3.3/test/browser/test-stream2-readable-non-empty-end.js000066400000000000000000000024521312520600100263170ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../lib/_stream_readable'); module.exports = function (t) { t.test('non empty end', function (t) { t.plan(4); var len = 0; var chunks = new Array(10); for (var i = 1; i <= 10; i++) { chunks[i - 1] = new Buffer(i); len += i; } var test = new Readable(); var n = 0; test._read = function(size) { var chunk = chunks[n++]; setTimeout(function() { test.push(chunk === undefined ? null : chunk); }); }; test.on('end', thrower); function thrower() { throw new Error('this should not happen!'); } var bytesread = 0; test.on('readable', function() { var b = len - bytesread - 1; var res = test.read(b); if (res) { bytesread += res.length; //console.error('br=%d len=%d', bytesread, len); setTimeout(next); } test.read(0); }); test.read(0); function next() { // now let's make 'end' happen test.removeListener('end', thrower); test.on('end', function() { t.ok(true, 'end emitted'); }); // one to get the last byte var r = test.read(); t.ok(r); t.equal(r.length, 1); r = test.read(); t.equal(r, null); } }); } readable-stream-2.3.3/test/browser/test-stream2-readable-wrap-empty.js000066400000000000000000000010411312520600100257230ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../lib/_stream_readable'); var EE = require('events').EventEmitter; module.exports = function (t) { t.test('wrap empty', function (t) { t.plan(1); var oldStream = new EE(); oldStream.pause = function() {}; oldStream.resume = function() {}; var newStream = new Readable().wrap(oldStream); newStream .on('readable', function() {}) .on('end', function() { t.ok(true, 'ended'); }); oldStream.emit('end'); }) } readable-stream-2.3.3/test/browser/test-stream2-readable-wrap.js000066400000000000000000000043331312520600100245760ustar00rootroot00000000000000'use strict'; var common = require('../common'); var Readable = require('../../lib/_stream_readable'); var Writable = require('../../lib/_stream_writable'); var EE = require('events').EventEmitter; var run = 0; function runTest(t, highWaterMark, objectMode, produce) { t.test('run #' + (++run), function (t) { var old = new EE(); var r = new Readable({ highWaterMark: highWaterMark, objectMode: objectMode }); t.equal(r, r.wrap(old)); var ended = false; r.on('end', function() { ended = true; }); old.pause = function() { //console.error('old.pause()'); old.emit('pause'); flowing = false; }; old.resume = function() { //console.error('old.resume()'); old.emit('resume'); flow(); }; var flowing; var chunks = 10; var oldEnded = false; var expected = []; function flow() { flowing = true; while (flowing && chunks-- > 0) { var item = produce(); expected.push(item); //console.log('old.emit', chunks, flowing); old.emit('data', item); //console.log('after emit', chunks, flowing); } if (chunks <= 0) { oldEnded = true; //console.log('old end', chunks, flowing); old.emit('end'); } } var w = new Writable({ highWaterMark: highWaterMark * 2, objectMode: objectMode }); var written = []; w._write = function(chunk, encoding, cb) { //console.log('_write', chunk); written.push(chunk); setTimeout(cb); }; w.on('finish', function() { performAsserts(); }); r.pipe(w); flow(); function performAsserts() { t.ok(ended); t.ok(oldEnded); t.deepEqual(written, expected); t.end(); } }); } module.exports = function (t) { t.test('readable wrap', function (t) { runTest(t, 100, false, function() { return new Buffer(100); }); runTest(t, 10, false, function() { return new Buffer('xxxxxxxxxx'); }); runTest(t, 1, true, function() { return { foo: 'bar' }; }); var objectChunks = [ 5, 'a', false, 0, '', 'xyz', { x: 4 }, 7, [], 555 ]; runTest(t, 1, true, function() { return objectChunks.shift(); }); }); } readable-stream-2.3.3/test/browser/test-stream2-set-encoding.js000066400000000000000000000151641312520600100244530ustar00rootroot00000000000000'use strict'; var common = require('../common'); var R = require('../../lib/_stream_readable'); var util = { inherits: require('inherits') }; // tiny node-tap lookalike. module.exports = function (t) { var test = t.test; ///// util.inherits(TestReader, R); function TestReader(n, opts) { R.call(this, opts); this.pos = 0; this.len = n || 100; } TestReader.prototype._read = function(n) { setTimeout(function() { if (this.pos >= this.len) { // double push(null) to test eos handling this.push(null); return this.push(null); } n = Math.min(n, this.len - this.pos); if (n <= 0) { // double push(null) to test eos handling this.push(null); return this.push(null); } this.pos += n; var ret = new Buffer(n); ret.fill('a'); //console.log('this.push(ret)', ret); return this.push(ret); }.bind(this), 1); }; test('setEncoding utf8', function(t) { var tr = new TestReader(100); tr.setEncoding('utf8'); var out = []; var expect = [ 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa' ]; tr.on('readable', function flow() { var chunk; while (null !== (chunk = tr.read(10))) out.push(chunk); }); tr.on('end', function() { t.same(out, expect); t.end(); }); }); test('setEncoding hex', function(t) { var tr = new TestReader(100); tr.setEncoding('hex'); var out = []; var expect = [ '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161' ]; tr.on('readable', function flow() { var chunk; while (null !== (chunk = tr.read(10))) out.push(chunk); }); tr.on('end', function() { t.same(out, expect); t.end(); }); }); test('setEncoding hex with read(13)', function(t) { var tr = new TestReader(100); tr.setEncoding('hex'); var out = []; var expect = [ '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '16161' ]; tr.on('readable', function flow() { //console.log('readable once'); var chunk; while (null !== (chunk = tr.read(13))) out.push(chunk); }); tr.on('end', function() { //console.log('END'); t.same(out, expect); t.end(); }); }); test('setEncoding base64', function(t) { var tr = new TestReader(100); tr.setEncoding('base64'); var out = []; var expect = [ 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYQ==' ]; tr.on('readable', function flow() { var chunk; while (null !== (chunk = tr.read(10))) out.push(chunk); }); tr.on('end', function() { t.same(out, expect); t.end(); }); }); test('encoding: utf8', function(t) { var tr = new TestReader(100, { encoding: 'utf8' }); var out = []; var expect = [ 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa' ]; tr.on('readable', function flow() { var chunk; while (null !== (chunk = tr.read(10))) out.push(chunk); }); tr.on('end', function() { t.same(out, expect); t.end(); }); }); test('encoding: hex', function(t) { var tr = new TestReader(100, { encoding: 'hex' }); var out = []; var expect = [ '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161' ]; tr.on('readable', function flow() { var chunk; while (null !== (chunk = tr.read(10))) out.push(chunk); }); tr.on('end', function() { t.same(out, expect); t.end(); }); }); test('encoding: hex with read(13)', function(t) { var tr = new TestReader(100, { encoding: 'hex' }); var out = []; var expect = [ '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '16161' ]; tr.on('readable', function flow() { var chunk; while (null !== (chunk = tr.read(13))) out.push(chunk); }); tr.on('end', function() { t.same(out, expect); t.end(); }); }); test('encoding: base64', function(t) { var tr = new TestReader(100, { encoding: 'base64' }); var out = []; var expect = [ 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYQ==' ]; tr.on('readable', function flow() { var chunk; while (null !== (chunk = tr.read(10))) out.push(chunk); }); tr.on('end', function() { t.same(out, expect); t.end(); }); }); test('chainable', function(t) { var tr = new TestReader(100); t.equal(tr.setEncoding('utf8'), tr); t.end(); }); } readable-stream-2.3.3/test/browser/test-stream2-transform.js000066400000000000000000000265211312520600100241060ustar00rootroot00000000000000'use strict'; var common = require('../common'); var PassThrough = require('../../lib/_stream_passthrough'); var Transform = require('../../lib/_stream_transform'); ///// module.exports = function (t) { t.test('writable side consumption', function(t) { var tx = new Transform({ highWaterMark: 10 }); var transformed = 0; tx._transform = function(chunk, encoding, cb) { transformed += chunk.length; tx.push(chunk); cb(); }; for (var i = 1; i <= 10; i++) { tx.write(new Buffer(i)); } tx.end(); t.equal(tx._readableState.length, 10); t.equal(transformed, 10); t.equal(tx._transformState.writechunk.length, 5); t.same(tx._writableState.getBuffer().map(function(c) { return c.chunk.length; }), [6, 7, 8, 9, 10]); t.end(); }); t.test('passthrough', function(t) { var pt = new PassThrough(); pt.write(new Buffer('foog')); pt.write(new Buffer('bark')); pt.write(new Buffer('bazy')); pt.write(new Buffer('kuel')); pt.end(); t.equal(pt.read(5).toString(), 'foogb'); t.equal(pt.read(5).toString(), 'arkba'); t.equal(pt.read(5).toString(), 'zykue'); t.equal(pt.read(5).toString(), 'l'); t.end(); }); t.test('object passthrough', function(t) { var pt = new PassThrough({ objectMode: true }); pt.write(1); pt.write(true); pt.write(false); pt.write(0); pt.write('foo'); pt.write(''); pt.write({ a: 'b'}); pt.end(); t.equal(pt.read(), 1); t.equal(pt.read(), true); t.equal(pt.read(), false); t.equal(pt.read(), 0); t.equal(pt.read(), 'foo'); t.equal(pt.read(), ''); t.same(pt.read(), { a: 'b'}); t.end(); }); t.test('simple transform', function(t) { var pt = new Transform(); pt._transform = function(c, e, cb) { var ret = new Buffer(c.length); ret.fill('x'); pt.push(ret); cb(); }; pt.write(new Buffer('foog')); pt.write(new Buffer('bark')); pt.write(new Buffer('bazy')); pt.write(new Buffer('kuel')); pt.end(); t.equal(pt.read(5).toString(), 'xxxxx'); t.equal(pt.read(5).toString(), 'xxxxx'); t.equal(pt.read(5).toString(), 'xxxxx'); t.equal(pt.read(5).toString(), 'x'); t.end(); }); t.test('simple object transform', function(t) { var pt = new Transform({ objectMode: true }); pt._transform = function(c, e, cb) { pt.push(JSON.stringify(c)); cb(); }; pt.write(1); pt.write(true); pt.write(false); pt.write(0); pt.write('foo'); pt.write(''); pt.write({ a: 'b'}); pt.end(); t.equal(pt.read(), '1'); t.equal(pt.read(), 'true'); t.equal(pt.read(), 'false'); t.equal(pt.read(), '0'); t.equal(pt.read(), '"foo"'); t.equal(pt.read(), '""'); t.equal(pt.read(), '{"a":"b"}'); t.end(); }); t.test('async passthrough', function(t) { var pt = new Transform(); pt._transform = function(chunk, encoding, cb) { setTimeout(function() { pt.push(chunk); cb(); }, 10); }; pt.write(new Buffer('foog')); pt.write(new Buffer('bark')); pt.write(new Buffer('bazy')); pt.write(new Buffer('kuel')); pt.end(); pt.on('finish', function() { t.equal(pt.read(5).toString(), 'foogb'); t.equal(pt.read(5).toString(), 'arkba'); t.equal(pt.read(5).toString(), 'zykue'); t.equal(pt.read(5).toString(), 'l'); t.end(); }); }); t.test('assymetric transform (expand)', function(t) { var pt = new Transform(); // emit each chunk 2 times. pt._transform = function(chunk, encoding, cb) { setTimeout(function() { pt.push(chunk); setTimeout(function() { pt.push(chunk); cb(); }, 10); }, 10); }; pt.write(new Buffer('foog')); pt.write(new Buffer('bark')); pt.write(new Buffer('bazy')); pt.write(new Buffer('kuel')); pt.end(); pt.on('finish', function() { t.equal(pt.read(5).toString(), 'foogf'); t.equal(pt.read(5).toString(), 'oogba'); t.equal(pt.read(5).toString(), 'rkbar'); t.equal(pt.read(5).toString(), 'kbazy'); t.equal(pt.read(5).toString(), 'bazyk'); t.equal(pt.read(5).toString(), 'uelku'); t.equal(pt.read(5).toString(), 'el'); t.end(); }); }); t.test('assymetric transform (compress)', function(t) { var pt = new Transform(); // each output is the first char of 3 consecutive chunks, // or whatever's left. pt.state = ''; pt._transform = function(chunk, encoding, cb) { if (!chunk) chunk = ''; var s = chunk.toString(); setTimeout(function() { this.state += s.charAt(0); if (this.state.length === 3) { pt.push(new Buffer(this.state)); this.state = ''; } cb(); }.bind(this), 10); }; pt._flush = function(cb) { // just output whatever we have. pt.push(new Buffer(this.state)); this.state = ''; cb(); }; pt.write(new Buffer('aaaa')); pt.write(new Buffer('bbbb')); pt.write(new Buffer('cccc')); pt.write(new Buffer('dddd')); pt.write(new Buffer('eeee')); pt.write(new Buffer('aaaa')); pt.write(new Buffer('bbbb')); pt.write(new Buffer('cccc')); pt.write(new Buffer('dddd')); pt.write(new Buffer('eeee')); pt.write(new Buffer('aaaa')); pt.write(new Buffer('bbbb')); pt.write(new Buffer('cccc')); pt.write(new Buffer('dddd')); pt.end(); // 'abcdeabcdeabcd' pt.on('finish', function() { t.equal(pt.read(5).toString(), 'abcde'); t.equal(pt.read(5).toString(), 'abcde'); t.equal(pt.read(5).toString(), 'abcd'); t.end(); }); }); // this tests for a stall when data is written to a full stream // that has empty transforms. t.test('complex transform', function(t) { var count = 0; var saved = null; var pt = new Transform({highWaterMark:3}); pt._transform = function(c, e, cb) { if (count++ === 1) saved = c; else { if (saved) { pt.push(saved); saved = null; } pt.push(c); } cb(); }; pt.once('readable', function() { process.nextTick(function() { pt.write(new Buffer('d')); pt.write(new Buffer('ef'), function() { pt.end(); t.end(); }); t.equal(pt.read().toString(), 'abcdef'); t.equal(pt.read(), null); }); }); pt.write(new Buffer('abc')); }); t.test('passthrough event emission', function(t) { var pt = new PassThrough(); var emits = 0; pt.on('readable', function() { var state = pt._readableState; //console.error('>>> emit readable %d', emits); emits++; }); var i = 0; pt.write(new Buffer('foog')); //console.error('need emit 0'); pt.write(new Buffer('bark')); //console.error('should have emitted readable now 1 === %d', emits); t.equal(emits, 1); t.equal(pt.read(5).toString(), 'foogb'); t.equal(pt.read(5) + '', 'null'); //console.error('need emit 1'); pt.write(new Buffer('bazy')); //console.error('should have emitted, but not again'); pt.write(new Buffer('kuel')); //console.error('should have emitted readable now 2 === %d', emits); t.equal(emits, 2); t.equal(pt.read(5).toString(), 'arkba'); t.equal(pt.read(5).toString(), 'zykue'); t.equal(pt.read(5), null); //console.error('need emit 2'); pt.end(); t.equal(emits, 3); t.equal(pt.read(5).toString(), 'l'); t.equal(pt.read(5), null); //console.error('should not have emitted again'); t.equal(emits, 3); t.end(); }); t.test('passthrough event emission reordered', function(t) { var pt = new PassThrough(); var emits = 0; pt.on('readable', function() { //console.error('emit readable', emits); emits++; }); pt.write(new Buffer('foog')); //console.error('need emit 0'); pt.write(new Buffer('bark')); //console.error('should have emitted readable now 1 === %d', emits); t.equal(emits, 1); t.equal(pt.read(5).toString(), 'foogb'); t.equal(pt.read(5), null); //console.error('need emit 1'); pt.once('readable', function() { t.equal(pt.read(5).toString(), 'arkba'); t.equal(pt.read(5), null); //console.error('need emit 2'); pt.once('readable', function() { t.equal(pt.read(5).toString(), 'zykue'); t.equal(pt.read(5), null); pt.once('readable', function() { t.equal(pt.read(5).toString(), 'l'); t.equal(pt.read(5), null); t.equal(emits, 4); t.end(); }); pt.end(); }); pt.write(new Buffer('kuel')); }); pt.write(new Buffer('bazy')); }); t.test('passthrough facaded', function(t) { //console.error('passthrough facaded'); var pt = new PassThrough(); var datas = []; pt.on('data', function(chunk) { datas.push(chunk.toString()); }); pt.on('end', function() { t.same(datas, ['foog', 'bark', 'bazy', 'kuel']); t.end(); }); pt.write(new Buffer('foog')); setTimeout(function() { pt.write(new Buffer('bark')); setTimeout(function() { pt.write(new Buffer('bazy')); setTimeout(function() { pt.write(new Buffer('kuel')); setTimeout(function() { pt.end(); }, 10); }, 10); }, 10); }, 10); }); t.test('object transform (json parse)', function(t) { //console.error('json parse stream'); var jp = new Transform({ objectMode: true }); jp._transform = function(data, encoding, cb) { try { jp.push(JSON.parse(data)); cb(); } catch (er) { cb(er); } }; // anything except null/undefined is fine. // those are "magic" in the stream API, because they signal EOF. var objects = [ { foo: 'bar' }, 100, 'string', { nested: { things: [ { foo: 'bar' }, 100, 'string' ] } } ]; var ended = false; jp.on('end', function() { ended = true; }); forEach(objects, function(obj) { jp.write(JSON.stringify(obj)); var res = jp.read(); t.same(res, obj); }); jp.end(); // read one more time to get the 'end' event jp.read(); process.nextTick(function() { t.ok(ended); t.end(); }); }); t.test('object transform (json stringify)', function(t) { //console.error('json parse stream'); var js = new Transform({ objectMode: true }); js._transform = function(data, encoding, cb) { try { js.push(JSON.stringify(data)); cb(); } catch (er) { cb(er); } }; // anything except null/undefined is fine. // those are "magic" in the stream API, because they signal EOF. var objects = [ { foo: 'bar' }, 100, 'string', { nested: { things: [ { foo: 'bar' }, 100, 'string' ] } } ]; var ended = false; js.on('end', function() { ended = true; }); forEach(objects, function(obj) { js.write(obj); var res = js.read(); t.equal(res, JSON.stringify(obj)); }); js.end(); // read one more time to get the 'end' event js.read(); process.nextTick(function() { t.ok(ended); t.end(); }); }); function forEach (xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } }; readable-stream-2.3.3/test/browser/test-stream2-unpipe-drain.js000066400000000000000000000026141312520600100244630ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); var crypto = require('crypto'); var inherits = require('inherits'); module.exports = function (t) { t.test('unpipe drain', function (t) { try { crypto.randomBytes(9); } catch(_) { t.ok(true, 'does not suport random, skipping'); return t.end(); } function TestWriter() { stream.Writable.call(this); } inherits(TestWriter, stream.Writable); TestWriter.prototype._write = function(buffer, encoding, callback) { //console.log('write called'); // super slow write stream (callback never called) }; var dest = new TestWriter(); function TestReader(id) { stream.Readable.call(this); this.reads = 0; } inherits(TestReader, stream.Readable); TestReader.prototype._read = function(size) { this.reads += 1; this.push(crypto.randomBytes(size)); }; var src1 = new TestReader(); var src2 = new TestReader(); src1.pipe(dest); src1.once('readable', function() { process.nextTick(function() { src2.pipe(dest); src2.once('readable', function() { process.nextTick(function() { src1.unpipe(dest); }); }); }); }); dest.on('unpipe', function() { t.equal(src1.reads, 2); t.equal(src2.reads, 2); t.end(); }); }); } readable-stream-2.3.3/test/browser/test-stream2-writable.js000066400000000000000000000202641312520600100237020ustar00rootroot00000000000000'use strict'; var common = require('../common'); var W = require('../../lib/_stream_writable'); var D = require('../../lib/_stream_duplex'); var inherits = require('inherits'); inherits(TestWriter, W); function TestWriter() { W.apply(this, arguments); this.buffer = []; this.written = 0; } TestWriter.prototype._write = function(chunk, encoding, cb) { // simulate a small unpredictable latency setTimeout(function() { this.buffer.push(chunk.toString()); this.written += chunk.length; cb(); }.bind(this), Math.floor(Math.random() * 10)); }; inherits(Processstdout, W); function Processstdout() { W.apply(this, arguments); this.buffer = []; this.written = 0; } Processstdout.prototype._write = function(chunk, encoding, cb) { //console.log(chunk.toString()); cb(); }; var chunks = new Array(50); for (var i = 0; i < chunks.length; i++) { chunks[i] = new Array(i + 1).join('x'); } module.exports = function (t) { var test = t.test; if (!process.stdout) { process.stdout = new Processstdout(); } test('write fast', function(t) { var tw = new TestWriter({ highWaterMark: 100 }); tw.on('finish', function() { t.same(tw.buffer, chunks, 'got chunks in the right order'); t.end(); }); forEach(chunks, function(chunk) { // screw backpressure. Just buffer it all up. tw.write(chunk); }); tw.end(); }); test('write slow', function(t) { var tw = new TestWriter({ highWaterMark: 100 }); tw.on('finish', function() { t.same(tw.buffer, chunks, 'got chunks in the right order'); t.end(); }); var i = 0; (function W() { tw.write(chunks[i++]); if (i < chunks.length) setTimeout(W, 10); else tw.end(); })(); }); test('write backpressure', function(t) { var tw = new TestWriter({ highWaterMark: 50 }); var drains = 0; tw.on('finish', function() { t.same(tw.buffer, chunks, 'got chunks in the right order'); t.equal(drains, 17); t.end(); }); tw.on('drain', function() { drains++; }); var i = 0; (function W() { do { var ret = tw.write(chunks[i++]); } while (ret !== false && i < chunks.length); if (i < chunks.length) { t.ok(tw._writableState.length >= 50); tw.once('drain', W); } else { tw.end(); } })(); }); test('write bufferize', function(t) { var tw = new TestWriter({ highWaterMark: 100 }); var encodings = [ 'hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', undefined ]; tw.on('finish', function() { t.same(tw.buffer, chunks, 'got the expected chunks'); }); forEach(chunks, function(chunk, i) { var enc = encodings[ i % encodings.length ]; chunk = new Buffer(chunk); tw.write(chunk.toString(enc), enc); }); t.end(); }); test('write no bufferize', function(t) { var tw = new TestWriter({ highWaterMark: 100, decodeStrings: false }); tw._write = function(chunk, encoding, cb) { t.equals(typeof chunk, 'string'); chunk = new Buffer(chunk, encoding); return TestWriter.prototype._write.call(this, chunk, encoding, cb); }; var encodings = [ 'hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', undefined ]; tw.on('finish', function() { t.same(tw.buffer, chunks, 'got the expected chunks'); }); forEach(chunks, function(chunk, i) { var enc = encodings[ i % encodings.length ]; chunk = new Buffer(chunk); tw.write(chunk.toString(enc), enc); }); t.end(); }); test('write callbacks', function(t) { var callbacks = chunks.map(function(chunk, i) { return [i, function(er) { callbacks._called[i] = chunk; }]; }).reduce(function(set, x) { set['callback-' + x[0]] = x[1]; return set; }, {}); callbacks._called = []; var tw = new TestWriter({ highWaterMark: 100 }); tw.on('finish', function() { process.nextTick(function() { t.same(tw.buffer, chunks, 'got chunks in the right order'); t.same(callbacks._called, chunks, 'called all callbacks'); t.end(); }); }); forEach(chunks, function(chunk, i) { tw.write(chunk, callbacks['callback-' + i]); }); tw.end(); }); test('end callback', function(t) { var tw = new TestWriter(); tw.end(function() { t.end(); }); }); test('end callback with chunk', function(t) { var tw = new TestWriter(); tw.end(new Buffer('hello world'), function() { t.end(); }); }); test('end callback with chunk and encoding', function(t) { var tw = new TestWriter(); tw.end('hello world', 'ascii', function() { t.end(); }); }); test('end callback after .write() call', function(t) { var tw = new TestWriter(); tw.write(new Buffer('hello world')); tw.end(function() { t.end(); }); }); test('end callback called after write callback', function(t) { var tw = new TestWriter(); var writeCalledback = false; tw.write(new Buffer('hello world'), function() { writeCalledback = true; }); tw.end(function() { t.equal(writeCalledback, true); t.end(); }); }); test('encoding should be ignored for buffers', function(t) { var tw = new W(); var hex = '018b5e9a8f6236ffe30e31baf80d2cf6eb'; tw._write = function(chunk, encoding, cb) { t.equal(chunk.toString('hex'), hex); t.end(); }; var buf = new Buffer(hex, 'hex'); tw.write(buf, 'binary'); }); test('writables are not pipable', function(t) { var w = new W(); w._write = function() {}; var gotError = false; w.on('error', function(er) { gotError = true; }); w.pipe(process.stdout); t.ok(gotError); t.end(); }); test('duplexes are pipable', function(t) { var d = new D(); d._read = function() {}; d._write = function() {}; var gotError = false; d.on('error', function(er) { gotError = true; }); d.pipe(process.stdout); t.ok(!gotError); t.end(); }); test('end(chunk) two times is an error', function(t) { var w = new W(); w._write = function() {}; var gotError = false; w.on('error', function(er) { gotError = true; t.equal(er.message, 'write after end'); }); w.end('this is the end'); w.end('and so is this'); process.nextTick(function() { t.ok(gotError); t.end(); }); }); test('dont end while writing', function(t) { var w = new W(); var wrote = false; w._write = function(chunk, e, cb) { t.ok(!this.writing); wrote = true; this.writing = true; setTimeout(function() { this.writing = false; cb(); }); }; w.on('finish', function() { t.ok(wrote); t.end(); }); w.write(Buffer(0)); w.end(); }); test('finish does not come before write cb', function(t) { var w = new W(); var writeCb = false; w._write = function(chunk, e, cb) { setTimeout(function() { writeCb = true; cb(); }, 10); }; w.on('finish', function() { t.ok(writeCb); t.end(); }); w.write(Buffer(0)); w.end(); }); test('finish does not come before sync _write cb', function(t) { var w = new W(); var writeCb = false; w._write = function(chunk, e, cb) { cb(); }; w.on('finish', function() { t.ok(writeCb); t.end(); }); w.write(Buffer(0), function(er) { writeCb = true; }); w.end(); }); test('finish is emitted if last chunk is empty', function(t) { var w = new W(); w._write = function(chunk, e, cb) { process.nextTick(cb); }; w.on('finish', function() { t.end(); }); w.write(Buffer(1)); w.end(Buffer(0)); }); function forEach (xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } } readable-stream-2.3.3/test/browser/test-stream3-pause-then-read.js000066400000000000000000000070641312520600100250570ustar00rootroot00000000000000'use strict'; var common = require('../common'); var stream = require('../../'); var Readable = stream.Readable; var Writable = stream.Writable; module.exports = function (t){ t.test('pause then read', function (t) { var totalChunks = 100; var chunkSize = 99; var expectTotalData = totalChunks * chunkSize; var expectEndingData = expectTotalData; var r = new Readable({ highWaterMark: 1000 }); var chunks = totalChunks; r._read = function(n) { if (!(chunks % 2)) setImmediate(push); else if (!(chunks % 3)) process.nextTick(push); else push(); }; var totalPushed = 0; function push() { var chunk = chunks-- > 0 ? new Buffer(chunkSize) : null; if (chunk) { totalPushed += chunk.length; chunk.fill('x'); } r.push(chunk); } read100(); // first we read 100 bytes function read100() { readn(100, onData); } function readn(n, then) { //console.error('read %d', n); expectEndingData -= n; ;(function read() { var c = r.read(n); if (!c) r.once('readable', read); else { t.equal(c.length, n); t.notOk(r._readableState.flowing); then(); } })(); } // then we listen to some data events function onData() { expectEndingData -= 100; //console.error('onData'); var seen = 0; r.on('data', function od(c) { seen += c.length; if (seen >= 100) { // seen enough r.removeListener('data', od); r.pause(); if (seen > 100) { // oh no, seen too much! // put the extra back. var diff = seen - 100; r.unshift(c.slice(c.length - diff)); console.error('seen too much', seen, diff); } // Nothing should be lost in between setImmediate(pipeLittle); } }); } // Just pipe 200 bytes, then unshift the extra and unpipe function pipeLittle() { expectEndingData -= 200; //console.error('pipe a little'); var w = new Writable(); var written = 0; w.on('finish', function() { t.equal(written, 200); setImmediate(read1234); }); w._write = function(chunk, encoding, cb) { written += chunk.length; if (written >= 200) { r.unpipe(w); w.end(); cb(); if (written > 200) { var diff = written - 200; written -= diff; r.unshift(chunk.slice(chunk.length - diff)); } } else { setImmediate(cb); } }; r.pipe(w); } // now read 1234 more bytes function read1234() { readn(1234, resumePause); } function resumePause() { //console.error('resumePause'); // don't read anything, just resume and re-pause a whole bunch r.resume(); r.pause(); r.resume(); r.pause(); r.resume(); r.pause(); r.resume(); r.pause(); r.resume(); r.pause(); setImmediate(pipe); } function pipe() { //console.error('pipe the rest'); var w = new Writable(); var written = 0; w._write = function(chunk, encoding, cb) { written += chunk.length; cb(); }; w.on('finish', function() { //console.error('written', written, totalPushed); t.equal(written, expectEndingData); t.equal(totalPushed, expectTotalData); t.end(); }); r.pipe(w); } }); } readable-stream-2.3.3/test/common.js000066400000000000000000000634471312520600100173600ustar00rootroot00000000000000function _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'); for (var i in util) { exports[i] = util[i]; } /**/ /**/ if (!global.setImmediate) { global.setImmediate = function setImmediate(fn) { return setTimeout(fn.bind.apply(fn, arguments), 4); }; } if (!global.clearImmediate) { global.clearImmediate = function clearImmediate(i) { return clearTimeout(i); }; } /**/ // 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'; /**/ var objectKeys = objectKeys || function (obj) { var keys = []; for (var key in obj) { keys.push(key); }return keys; }; /**/ var path = require('path'); var fs = require('fs'); 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'); 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) : path.resolve(__dirname, '..'); 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; exports.isWindows = process.platform === 'win32'; exports.isWOW64 = exports.isWindows && process.env.PROCESSOR_ARCHITEW6432 !== undefined; exports.isAix = process.platform === 'aix'; exports.isLinuxPPCBE = process.platform === 'linux' && process.arch === 'ppc64' && os.endianness() === 'BE'; exports.isSunOS = process.platform === 'sunos'; exports.isFreeBSD = process.platform === 'freebsd'; 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);*/ 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 { st = fs.lstatSync(p); } catch (e) { if (e.code === 'ENOENT') return; } try { if (st && st.isDirectory()) rmdirSync(p, null);else fs.unlinkSync(p); } catch (e) { if (e.code === 'ENOENT') return; if (e.code === 'EPERM') return rmdirSync(p, e); if (e.code !== 'EISDIR') throw e; rmdirSync(p, e); } } function rmdirSync(p, originalEr) { try { fs.rmdirSync(p); } catch (e) { if (e.code === 'ENOTDIR') throw originalEr; if (e.code === 'ENOTEMPTY' || e.code === 'EEXIST' || e.code === 'EPERM') { var enc = exports.isLinux ? 'buffer' : 'utf8'; fs.readdirSync(p, forEach(enc), function (f) { if (f instanceof Buffer) { var buf = Buffer.concat([Buffer.from(p), Buffer.from(path.sep), f]); rimrafSync(buf); } else { rimrafSync(path.join(p, f)); } }); fs.rmdirSync(p); } } } exports.refreshTmpDir = function () { rimrafSync(exports.tmpDir); fs.mkdirSync(exports.tmpDir); }; if (process.env.TEST_THREAD_ID) { exports.PORT += process.env.TEST_THREAD_ID * 100; exports.tmpDirName += '.' + process.env.TEST_THREAD_ID; } exports.tmpDir = path.join(testRoot, exports.tmpDirName); var opensslCli = null; var inFreeBSDJail = null; var localhostIPv4 = null; exports.localIPv6Hosts = ['localhost']; if (exports.isLinux) { exports.localIPv6Hosts = [ // Debian/Ubuntu 'ip6-localhost', 'ip6-loopback', // SUSE 'ipv6-localhost', 'ipv6-loopback', // Typically universal 'localhost']; } /**/if (!process.browser) { Object.defineProperty(exports, 'inFreeBSDJail', { get: function () { if (inFreeBSDJail !== null) return inFreeBSDJail; if (exports.isFreeBSD && child_process.execSync('sysctl -n security.jail.jailed').toString() === '1\n') { inFreeBSDJail = true; } else { inFreeBSDJail = false; } return inFreeBSDJail; } }); } /**/ /**/if (!process.browser) { Object.defineProperty(exports, 'localhostIPv4', { get: function () { if (localhostIPv4 !== null) return localhostIPv4; if (exports.inFreeBSDJail) { // Jailed network interfaces are a bit special - since we need to jump // through loops, as well as this being an exception case, assume the // user will provide this instead. if (process.env.LOCALHOST) { localhostIPv4 = process.env.LOCALHOST; } else { console.error('Looks like we\'re in a FreeBSD Jail. ' + 'Please provide your default interface address ' + 'as LOCALHOST or expect some tests to fail.'); } } if (localhostIPv4 === null) localhostIPv4 = '127.0.0.1'; return localhostIPv4; } }); } /**/ // opensslCli defined lazily to reduce overhead of spawnSync /**/if (!process.browser) { Object.defineProperty(exports, 'opensslCli', { get: function () { if (opensslCli !== null) return opensslCli; if (process.config.variables.node_shared_openssl) { // use external command opensslCli = 'openssl'; } else { // use command built from sources included in Node.js repository opensslCli = path.join(path.dirname(process.execPath), 'openssl-cli'); } if (exports.isWindows) opensslCli += '.exe'; var opensslCmd = child_process.spawnSync(opensslCli, ['version']); if (opensslCmd.status !== 0 || opensslCmd.error !== undefined) { // openssl command cannot be executed opensslCli = false; } return opensslCli; }, enumerable: true }); } /**/ /**/if (!process.browser) { Object.defineProperty(exports, 'hasCrypto', { get: function () { return process.versions.openssl ? true : false; } }); } /**/ /**/if (!process.browser) { Object.defineProperty(exports, 'hasFipsCrypto', { get: function () { return exports.hasCrypto && require('crypto').fips; } }); } /**/ if (exports.isWindows) { exports.PIPE = '\\\\.\\pipe\\libuv-test'; if (process.env.TEST_THREAD_ID) { exports.PIPE += '.' + process.env.TEST_THREAD_ID; } } else { exports.PIPE = exports.tmpDir + '/test.sock'; } var ifaces = os.networkInterfaces(); var re = /lo/; exports.hasIPv6 = objectKeys(ifaces).some(function (name) { return re.test(name) && ifaces[name].some(function (info) { return info.family === 'IPv6'; }); }); /* * Check that when running a test with * `$node --abort-on-uncaught-exception $file child` * the process aborts. */ exports.childShouldThrowAndAbort = function () { var testCmd = ''; if (!exports.isWindows) { // Do not create core files, as it can take a lot of disk space on // continuous testing and developers' machines testCmd += 'ulimit -c 0 && '; } 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); assert(exports.nodeProcessAborted(exitCode, signal), errMsg); }); }; exports.ddCommand = function (filename, kilobytes) { if (exports.isWindows) { var p = path.resolve(exports.fixturesDir, 'create-file.js'); return '"' + process.argv[0] + '" "' + p + '" "' + filename + '" ' + kilobytes * 1024; } else { return 'dd if=/dev/zero of="' + filename + '" bs=1024 count=' + kilobytes; } }; exports.spawnPwd = function (options) { var spawn = require('child_process').spawn; if (exports.isWindows) { return spawn('cmd.exe', ['/d', '/c', 'cd'], options); } else { return spawn('pwd', [], options); } }; exports.spawnSyncPwd = function (options) { var spawnSync = require('child_process').spawnSync; if (exports.isWindows) { return spawnSync('cmd.exe', ['/d', '/c', 'cd'], options); } else { return spawnSync('pwd', [], options); } }; exports.platformTimeout = function (ms) { if (process.config.target_defaults.default_configuration === 'Debug') ms = 2 * ms; if (global.__coverage__) ms = 4 * ms; if (exports.isAix) return 2 * ms; // default localhost speed is slower on AIX if (process.arch !== 'arm') return ms; var armv = process.config.variables.arm_version; if (armv === '6') return 7 * ms; // ARMv6 if (armv === '7') return 2 * ms; // ARMv7 return ms; // ARMv8+ }; var knownGlobals = [Buffer, clearImmediate, clearInterval, clearTimeout, console, constructor, // Enumerable in V8 3.21. global, process, setImmediate, setInterval, setTimeout]; if (global.gc) { knownGlobals.push(global.gc); } if (global.DTRACE_HTTP_SERVER_RESPONSE) { knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE); knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST); knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE); knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST); knownGlobals.push(DTRACE_NET_STREAM_END); knownGlobals.push(DTRACE_NET_SERVER_CONNECTION); } if (global.COUNTER_NET_SERVER_CONNECTION) { knownGlobals.push(COUNTER_NET_SERVER_CONNECTION); knownGlobals.push(COUNTER_NET_SERVER_CONNECTION_CLOSE); knownGlobals.push(COUNTER_HTTP_SERVER_REQUEST); knownGlobals.push(COUNTER_HTTP_SERVER_RESPONSE); knownGlobals.push(COUNTER_HTTP_CLIENT_REQUEST); knownGlobals.push(COUNTER_HTTP_CLIENT_RESPONSE); } if (global.LTTNG_HTTP_SERVER_RESPONSE) { knownGlobals.push(LTTNG_HTTP_SERVER_RESPONSE); knownGlobals.push(LTTNG_HTTP_SERVER_REQUEST); knownGlobals.push(LTTNG_HTTP_CLIENT_RESPONSE); knownGlobals.push(LTTNG_HTTP_CLIENT_REQUEST); knownGlobals.push(LTTNG_NET_STREAM_END); knownGlobals.push(LTTNG_NET_SERVER_CONNECTION); } /**/if (!process.browser) { if (global.ArrayBuffer) { knownGlobals.push(ArrayBuffer); knownGlobals.push(Int8Array); knownGlobals.push(Uint8Array); knownGlobals.push(Uint8ClampedArray); knownGlobals.push(Int16Array); knownGlobals.push(Uint16Array); knownGlobals.push(Int32Array); knownGlobals.push(Uint32Array); knownGlobals.push(Float32Array); knownGlobals.push(Float64Array); knownGlobals.push(DataView); } } /**/ // Harmony features. if (global.Proxy) { knownGlobals.push(Proxy); } if (global.Symbol) { knownGlobals.push(Symbol); } function allowGlobals() { for (var _len = arguments.length, whitelist = Array(_len), _key = 0; _key < _len; _key++) { whitelist[_key] = arguments[_key]; } knownGlobals = knownGlobals.concat(whitelist); } exports.allowGlobals = allowGlobals; /**/ if (typeof constructor == 'function') knownGlobals.push(constructor); if (typeof DTRACE_NET_SOCKET_READ == 'function') knownGlobals.push(DTRACE_NET_SOCKET_READ); if (typeof DTRACE_NET_SOCKET_WRITE == 'function') knownGlobals.push(DTRACE_NET_SOCKET_WRITE); if (global.__coverage__) knownGlobals.push(__coverage__); 'core,__core-js_shared__,Promise,Map,Set,WeakMap,WeakSet,Reflect,System,asap,Observable,regeneratorRuntime,_babelPolyfill'.split(',').filter(function (item) { return typeof global[item] !== undefined; }).forEach(function (item) { knownGlobals.push(global[item]); }); /**/ function leakedGlobals() { var leaked = []; // eslint-disable-next-line no-var for (var val in global) { if (!knownGlobals.includes(global[val])) leaked.push(val); }if (global.__coverage__) { return leaked.filter(function (varname) { return !/^(?:cov_|__cov)/.test(varname); }); } else { return leaked; } } exports.leakedGlobals = leakedGlobals; // Turn this off if the test should not check for global leaks. exports.globalCheck = true; process.on('exit', function () { if (!exports.globalCheck) return; var leaked = leakedGlobals(); if (leaked.length > 0) { assert.fail('Unexpected global(s) found: ' + leaked.join(', ')); } }); var mustCallChecks = []; function runCallChecks(exitCode) { if (exitCode !== 0) return; var failed = mustCallChecks.filter(function (context) { 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 %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, exact) { return _mustCallInner(fn, exact, 'exact'); }; exports.mustCallAtLeast = function (fn, minimum) { return _mustCallInner(fn, minimum, 'minimum'); }; function _mustCallInner(fn, criteria, field) { var _context; 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); mustCallChecks.push(context); return function () { context.actual++; return fn.apply(this, arguments); }; } exports.hasMultiLocalhost = function hasMultiLocalhost() { var TCP = process.binding('tcp_wrap').TCP; var t = new TCP(); var ret = t.bind('127.0.0.2', exports.PORT); t.close(); return ret === 0; }; exports.fileExists = function (pathname) { try { fs.accessSync(pathname); return true; } catch (err) { return false; } }; exports.canCreateSymLink = function () { // On Windows, creating symlinks requires admin privileges. // We'll only try to run symlink test if we have enough privileges. // On other platforms, creating symlinks shouldn't need admin privileges if (exports.isWindows) { // whoami.exe needs to be the one from System32 // If unix tools are in the path, they can shadow the one we want, // so use the full path while executing whoami var whoamiPath = path.join(process.env['SystemRoot'], 'System32', 'whoami.exe'); var err = false; var output = ''; try { output = execSync(whoamiPath + ' /priv', { timout: 1000 }); } catch (e) { err = true; } finally { if (err || !output.includes('SeCreateSymbolicLinkPrivilege')) { return false; } } } return true; }; exports.mustNotCall = function (msg) { return function mustNotCall() { assert.fail(msg || 'function should not have been called'); }; }; exports.skip = function (msg) { console.log('1..0 # Skipped: ' + msg); }; // A stream to push an array into a REPL function ArrayStream() { this.run = function (data) { var _this = this; forEach(data, function (line) { _this.emit('data', line + '\n'); }); }; } util.inherits(ArrayStream, stream.Stream); exports.ArrayStream = ArrayStream; ArrayStream.prototype.readable = true; ArrayStream.prototype.writable = true; 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, // false otherwise. exports.nodeProcessAborted = function nodeProcessAborted(exitCode, signal) { // Depending on the compiler used, node will exit with either // exit code 132 (SIGILL), 133 (SIGTRAP) or 134 (SIGABRT). var expectedExitCodes = [132, 133, 134]; // On platforms using KSH as the default shell (like SmartOS), // when a process aborts, KSH exits with an exit code that is // greater than 256, and thus the exit code emitted with the 'exit' // event is null and the signal is set to either SIGILL, SIGTRAP, // or SIGABRT (depending on the compiler). var expectedSignals = ['SIGILL', 'SIGTRAP', 'SIGABRT']; // 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) // (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. // Depending on the compiler used, the shell or other aspects of // the platform used to build the node binary, this will actually // make V8 exit by aborting or by raising a signal. In any case, // one of them (exit code or signal) needs to be set to one of // the expected exit codes or signals. if (signal !== null) { return expectedSignals.includes(signal); } else { return expectedExitCodes.includes(exitCode); } }; exports.busyLoop = function busyLoop(time) { var startTime = Timer.now(); var stopTime = startTime + time; while (Timer.now() < stopTime) {} }; exports.isAlive = function isAlive(pid) { try { process.kill(pid, 'SIGCONT'); return true; } catch (e) { return false; } }; function expectWarning(name, expectedMessages) { return exports.mustCall(function (warning) { assert.strictEqual(warning.name, name); assert.ok(expectedMessages.includes(warning.message), 'unexpected error message: "' + warning.message + '"'); // Remove a warning message after it is seen so that we guarantee that we // get each message only once. expectedMessages.splice(expectedMessages.indexOf(warning.message), 1); }, expectedMessages.length); } function expectWarningByName(name, expected) { if (typeof expected === 'string') { expected = [expected]; } process.on('warning', expectWarning(name, expected)); } function expectWarningByMap(warningMap) { var catchWarning = {}; forEach(objectKeys(warningMap), function (name) { var expected = warningMap[name]; if (typeof expected === 'string') { expected = [expected]; } catchWarning[name] = expectWarning(name, expected); }); process.on('warning', function (warning) { return catchWarning[warning.name](warning); }); } // accepts a warning name and description or array of descriptions or a map // of warning names to description(s) // ensures a warning is generated for each name/description pair exports.expectWarning = function (nameOrMap, expected) { if (typeof nameOrMap === 'string') { expectWarningByName(nameOrMap, expected); } else { expectWarningByMap(nameOrMap); } }; /**/if (!process.browser) { Object.defineProperty(exports, 'hasIntl', { get: function () { return process.binding('config').hasIntl; } }); } /**/ /**/if (!process.browser) { Object.defineProperty(exports, 'hasSmallICU', { get: function () { return process.binding('config').hasSmallICU; } }); } /**/ // Useful for testing expected internal/error objects exports.expectsError = function expectsError(_ref) { var code = _ref.code, type = _ref.type, message = _ref.message; return function (error) { assert.strictEqual(error.code, code); if (type !== undefined) assert(error instanceof type, error + ' is not the expected type ' + type); if (message instanceof RegExp) { assert(message.test(error.message), error.message + ' does not match ' + message); } else if (typeof message === 'string') { assert.strictEqual(error.message, message); } return true; }; }; 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; }; // Hijack stdout and stderr var stdWrite = {}; function hijackStdWritable(name, listener) { var stream = process[name]; var _write = stdWrite[name] = stream.write; stream.writeTimes = 0; stream.write = function (data, callback) { listener(data); _write.call(stream, data, callback); stream.writeTimes++; }; } function restoreWritable(name) { process[name].write = stdWrite[name]; delete process[name].writeTimes; } exports.hijackStdout = hijackStdWritable.bind(null, 'stdout'); exports.hijackStderr = hijackStdWritable.bind(null, 'stderr'); exports.restoreStdout = restoreWritable.bind(null, 'stdout'); exports.restoreStderr = restoreWritable.bind(null, 'stderr'); function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } if (!util._errnoException) { var uv; util._errnoException = function (err, syscall) { if (util.isUndefined(uv)) try { uv = process.binding('uv'); } catch (e) {} var errname = uv ? uv.errname(err) : ''; var e = new Error(syscall + ' ' + errname); e.code = errname; e.errno = errname; e.syscall = syscall; return e; }; }readable-stream-2.3.3/test/fixtures/000077500000000000000000000000001312520600100173655ustar00rootroot00000000000000readable-stream-2.3.3/test/fixtures/x1024.txt000066400000000000000000000020001312520600100206740ustar00rootroot00000000000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxreadable-stream-2.3.3/test/ours/000077500000000000000000000000001312520600100165045ustar00rootroot00000000000000readable-stream-2.3.3/test/ours/test-stream-sync-write.js000066400000000000000000000014331312520600100234150ustar00rootroot00000000000000require('../common'); var util = require('util'); var stream = require('../../'); var WritableStream = stream.Writable; var InternalStream = function() { WritableStream.call(this); }; util.inherits(InternalStream, WritableStream); InternalStream.prototype._write = function(chunk, encoding, callback) { callback(); }; var internalStream = new InternalStream(); var ExternalStream = function(writable) { this._writable = writable; WritableStream.call(this); }; util.inherits(ExternalStream, WritableStream); ExternalStream.prototype._write = function(chunk, encoding, callback) { this._writable.write(chunk, encoding, callback); }; var externalStream = new ExternalStream(internalStream); for (var i = 0; i < 2000; i++) { externalStream.write(i.toString()); } readable-stream-2.3.3/test/parallel/000077500000000000000000000000001312520600100173105ustar00rootroot00000000000000readable-stream-2.3.3/test/parallel/test-stream-big-packet.js000066400000000000000000000054211312520600100241240ustar00rootroot00000000000000// 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 assert = require('assert/'); var util = require('util'); var stream = require('../../'); var passed = false; function PassThrough() { stream.Transform.call(this); } util.inherits(PassThrough, stream.Transform); PassThrough.prototype._transform = function (chunk, encoding, done) { this.push(chunk); done(); }; function TestStream() { stream.Transform.call(this); } util.inherits(TestStream, stream.Transform); TestStream.prototype._transform = function (chunk, encoding, done) { if (!passed) { // Char 'a' only exists in the last write passed = chunk.toString().includes('a'); } done(); }; var s1 = new PassThrough(); var s2 = new PassThrough(); var s3 = new TestStream(); s1.pipe(s3); // Don't let s2 auto close which may close s3 s2.pipe(s3, { end: false }); // We must write a buffer larger than highWaterMark var big = bufferShim.alloc(s1._writableState.highWaterMark + 1, 'x'); // Since big is larger than highWaterMark, it will be buffered internally. assert(!s1.write(big)); // 'tiny' is small enough to pass through internal buffer. assert(s2.write('tiny')); // Write some small data in next IO loop, which will never be written to s3 // Because 'drain' event is not emitted from s1 and s1 is still paused setImmediate(s1.write.bind(s1), 'later'); // Assert after two IO loops when all operations have been done. process.on('exit', function () { assert(passed, 'Large buffer is not handled properly by Writable Stream'); }); function indexOf(xs, x) { for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) return i; } return -1; }readable-stream-2.3.3/test/parallel/test-stream-big-push.js000066400000000000000000000045541312520600100236420ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); var str = 'asdfasdfasdfasdfasdf'; var r = new stream.Readable({ highWaterMark: 5, encoding: 'utf8' }); var reads = 0; function _read() { if (reads === 0) { setTimeout(function () { r.push(str); }, 1); reads++; } else if (reads === 1) { var _ret = r.push(str); assert.strictEqual(_ret, false); reads++; } else { r.push(null); } } r._read = common.mustCall(_read, 3); r.on('end', common.mustCall()); // push some data in to start. // we've never gotten any read event at this point. var ret = r.push(str); // should be false. > hwm assert(!ret); var chunk = r.read(); assert.strictEqual(chunk, str); chunk = r.read(); assert.strictEqual(chunk, null); r.once('readable', function () { // this time, we'll get *all* the remaining data, because // it's been added synchronously, as the read WOULD take // us below the hwm, and so it triggered a _read() again, // which synchronously added more, which we then return. chunk = r.read(); assert.strictEqual(chunk, str + str); chunk = r.read(); assert.strictEqual(chunk, null); });readable-stream-2.3.3/test/parallel/test-stream-buffer-list.js000066400000000000000000000014021312520600100243330ustar00rootroot00000000000000// Flags: --expose_internals /**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var assert = require('assert/'); var BufferList = require('../../lib/internal/streams/BufferList'); // Test empty buffer list. var emptyList = new BufferList(); emptyList.shift(); assert.deepStrictEqual(emptyList, new BufferList()); assert.strictEqual(emptyList.join(','), ''); assert.deepStrictEqual(emptyList.concat(0), bufferShim.alloc(0)); // Test buffer list with one element. var list = new BufferList(); list.push('foo'); assert.strictEqual(list.concat(1), 'foo'); assert.strictEqual(list.join(','), 'foo'); var shifted = list.shift(); assert.strictEqual(shifted, 'foo'); assert.deepStrictEqual(list, new BufferList());readable-stream-2.3.3/test/parallel/test-stream-decoder-objectmode.js000066400000000000000000000011511312520600100256300ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); var readable = new stream.Readable({ read: common.noop, encoding: 'utf16le', objectMode: true }); readable.push(bufferShim.from('abc', 'utf16le')); readable.push(bufferShim.from('def', 'utf16le')); readable.push(null); // Without object mode, these would be concatenated into a single chunk. assert.strictEqual(readable.read(), 'abc'); assert.strictEqual(readable.read(), 'def'); assert.strictEqual(readable.read(), null);readable-stream-2.3.3/test/parallel/test-stream-duplex-destroy.js000066400000000000000000000110771312520600100251120ustar00rootroot00000000000000/**/ 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(); }readable-stream-2.3.3/test/parallel/test-stream-duplex.js000066400000000000000000000034711312520600100234220ustar00rootroot00000000000000// 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 assert = require('assert/'); var Duplex = require('../../').Duplex; var stream = new Duplex({ objectMode: true }); assert(Duplex() instanceof Duplex); assert(stream._readableState.objectMode); assert(stream._writableState.objectMode); var written = void 0; var read = void 0; stream._write = function (obj, _, cb) { written = obj; cb(); }; stream._read = common.noop; stream.on('data', function (obj) { read = obj; }); stream.push({ val: 1 }); stream.end({ val: 2 }); process.on('exit', function () { assert.strictEqual(read.val, 1); assert.strictEqual(written.val, 2); });readable-stream-2.3.3/test/parallel/test-stream-end-paused.js000066400000000000000000000034551312520600100241500ustar00rootroot00000000000000// 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 assert = require('assert/'); // Make sure we don't miss the end event for paused 0-length streams var Readable = require('../../').Readable; var stream = new Readable(); var calledRead = false; stream._read = function () { assert(!calledRead); calledRead = true; this.push(null); }; stream.on('data', function () { throw new Error('should not ever get data'); }); stream.pause(); setTimeout(common.mustCall(function () { stream.on('end', common.mustCall()); stream.resume(); }), 1); process.on('exit', function () { assert(calledRead); console.log('ok'); });readable-stream-2.3.3/test/parallel/test-stream-events-prepend.js000066400000000000000000000012511312520600100250520ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var util = require('util'); function Writable() { this.writable = true; stream.Writable.call(this); this.prependListener = undefined; } util.inherits(Writable, stream.Writable); Writable.prototype._write = function (chunk, end, cb) { cb(); }; function Readable() { this.readable = true; stream.Readable.call(this); } util.inherits(Readable, stream.Readable); Readable.prototype._read = function () { this.push(null); }; var w = new Writable(); w.on('pipe', common.mustCall()); var r = new Readable(); r.pipe(w);readable-stream-2.3.3/test/parallel/test-stream-ispaused.js000066400000000000000000000032531312520600100237340ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); var readable = new stream.Readable(); // _read is a noop, here. readable._read = Function(); // default state of a stream is not "paused" assert.ok(!readable.isPaused()); // make the stream start flowing... readable.on('data', Function()); // still not paused. assert.ok(!readable.isPaused()); readable.pause(); assert.ok(readable.isPaused()); readable.resume(); assert.ok(!readable.isPaused());readable-stream-2.3.3/test/parallel/test-stream-objectmode-undefined.js000066400000000000000000000020171312520600100261660ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var _require = require('../../'), Readable = _require.Readable, Writable = _require.Writable, Transform = _require.Transform; { var stream = new Readable({ objectMode: true, read: common.mustCall(function () { stream.push(undefined); stream.push(null); }) }); stream.on('data', common.mustCall(function (chunk) { assert.strictEqual(chunk, undefined); })); } { var _stream = new Writable({ objectMode: true, write: common.mustCall(function (chunk) { assert.strictEqual(chunk, undefined); }) }); _stream.write(undefined); } { var _stream2 = new Transform({ objectMode: true, transform: common.mustCall(function (chunk) { _stream2.push(chunk); }) }); _stream2.on('data', common.mustCall(function (chunk) { assert.strictEqual(chunk, undefined); })); _stream2.write(undefined); }readable-stream-2.3.3/test/parallel/test-stream-pipe-after-end.js000066400000000000000000000050121312520600100247120ustar00rootroot00000000000000// 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 assert = require('assert/'); var Readable = require('../../lib/_stream_readable'); var Writable = require('../../lib/_stream_writable'); var util = require('util'); util.inherits(TestReadable, Readable); function TestReadable(opt) { if (!(this instanceof TestReadable)) return new TestReadable(opt); Readable.call(this, opt); this._ended = false; } TestReadable.prototype._read = function () { if (this._ended) this.emit('error', new Error('_read called twice')); this._ended = true; this.push(null); }; util.inherits(TestWritable, Writable); function TestWritable(opt) { if (!(this instanceof TestWritable)) return new TestWritable(opt); Writable.call(this, opt); this._written = []; } TestWritable.prototype._write = function (chunk, encoding, cb) { this._written.push(chunk); cb(); }; // this one should not emit 'end' until we read() from it later. var ender = new TestReadable(); // what happens when you pipe() a Readable that's already ended? var piper = new TestReadable(); // pushes EOF null, and length=0, so this will trigger 'end' piper.read(); setTimeout(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()); piper.pipe(w); }), 1);readable-stream-2.3.3/test/parallel/test-stream-pipe-await-drain-manual-resume.js000066400000000000000000000052121312520600100300200ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); // A consumer stream with a very low highWaterMark, which starts in a state // where it buffers the chunk it receives rather than indicating that they // have been consumed. var writable = new stream.Writable({ highWaterMark: 5 }); var isCurrentlyBufferingWrites = true; var queue = []; writable._write = function (chunk, encoding, cb) { if (isCurrentlyBufferingWrites) queue.push({ chunk: chunk, cb: cb });else cb(); }; var readable = new stream.Readable({ read: function () {} }); readable.pipe(writable); readable.once('pause', common.mustCall(function () { assert.strictEqual(readable._readableState.awaitDrain, 1, 'awaitDrain doesn\'t increase'); // First pause, resume manually. The next write() to writable will still // return false, because chunks are still being buffered, so it will increase // the awaitDrain counter again. process.nextTick(common.mustCall(function () { readable.resume(); })); readable.once('pause', common.mustCall(function () { assert.strictEqual(readable._readableState.awaitDrain, 1, '.resume() does not reset counter'); // Second pause, handle all chunks from now on. Once all callbacks that // are currently queued up are handled, the awaitDrain drain counter should // fall back to 0 and all chunks that are pending on the readable side // should be flushed. isCurrentlyBufferingWrites = false; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = queue[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var queued = _step.value; queued.cb(); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } })); })); readable.push(bufferShim.alloc(100)); // Fill the writable HWM, first 'pause'. readable.push(bufferShim.alloc(100)); // Second 'pause'. readable.push(bufferShim.alloc(100)); // Should get through to the writable. readable.push(null); writable.on('finish', common.mustCall(function () { assert.strictEqual(readable._readableState.awaitDrain, 0, 'awaitDrain not 0 after all chunks are written'); // Everything okay, all chunks were written. }));readable-stream-2.3.3/test/parallel/test-stream-pipe-await-drain-push-while-write.js000066400000000000000000000031131312520600100304600ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); var awaitDrainStates = [1, // after first chunk before callback 1, // after second chunk before callback 0 // resolving chunk pushed after first chunk, awaitDrain is decreased ]; // A writable stream which pushes data onto the stream which pipes into it, // but only the first time it's written to. Since it's not paused at this time, // a second write will occur. If the pipe increases awaitDrain twice, we'll // never get subsequent chunks because 'drain' is only emitted once. var writable = new stream.Writable({ write: common.mustCall(function (chunk, encoding, cb) { if (chunk.length === 32 * 1024) { // first chunk var beforePush = readable._readableState.awaitDrain; readable.push(bufferShim.alloc(34 * 1024)); // above hwm // We should check if awaitDrain counter is increased. var afterPush = readable._readableState.awaitDrain; assert.strictEqual(afterPush - beforePush, 1, 'Counter is not increased for awaitDrain'); } assert.strictEqual(awaitDrainStates.shift(), readable._readableState.awaitDrain, 'State variable awaitDrain is not correct.'); cb(); }, 3) }); // A readable stream which produces two buffers. var bufs = [bufferShim.alloc(32 * 1024), bufferShim.alloc(33 * 1024)]; // above hwm var readable = new stream.Readable({ read: function () { while (bufs.length > 0) { this.push(bufs.shift()); } } }); readable.pipe(writable);readable-stream-2.3.3/test/parallel/test-stream-pipe-await-drain.js000066400000000000000000000034151312520600100252520ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); // This is very similar to test-stream-pipe-cleanup-pause.js. var reader = new stream.Readable(); var writer1 = new stream.Writable(); var writer2 = new stream.Writable(); var writer3 = new stream.Writable(); // 560000 is chosen here because it is larger than the (default) highWaterMark // and will cause `.write()` to return false // See: https://github.com/nodejs/node/issues/5820 var buffer = bufferShim.allocUnsafe(560000); reader._read = common.noop; writer1._write = common.mustCall(function (chunk, encoding, cb) { this.emit('chunk-received'); cb(); }, 1); writer1.once('chunk-received', function () { assert.strictEqual(reader._readableState.awaitDrain, 0, 'initial value is not 0'); setImmediate(function () { // This one should *not* get through to writer1 because writer2 is not // "done" processing. reader.push(buffer); }); }); // A "slow" consumer: writer2._write = common.mustCall(function (chunk, encoding, cb) { assert.strictEqual(reader._readableState.awaitDrain, 1, 'awaitDrain isn\'t 1 after first push'); // Not calling cb here to "simulate" slow stream. // This should be called exactly once, since the first .write() call // will return false. }, 1); writer3._write = common.mustCall(function (chunk, encoding, cb) { assert.strictEqual(reader._readableState.awaitDrain, 2, 'awaitDrain isn\'t 2 after second push'); // Not calling cb here to "simulate" slow stream. // This should be called exactly once, since the first .write() call // will return false. }, 1); reader.pipe(writer1); reader.pipe(writer2); reader.pipe(writer3); reader.push(buffer);readable-stream-2.3.3/test/parallel/test-stream-pipe-cleanup-pause.js000066400000000000000000000017471312520600100256220ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var reader = new stream.Readable(); var writer1 = new stream.Writable(); var writer2 = new stream.Writable(); // 560000 is chosen here because it is larger than the (default) highWaterMark // and will cause `.write()` to return false // See: https://github.com/nodejs/node/issues/2323 var buffer = bufferShim.allocUnsafe(560000); reader._read = common.noop; writer1._write = common.mustCall(function (chunk, encoding, cb) { this.emit('chunk-received'); cb(); }, 1); writer1.once('chunk-received', function () { reader.unpipe(writer1); reader.pipe(writer2); reader.push(buffer); setImmediate(function () { reader.push(buffer); setImmediate(function () { reader.push(buffer); }); }); }); writer2._write = common.mustCall(function (chunk, encoding, cb) { cb(); }, 3); reader.pipe(writer1); reader.push(buffer);readable-stream-2.3.3/test/parallel/test-stream-pipe-cleanup.js000066400000000000000000000101401312520600100244720ustar00rootroot00000000000000// 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; /**/ // This test asserts that Stream.prototype.pipe does not leave listeners // hanging on the source or dest. require('../common'); var stream = require('../../'); var assert = require('assert/'); var util = require('util'); (function () { if (/^v0\.8\./.test(process.version)) return; function Writable() { this.writable = true; this.endCalls = 0; require('stream').Stream.call(this); } util.inherits(Writable, require('stream').Stream); Writable.prototype.end = function () { this.endCalls++; }; Writable.prototype.destroy = function () { this.endCalls++; }; function Readable() { this.readable = true; require('stream').Stream.call(this); } util.inherits(Readable, require('stream').Stream); function Duplex() { this.readable = true; Writable.call(this); } util.inherits(Duplex, Writable); var i = 0; var limit = 100; var w = new Writable(); var r = void 0; for (i = 0; i < limit; i++) { r = new Readable(); r.pipe(w); r.emit('end'); } assert.strictEqual(0, r.listeners('end').length); assert.strictEqual(limit, w.endCalls); w.endCalls = 0; for (i = 0; i < limit; i++) { r = new Readable(); r.pipe(w); r.emit('close'); } assert.strictEqual(0, r.listeners('close').length); assert.strictEqual(limit, w.endCalls); w.endCalls = 0; r = new Readable(); for (i = 0; i < limit; i++) { w = new Writable(); r.pipe(w); w.emit('close'); } assert.strictEqual(0, w.listeners('close').length); r = new Readable(); w = new Writable(); var d = new Duplex(); r.pipe(d); // pipeline A d.pipe(w); // pipeline B assert.strictEqual(r.listeners('end').length, 2); // A.onend, A.cleanup assert.strictEqual(r.listeners('close').length, 2); // A.onclose, A.cleanup assert.strictEqual(d.listeners('end').length, 2); // B.onend, B.cleanup // A.cleanup, B.onclose, B.cleanup assert.strictEqual(d.listeners('close').length, 3); assert.strictEqual(w.listeners('end').length, 0); assert.strictEqual(w.listeners('close').length, 1); // B.cleanup r.emit('end'); assert.strictEqual(d.endCalls, 1); assert.strictEqual(w.endCalls, 0); assert.strictEqual(r.listeners('end').length, 0); assert.strictEqual(r.listeners('close').length, 0); assert.strictEqual(d.listeners('end').length, 2); // B.onend, B.cleanup assert.strictEqual(d.listeners('close').length, 2); // B.onclose, B.cleanup assert.strictEqual(w.listeners('end').length, 0); assert.strictEqual(w.listeners('close').length, 1); // B.cleanup d.emit('end'); assert.strictEqual(d.endCalls, 1); assert.strictEqual(w.endCalls, 1); assert.strictEqual(r.listeners('end').length, 0); assert.strictEqual(r.listeners('close').length, 0); assert.strictEqual(d.listeners('end').length, 0); assert.strictEqual(d.listeners('close').length, 0); assert.strictEqual(w.listeners('end').length, 0); assert.strictEqual(w.listeners('close').length, 0); })();readable-stream-2.3.3/test/parallel/test-stream-pipe-error-handling.js000066400000000000000000000056501312520600100257700ustar00rootroot00000000000000// 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 assert = require('assert/'); var Stream = require('stream').Stream; { var source = new Stream(); var dest = new Stream(); source.pipe(dest); var gotErr = null; source.on('error', function (err) { gotErr = err; }); var err = new Error('This stream turned into bacon.'); source.emit('error', err); assert.strictEqual(gotErr, err); } { var _source = new Stream(); var _dest = new Stream(); _source.pipe(_dest); var _err = new Error('This stream turned into bacon.'); var _gotErr = null; try { _source.emit('error', _err); } catch (e) { _gotErr = e; } assert.strictEqual(_gotErr, _err); } { var R = require('../../').Readable; var W = require('../../').Writable; var r = new R(); var w = new W(); var removed = false; r._read = common.mustCall(function () { setTimeout(common.mustCall(function () { assert(removed); assert.throws(function () { w.emit('error', new Error('fail')); }, /^Error: fail$/); }), 1); }); w.on('error', myOnError); r.pipe(w); w.removeListener('error', myOnError); removed = true; function myOnError() { throw new Error('this should not happen'); } } { var _R = require('../../').Readable; var _W = require('../../').Writable; var _r = new _R(); var _w = new _W(); var _removed = false; _r._read = common.mustCall(function () { setTimeout(common.mustCall(function () { assert(_removed); _w.emit('error', new Error('fail')); }), 1); }); _w.on('error', common.mustCall()); _w._write = common.noop; _r.pipe(_w); // Removing some OTHER random listener should not do anything _w.removeListener('error', common.noop); _removed = true; }readable-stream-2.3.3/test/parallel/test-stream-pipe-event.js000066400000000000000000000033441312520600100241740ustar00rootroot00000000000000// 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 stream = require('../../'); var assert = require('assert/'); var util = require('util'); function Writable() { this.writable = true; require('stream').Stream.call(this); } util.inherits(Writable, require('stream').Stream); function Readable() { this.readable = true; require('stream').Stream.call(this); } util.inherits(Readable, require('stream').Stream); var passed = false; var w = new Writable(); w.on('pipe', function (src) { passed = true; }); var r = new Readable(); r.pipe(w); assert.ok(passed);readable-stream-2.3.3/test/parallel/test-stream-pipe-multiple-pipes.js000066400000000000000000000047431312520600100260300ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); var readable = new stream.Readable({ read: common.noop }); var writables = []; var _loop = function (i) { var target = new stream.Writable({ write: common.mustCall(function (chunk, encoding, callback) { target.output.push(chunk); callback(); }, 1) }); target.output = []; target.on('pipe', common.mustCall()); readable.pipe(target); writables.push(target); }; for (var i = 0; i < 5; i++) { _loop(i); } var input = bufferShim.from([1, 2, 3, 4, 5]); readable.push(input); // The pipe() calls will postpone emission of the 'resume' event using nextTick, // so no data will be available to the writable streams until then. process.nextTick(common.mustCall(function () { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = writables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _target = _step.value; assert.deepStrictEqual(_target.output, [input]); _target.on('unpipe', common.mustCall()); readable.unpipe(_target); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } readable.push('something else'); // This does not get through. readable.push(null); readable.resume(); // Make sure the 'end' event gets emitted. })); readable.on('end', common.mustCall(function () { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = writables[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _target2 = _step2.value; assert.deepStrictEqual(_target2.output, [input]); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } }));readable-stream-2.3.3/test/parallel/test-stream-pipe-same-destination-twice.js000066400000000000000000000046711312520600100274340ustar00rootroot00000000000000/**/ 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'); }readable-stream-2.3.3/test/parallel/test-stream-pipe-unpipe-streams.js000066400000000000000000000020341312520600100260220ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var _require = require('../../'), Readable = _require.Readable, Writable = _require.Writable; 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()); dest2.on('unpipe', common.mustCall()); assert.strictEqual(source._readableState.pipes[0], dest1); assert.strictEqual(source._readableState.pipes[1], dest2); assert.strictEqual(source._readableState.pipes.length, 2); // Should be able to unpipe them in the reverse order that they were piped. source.unpipe(dest2); assert.strictEqual(source._readableState.pipes, dest1); assert.notStrictEqual(source._readableState.pipes, dest2); dest2.on('unpipe', common.mustNotCall()); source.unpipe(dest2); source.unpipe(dest1); assert.strictEqual(source._readableState.pipes, null);readable-stream-2.3.3/test/parallel/test-stream-pipe-without-listenerCount.js000066400000000000000000000007341312520600100274120ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var r = new stream.Stream(); r.listenerCount = undefined; var w = new stream.Stream(); w.listenerCount = undefined; w.on('pipe', function () { r.emit('error', new Error('Readable Error')); w.emit('error', new Error('Writable Error')); }); r.on('error', common.mustCall()); w.on('error', common.mustCall()); r.pipe(w);readable-stream-2.3.3/test/parallel/test-stream-push-order.js000066400000000000000000000033541312520600100242110ustar00rootroot00000000000000// 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 Readable = require('../../').Readable; var assert = require('assert/'); var s = new Readable({ highWaterMark: 20, encoding: 'ascii' }); var list = ['1', '2', '3', '4', '5', '6']; s._read = function (n) { var one = list.shift(); if (!one) { s.push(null); } else { var two = list.shift(); s.push(one); s.push(two); } }; s.read(0); // ACTUALLY [1, 3, 5, 6, 4, 2] process.on('exit', function () { assert.deepStrictEqual(s._readableState.buffer.join(','), '1,2,3,4,5,6'); console.log('ok'); });readable-stream-2.3.3/test/parallel/test-stream-push-strings.js000066400000000000000000000043611312520600100245660ustar00rootroot00000000000000// 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 assert = require('assert/'); var Readable = require('../../').Readable; var util = require('util'); util.inherits(MyStream, Readable); function MyStream(options) { Readable.call(this, options); this._chunks = 3; } MyStream.prototype._read = function (n) { switch (this._chunks--) { case 0: return this.push(null); case 1: return setTimeout(function () { this.push('last chunk'); }.bind(this), 100); case 2: return this.push('second to last chunk'); case 3: return process.nextTick(function () { this.push('first chunk'); }.bind(this)); default: throw new Error('?'); } }; var ms = new MyStream(); var results = []; ms.on('readable', function () { var chunk = void 0; while (null !== (chunk = ms.read())) { results.push(String(chunk)); } }); var expect = ['first chunksecond to last chunk', 'last chunk']; process.on('exit', function () { assert.strictEqual(ms._chunks, -1); assert.deepStrictEqual(results, expect); console.log('ok'); });readable-stream-2.3.3/test/parallel/test-stream-readable-constructor-set-methods.js000066400000000000000000000004371312520600100304740ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var Readable = require('../../').Readable; var _read = common.mustCall(function _read(n) { this.push(null); }); var r = new Readable({ read: _read }); r.resume();readable-stream-2.3.3/test/parallel/test-stream-readable-destroy.js000066400000000000000000000071331312520600100253460ustar00rootroot00000000000000/**/ 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); })); }readable-stream-2.3.3/test/parallel/test-stream-readable-emittedReadable.js000066400000000000000000000040601312520600100267240ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var Readable = require('../../').Readable; var readable = new Readable({ read: common.noop }); // Initialized to false. assert.strictEqual(readable._readableState.emittedReadable, false); readable.on('readable', common.mustCall(function () { // emittedReadable should be true when the readable event is emitted assert.strictEqual(readable._readableState.emittedReadable, true); readable.read(); // emittedReadable is reset to false during read() assert.strictEqual(readable._readableState.emittedReadable, false); }, 4)); // When the first readable listener is just attached, // emittedReadable should be false assert.strictEqual(readable._readableState.emittedReadable, false); // Each one of these should trigger a readable event. process.nextTick(common.mustCall(function () { readable.push('foo'); })); process.nextTick(common.mustCall(function () { readable.push('bar'); })); process.nextTick(common.mustCall(function () { readable.push('quo'); })); process.nextTick(common.mustCall(function () { readable.push(null); })); var noRead = new Readable({ read: common.noop }); noRead.on('readable', common.mustCall(function () { // emittedReadable should be true when the readable event is emitted assert.strictEqual(noRead._readableState.emittedReadable, true); noRead.read(0); // emittedReadable is not reset during read(0) assert.strictEqual(noRead._readableState.emittedReadable, true); })); noRead.push('foo'); noRead.push(null); var flowing = new Readable({ read: common.noop }); flowing.on('data', common.mustCall(function () { // When in flowing mode, emittedReadable is always false. assert.strictEqual(flowing._readableState.emittedReadable, false); flowing.read(); assert.strictEqual(flowing._readableState.emittedReadable, false); }, 3)); flowing.push('foooo'); flowing.push('bar'); flowing.push('quo'); process.nextTick(common.mustCall(function () { flowing.push(null); }));readable-stream-2.3.3/test/parallel/test-stream-readable-event.js000066400000000000000000000052631312520600100250000ustar00rootroot00000000000000// 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 assert = require('assert/'); var Readable = require('../../').Readable; { // First test, not reading when the readable is added. // make sure that on('readable', ...) triggers a readable event. var r = new Readable({ highWaterMark: 3 }); r._read = common.mustNotCall(); // This triggers a 'readable' event, which is lost. r.push(bufferShim.from('blerg')); setTimeout(function () { // we're testing what we think we are assert(!r._readableState.reading); r.on('readable', common.mustCall()); }, 1); } { // second test, make sure that readable is re-emitted if there's // already a length, while it IS reading. var _r = new Readable({ highWaterMark: 3 }); _r._read = common.mustCall(); // This triggers a 'readable' event, which is lost. _r.push(bufferShim.from('bl')); setTimeout(function () { // assert we're testing what we think we are assert(_r._readableState.reading); _r.on('readable', common.mustCall()); }, 1); } { // Third test, not reading when the stream has not passed // the highWaterMark but *has* reached EOF. var _r2 = new Readable({ highWaterMark: 30 }); _r2._read = common.mustNotCall(); // This triggers a 'readable' event, which is lost. _r2.push(bufferShim.from('blerg')); _r2.push(null); setTimeout(function () { // assert we're testing what we think we are assert(!_r2._readableState.reading); _r2.on('readable', common.mustCall()); }, 1); }readable-stream-2.3.3/test/parallel/test-stream-readable-flow-recursion.js000066400000000000000000000050351312520600100266320ustar00rootroot00000000000000// 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 assert = require('assert/'); // this test verifies that passing a huge number to read(size) // will push up the highWaterMark, and cause the stream to read // more data continuously, but without triggering a nextTick // warning or RangeError. var Readable = require('../../').Readable; // throw an error if we trigger a nextTick warning. process.throwDeprecation = true; var stream = new Readable({ highWaterMark: 2 }); var reads = 0; var total = 5000; stream._read = function (size) { reads++; size = Math.min(size, total); total -= size; if (size === 0) stream.push(null);else stream.push(bufferShim.allocUnsafe(size)); }; var depth = 0; function flow(stream, size, callback) { depth += 1; var chunk = stream.read(size); if (!chunk) stream.once('readable', flow.bind(null, stream, size, callback));else callback(chunk); depth -= 1; console.log('flow(' + depth + '): exit'); } flow(stream, 5000, function () { console.log('complete (' + depth + ')'); }); process.on('exit', function (code) { assert.strictEqual(reads, 2); // we pushed up the high water mark assert.strictEqual(stream._readableState.highWaterMark, 8192); // length is 0 right now, because we pulled it all out. assert.strictEqual(stream._readableState.length, 0); assert(!code); assert.strictEqual(depth, 0); console.log('ok'); });readable-stream-2.3.3/test/parallel/test-stream-readable-invalid-chunk.js000066400000000000000000000010041312520600100264000ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); var readable = new stream.Readable({ read: common.noop }); var errMessage = /Invalid non-string\/buffer chunk/; assert.throws(function () { return readable.push([]); }, errMessage); assert.throws(function () { return readable.push({}); }, errMessage); assert.throws(function () { return readable.push(0); }, errMessage);readable-stream-2.3.3/test/parallel/test-stream-readable-needReadable.js000066400000000000000000000053721312520600100262130ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var Readable = require('../../').Readable; var readable = new Readable({ read: common.noop }); // Initialized to false. assert.strictEqual(readable._readableState.needReadable, false); readable.on('readable', common.mustCall(function () { // When the readable event fires, needReadable is reset. assert.strictEqual(readable._readableState.needReadable, false); readable.read(); })); // If a readable listener is attached, then a readable event is needed. assert.strictEqual(readable._readableState.needReadable, true); readable.push('foo'); readable.push(null); readable.on('end', common.mustCall(function () { // No need to emit readable anymore when the stream ends. assert.strictEqual(readable._readableState.needReadable, false); })); var asyncReadable = new Readable({ read: common.noop }); asyncReadable.on('readable', common.mustCall(function () { if (asyncReadable.read() !== null) { // After each read(), the buffer is empty. // If the stream doesn't end now, // then we need to notify the reader on future changes. assert.strictEqual(asyncReadable._readableState.needReadable, true); } }, 3)); process.nextTick(common.mustCall(function () { asyncReadable.push('foooo'); })); process.nextTick(common.mustCall(function () { asyncReadable.push('bar'); })); process.nextTick(common.mustCall(function () { asyncReadable.push(null); })); var flowing = new Readable({ read: common.noop }); // Notice this must be above the on('data') call. flowing.push('foooo'); flowing.push('bar'); flowing.push('quo'); process.nextTick(common.mustCall(function () { flowing.push(null); })); // When the buffer already has enough data, and the stream is // in flowing mode, there is no need for the readable event. flowing.on('data', common.mustCall(function (data) { assert.strictEqual(flowing._readableState.needReadable, false); }, 3)); var slowProducer = new Readable({ read: common.noop }); slowProducer.on('readable', common.mustCall(function () { if (slowProducer.read(8) === null) { // The buffer doesn't have enough data, and the stream is not need, // we need to notify the reader when data arrives. assert.strictEqual(slowProducer._readableState.needReadable, true); } else { assert.strictEqual(slowProducer._readableState.needReadable, false); } }, 4)); process.nextTick(common.mustCall(function () { slowProducer.push('foo'); })); process.nextTick(common.mustCall(function () { slowProducer.push('foo'); })); process.nextTick(common.mustCall(function () { slowProducer.push('foo'); })); process.nextTick(common.mustCall(function () { slowProducer.push(null); }));readable-stream-2.3.3/test/parallel/test-stream-readable-reading-readingMore.js000066400000000000000000000033671312520600100275250ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var Readable = require('../../').Readable; var readable = new Readable({ read: function (size) {} }); var state = readable._readableState; // Starting off with false initially. assert.strictEqual(state.reading, false); assert.strictEqual(state.readingMore, false); readable.on('data', common.mustCall(function (data) { // while in a flowing state, should try to read more. if (state.flowing) assert.strictEqual(state.readingMore, true); // reading as long as we've not ended assert.strictEqual(state.reading, !state.ended); }, 2)); function onStreamEnd() { // End of stream; state.reading is false // And so should be readingMore. assert.strictEqual(state.readingMore, false); assert.strictEqual(state.reading, false); } readable.on('readable', common.mustCall(function () { // 'readable' always gets called before 'end' // since 'end' hasn't been emitted, more data could be incoming assert.strictEqual(state.readingMore, true); // if the stream has ended, we shouldn't be reading assert.strictEqual(state.ended, !state.reading); if (readable.read() === null) // reached end of stream process.nextTick(common.mustCall(onStreamEnd, 1)); }, 2)); readable.on('end', common.mustCall(onStreamEnd)); readable.push('pushed'); // stop emitting 'data' events readable.pause(); // read() should only be called while operating in paused mode readable.read(6); // reading assert.strictEqual(state.reading, true); assert.strictEqual(state.readingMore, true); // resume emitting 'data' events readable.resume(); // add chunk to front readable.unshift('unshifted'); // end readable.push(null);readable-stream-2.3.3/test/parallel/test-stream-readable-resumeScheduled.js000066400000000000000000000037361312520600100270030ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); // Testing Readable Stream resumeScheduled state var assert = require('assert/'); var _require = require('../../'), Readable = _require.Readable, Writable = _require.Writable; { // pipe() test case var r = new Readable({ read: function () {} }); var w = new Writable(); // resumeScheduled should start = `false`. assert.strictEqual(r._readableState.resumeScheduled, false); // calling pipe() should change the state value = true. r.pipe(w); assert.strictEqual(r._readableState.resumeScheduled, true); process.nextTick(common.mustCall(function () { assert.strictEqual(r._readableState.resumeScheduled, false); })); } { // 'data' listener test case var _r = new Readable({ read: function () {} }); // resumeScheduled should start = `false`. assert.strictEqual(_r._readableState.resumeScheduled, false); _r.push(bufferShim.from([1, 2, 3])); // adding 'data' listener should change the state value _r.on('data', common.mustCall(function () { assert.strictEqual(_r._readableState.resumeScheduled, false); })); assert.strictEqual(_r._readableState.resumeScheduled, true); process.nextTick(common.mustCall(function () { assert.strictEqual(_r._readableState.resumeScheduled, false); })); } { // resume() test case var _r2 = new Readable({ read: function () {} }); // resumeScheduled should start = `false`. assert.strictEqual(_r2._readableState.resumeScheduled, false); // Calling resume() should change the state value. _r2.resume(); assert.strictEqual(_r2._readableState.resumeScheduled, true); _r2.on('resume', common.mustCall(function () { // The state value should be `false` again assert.strictEqual(_r2._readableState.resumeScheduled, false); })); process.nextTick(common.mustCall(function () { assert.strictEqual(_r2._readableState.resumeScheduled, false); })); }readable-stream-2.3.3/test/parallel/test-stream-readable-with-unimplemented-_read.js000066400000000000000000000004401312520600100305360ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var stream = require('../../'); var assert = require('assert/'); var readable = new stream.Readable(); assert.throws(function () { return readable.read(); }, /not implemented/);readable-stream-2.3.3/test/parallel/test-stream-readableListening-state.js000066400000000000000000000020141312520600100266430ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var stream = require('../../'); var r = new stream.Readable({ read: common.noop }); // readableListening state should start in `false`. assert.strictEqual(r._readableState.readableListening, false); r.on('readable', common.mustCall(function () { // Inside the readable event this state should be true. assert.strictEqual(r._readableState.readableListening, true); })); r.push(bufferShim.from('Testing readableListening state')); var r2 = new stream.Readable({ read: common.noop }); // readableListening state should start in `false`. assert.strictEqual(r2._readableState.readableListening, false); r2.on('data', common.mustCall(function (chunk) { // readableListening should be false because we don't have // a `readable` listener assert.strictEqual(r2._readableState.readableListening, false); })); r2.push(bufferShim.from('Testing readableListening state'));readable-stream-2.3.3/test/parallel/test-stream-transform-callback-twice.js000066400000000000000000000007421312520600100267750ustar00rootroot00000000000000/**/ 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');readable-stream-2.3.3/test/parallel/test-stream-transform-constructor-set-methods.js000066400000000000000000000014741312520600100307520ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var Transform = require('../../').Transform; var _transform = common.mustCall(function _transform(d, e, n) { n(); }); var _final = common.mustCall(function _final(n) { n(); }); var _flush = common.mustCall(function _flush(n) { n(); }); var t = new Transform({ transform: _transform, flush: _flush, final: _final }); var t2 = new Transform({}); t.end(bufferShim.from('blerg')); t.resume(); assert.throws(function () { t2.end(bufferShim.from('blerg')); }, /^Error: .*[Nn]ot implemented$/); process.on('exit', function () { assert.strictEqual(t._transform, _transform); assert.strictEqual(t._flush, _flush); assert.strictEqual(t._final, _final); });readable-stream-2.3.3/test/parallel/test-stream-transform-destroy.js000066400000000000000000000067711312520600100256310ustar00rootroot00000000000000/**/ 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(); }readable-stream-2.3.3/test/parallel/test-stream-transform-final-sync.js000066400000000000000000000045711312520600100261770ustar00rootroot00000000000000/**/ 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));readable-stream-2.3.3/test/parallel/test-stream-transform-final.js000066400000000000000000000046511312520600100252240ustar00rootroot00000000000000/**/ 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));readable-stream-2.3.3/test/parallel/test-stream-transform-flush-data.js000066400000000000000000000007431312520600100261610ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var assert = require('assert/'); var Transform = require('../../').Transform; var expected = 'asdf'; function _transform(d, e, n) { n(); } function _flush(n) { n(null, expected); } var t = new Transform({ transform: _transform, flush: _flush }); t.end(bufferShim.from('blerg')); t.on('data', function (data) { assert.strictEqual(data.toString(), expected); });readable-stream-2.3.3/test/parallel/test-stream-transform-objectmode-falsey-value.js000066400000000000000000000036271312520600100306430ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); var PassThrough = stream.PassThrough; var src = new PassThrough({ objectMode: true }); var tx = new PassThrough({ objectMode: true }); var dest = new PassThrough({ objectMode: true }); var expect = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var results = []; dest.on('data', common.mustCall(function (x) { results.push(x); }, expect.length)); src.pipe(tx).pipe(dest); var i = -1; var int = setInterval(common.mustCall(function () { if (results.length === expect.length) { src.end(); clearInterval(int); assert.deepStrictEqual(results, expect); } else { src.write(i++); } }, expect.length + 1), 1);readable-stream-2.3.3/test/parallel/test-stream-transform-split-objectmode.js000066400000000000000000000046611312520600100274000ustar00rootroot00000000000000// 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 assert = require('assert/'); var Transform = require('../../').Transform; var parser = new Transform({ readableObjectMode: true }); assert(parser._readableState.objectMode); assert(!parser._writableState.objectMode); assert.strictEqual(parser._readableState.highWaterMark, 16); assert.strictEqual(parser._writableState.highWaterMark, 16 * 1024); parser._transform = function (chunk, enc, callback) { callback(null, { val: chunk[0] }); }; var parsed = void 0; parser.on('data', function (obj) { parsed = obj; }); parser.end(bufferShim.from([42])); process.on('exit', function () { assert.strictEqual(parsed.val, 42); }); var serializer = new Transform({ writableObjectMode: true }); assert(!serializer._readableState.objectMode); assert(serializer._writableState.objectMode); assert.strictEqual(serializer._readableState.highWaterMark, 16 * 1024); assert.strictEqual(serializer._writableState.highWaterMark, 16); serializer._transform = function (obj, _, callback) { callback(null, bufferShim.from([obj.val])); }; var serialized = void 0; serializer.on('data', function (chunk) { serialized = chunk; }); serializer.write({ val: 42 }); process.on('exit', function () { assert.strictEqual(serialized[0], 42); });readable-stream-2.3.3/test/parallel/test-stream-uint8array.js000066400000000000000000000052501312520600100242240ustar00rootroot00000000000000function _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'); }readable-stream-2.3.3/test/parallel/test-stream-unpipe-event.js000066400000000000000000000100701312520600100245310ustar00rootroot00000000000000function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } if (process.version.indexOf('v0.8') === 0) { process.exit(0); } /**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var _require = require('../../'), Writable = _require.Writable, Readable = _require.Readable; var NullWriteable = function (_Writable) { _inherits(NullWriteable, _Writable); function NullWriteable() { _classCallCheck(this, NullWriteable); return _possibleConstructorReturn(this, _Writable.apply(this, arguments)); } NullWriteable.prototype._write = function _write(chunk, encoding, callback) { return callback(); }; return NullWriteable; }(Writable); var QuickEndReadable = function (_Readable) { _inherits(QuickEndReadable, _Readable); function QuickEndReadable() { _classCallCheck(this, QuickEndReadable); return _possibleConstructorReturn(this, _Readable.apply(this, arguments)); } QuickEndReadable.prototype._read = function _read() { this.push(null); }; return QuickEndReadable; }(Readable); var NeverEndReadable = function (_Readable2) { _inherits(NeverEndReadable, _Readable2); function NeverEndReadable() { _classCallCheck(this, NeverEndReadable); return _possibleConstructorReturn(this, _Readable2.apply(this, arguments)); } NeverEndReadable.prototype._read = function _read() {}; return NeverEndReadable; }(Readable); { var dest = new NullWriteable(); var src = new QuickEndReadable(); dest.on('pipe', common.mustCall()); dest.on('unpipe', common.mustCall()); src.pipe(dest); setImmediate(function () { assert.strictEqual(src._readableState.pipesCount, 0); }); } { var _dest = new NullWriteable(); var _src = new NeverEndReadable(); _dest.on('pipe', common.mustCall()); _dest.on('unpipe', common.mustNotCall('unpipe should not have been emitted')); _src.pipe(_dest); setImmediate(function () { assert.strictEqual(_src._readableState.pipesCount, 1); }); } { var _dest2 = new NullWriteable(); var _src2 = new NeverEndReadable(); _dest2.on('pipe', common.mustCall()); _dest2.on('unpipe', common.mustCall()); _src2.pipe(_dest2); _src2.unpipe(_dest2); setImmediate(function () { assert.strictEqual(_src2._readableState.pipesCount, 0); }); } { var _dest3 = new NullWriteable(); var _src3 = new QuickEndReadable(); _dest3.on('pipe', common.mustCall()); _dest3.on('unpipe', common.mustCall()); _src3.pipe(_dest3, { end: false }); setImmediate(function () { assert.strictEqual(_src3._readableState.pipesCount, 0); }); } { var _dest4 = new NullWriteable(); var _src4 = new NeverEndReadable(); _dest4.on('pipe', common.mustCall()); _dest4.on('unpipe', common.mustNotCall('unpipe should not have been emitted')); _src4.pipe(_dest4, { end: false }); setImmediate(function () { assert.strictEqual(_src4._readableState.pipesCount, 1); }); } { var _dest5 = new NullWriteable(); var _src5 = new NeverEndReadable(); _dest5.on('pipe', common.mustCall()); _dest5.on('unpipe', common.mustCall()); _src5.pipe(_dest5, { end: false }); _src5.unpipe(_dest5); setImmediate(function () { assert.strictEqual(_src5._readableState.pipesCount, 0); }); }readable-stream-2.3.3/test/parallel/test-stream-unshift-empty-chunk.js000066400000000000000000000046561312520600100260510ustar00rootroot00000000000000// 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 assert = require('assert/'); // This test verifies that stream.unshift(bufferShim.alloc(0)) or // stream.unshift('') does not set state.reading=false. var Readable = require('../../').Readable; var r = new Readable(); var nChunks = 10; var chunk = bufferShim.alloc(10, 'x'); r._read = function (n) { setImmediate(function () { r.push(--nChunks === 0 ? null : chunk); }); }; var readAll = false; var seen = []; r.on('readable', function () { var chunk = void 0; while (chunk = r.read()) { seen.push(chunk.toString()); // simulate only reading a certain amount of the data, // and then putting the rest of the chunk back into the // stream, like a parser might do. We just fill it with // 'y' so that it's easy to see which bits were touched, // and which were not. var putBack = bufferShim.alloc(readAll ? 0 : 5, 'y'); readAll = !readAll; r.unshift(putBack); } }); var expect = ['xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy', 'xxxxxxxxxx', 'yyyyy']; r.on('end', function () { assert.deepStrictEqual(seen, expect); console.log('ok'); });readable-stream-2.3.3/test/parallel/test-stream-unshift-read-race.js000066400000000000000000000077521312520600100254300ustar00rootroot00000000000000// 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 assert = require('assert/'); // This test verifies that: // 1. unshift() does not cause colliding _read() calls. // 2. unshift() after the 'end' event is an error, but after the EOF // signalling null, it is ok, and just creates a new readable chunk. // 3. push() after the EOF signaling null is an error. // 4. _read() is not called after pushing the EOF null chunk. var stream = require('../../'); var hwm = 10; var r = stream.Readable({ highWaterMark: hwm }); var chunks = 10; var data = bufferShim.allocUnsafe(chunks * hwm + Math.ceil(hwm / 2)); for (var i = 0; i < data.length; i++) { var c = 'asdf'.charCodeAt(i % 4); data[i] = c; } var pos = 0; var pushedNull = false; r._read = function (n) { assert(!pushedNull, '_read after null push'); // every third chunk is fast push(!(chunks % 3)); function push(fast) { assert(!pushedNull, 'push() after null push'); var c = pos >= data.length ? null : data.slice(pos, Math.min(pos + n, data.length)); pushedNull = c === null; if (fast) { pos += n; r.push(c); if (c === null) pushError(); } else { setTimeout(function () { pos += n; r.push(c); if (c === null) pushError(); }, 1); } } }; function pushError() { assert.throws(function () { r.push(bufferShim.allocUnsafe(1)); }, /^Error: stream\.push\(\) after EOF$/); } var w = stream.Writable(); var written = []; w._write = function (chunk, encoding, cb) { written.push(chunk.toString()); cb(); }; r.on('end', common.mustCall(function () { assert.throws(function () { r.unshift(bufferShim.allocUnsafe(1)); }, /^Error: stream\.unshift\(\) after end event$/); w.end(); })); r.on('readable', function () { var chunk = void 0; while (null !== (chunk = r.read(10))) { w.write(chunk); if (chunk.length > 4) r.unshift(bufferShim.from('1234')); } }); w.on('finish', common.mustCall(function () { // each chunk should start with 1234, and then be asfdasdfasdf... // The first got pulled out before the first unshift('1234'), so it's // lacking that piece. assert.strictEqual(written[0], 'asdfasdfas'); var asdf = 'd'; console.error('0: %s', written[0]); for (var _i = 1; _i < written.length; _i++) { console.error('%s: %s', _i.toString(32), written[_i]); assert.strictEqual(written[_i].slice(0, 4), '1234'); for (var j = 4; j < written[_i].length; j++) { var _c = written[_i].charAt(j); assert.strictEqual(_c, asdf); switch (asdf) { case 'a': asdf = 's';break; case 's': asdf = 'd';break; case 'd': asdf = 'f';break; case 'f': asdf = 'a';break; } } } })); process.on('exit', function () { assert.strictEqual(written.length, 18); console.log('ok'); });readable-stream-2.3.3/test/parallel/test-stream-writable-change-default-encoding.js000066400000000000000000000047241312520600100303650ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); var util = require('util'); function MyWritable(fn, options) { stream.Writable.call(this, options); this.fn = fn; } util.inherits(MyWritable, stream.Writable); MyWritable.prototype._write = function (chunk, encoding, callback) { this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding); callback(); }; (function defaultCondingIsUtf8() { var m = new MyWritable(function (isBuffer, type, enc) { assert.strictEqual(enc, 'utf8'); }, { decodeStrings: false }); m.write('foo'); m.end(); })(); (function changeDefaultEncodingToAscii() { var m = new MyWritable(function (isBuffer, type, enc) { assert.strictEqual(enc, 'ascii'); }, { decodeStrings: false }); m.setDefaultEncoding('ascii'); m.write('bar'); m.end(); })(); assert.throws(function changeDefaultEncodingToInvalidValue() { var m = new MyWritable(function (isBuffer, type, enc) {}, { decodeStrings: false }); m.setDefaultEncoding({}); m.write('bar'); m.end(); }, TypeError); (function checkVairableCaseEncoding() { var m = new MyWritable(function (isBuffer, type, enc) { assert.strictEqual(enc, 'ascii'); }, { decodeStrings: false }); m.setDefaultEncoding('AsCii'); m.write('bar'); m.end(); })();readable-stream-2.3.3/test/parallel/test-stream-writable-constructor-set-methods.js000066400000000000000000000014361312520600100305460ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var assert = require('assert/'); var Writable = require('../../').Writable; var _writeCalled = false; function _write(d, e, n) { _writeCalled = true; } var w = new Writable({ write: _write }); w.end(bufferShim.from('blerg')); var _writevCalled = false; var dLength = 0; function _writev(d, n) { dLength = d.length; _writevCalled = true; } var w2 = new Writable({ writev: _writev }); w2.cork(); w2.write(bufferShim.from('blerg')); w2.write(bufferShim.from('blerg')); w2.end(); process.on('exit', function () { assert.strictEqual(w._write, _write); assert(_writeCalled); assert.strictEqual(w2._writev, _writev); assert.strictEqual(dLength, 2); assert(_writevCalled); });readable-stream-2.3.3/test/parallel/test-stream-writable-decoded-encoding.js000066400000000000000000000040611312520600100270770ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); var util = require('util'); function MyWritable(fn, options) { stream.Writable.call(this, options); this.fn = fn; } util.inherits(MyWritable, stream.Writable); MyWritable.prototype._write = function (chunk, encoding, callback) { this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding); callback(); }; { var m = new MyWritable(function (isBuffer, type, enc) { assert(isBuffer); assert.strictEqual(type, 'object'); assert.strictEqual(enc, 'buffer'); }, { decodeStrings: true }); m.write('some-text', 'utf8'); m.end(); } { var _m = new MyWritable(function (isBuffer, type, enc) { assert(!isBuffer); assert.strictEqual(type, 'string'); assert.strictEqual(enc, 'utf8'); }, { decodeStrings: false }); _m.write('some-text', 'utf8'); _m.end(); }readable-stream-2.3.3/test/parallel/test-stream-writable-destroy.js000066400000000000000000000103341312520600100254150ustar00rootroot00000000000000/**/ 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); })); }readable-stream-2.3.3/test/parallel/test-stream-writable-ended-state.js000066400000000000000000000011241312520600100261160ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var stream = require('../../'); var writable = new stream.Writable(); writable._write = function (chunk, encoding, cb) { assert.strictEqual(writable._writableState.ended, false); cb(); }; assert.strictEqual(writable._writableState.ended, false); writable.end('testing ended state', common.mustCall(function () { assert.strictEqual(writable._writableState.ended, true); })); assert.strictEqual(writable._writableState.ended, true);readable-stream-2.3.3/test/parallel/test-stream-writable-finished-state.js000066400000000000000000000012171312520600100266330ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var stream = require('../../'); var writable = new stream.Writable(); writable._write = function (chunk, encoding, cb) { // The state finished should start in false. assert.strictEqual(writable._writableState.finished, false); cb(); }; writable.on('finish', common.mustCall(function () { assert.strictEqual(writable._writableState.finished, true); })); writable.end('testing finished state', common.mustCall(function () { assert.strictEqual(writable._writableState.finished, true); }));readable-stream-2.3.3/test/parallel/test-stream-writable-needdrain-state.js000066400000000000000000000012051312520600100267700ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var stream = require('../../'); var assert = require('assert/'); var transform = new stream.Transform({ transform: _transform, highWaterMark: 1 }); function _transform(chunk, encoding, cb) { assert.strictEqual(transform._writableState.needDrain, true); cb(); } assert.strictEqual(transform._writableState.needDrain, false); transform.write('asdasd', common.mustCall(function () { assert.strictEqual(transform._writableState.needDrain, false); })); assert.strictEqual(transform._writableState.needDrain, true);readable-stream-2.3.3/test/parallel/test-stream-writable-null.js000066400000000000000000000030621312520600100246760ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var assert = require('assert/'); var stream = require('../../'); var util = require('util'); function MyWritable(options) { stream.Writable.call(this, options); } util.inherits(MyWritable, stream.Writable); MyWritable.prototype._write = function (chunk, encoding, callback) { assert.notStrictEqual(chunk, null); callback(); }; assert.throws(function () { var m = new MyWritable({ objectMode: true }); m.write(null, function (err) { return assert.ok(err); }); }, TypeError, 'May not write null values to stream'); assert.doesNotThrow(function () { var m = new MyWritable({ objectMode: true }).on('error', function (e) { assert.ok(e); }); m.write(null, function (err) { assert.ok(err); }); }); assert.throws(function () { var m = new MyWritable(); m.write(false, function (err) { return assert.ok(err); }); }, TypeError, 'Invalid non-string/buffer chunk'); assert.doesNotThrow(function () { var m = new MyWritable().on('error', function (e) { assert.ok(e); }); m.write(false, function (err) { assert.ok(err); }); }); assert.doesNotThrow(function () { var m = new MyWritable({ objectMode: true }); m.write(false, function (err) { return assert.ifError(err); }); }); assert.doesNotThrow(function () { var m = new MyWritable({ objectMode: true }).on('error', function (e) { assert.ifError(e || new Error('should not get here')); }); m.write(false, function (err) { assert.ifError(err); }); });readable-stream-2.3.3/test/parallel/test-stream-writable-write-writev-finish.js000066400000000000000000000067171312520600100276640ustar00rootroot00000000000000/**/ 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')); }; var firstError = false; writable.on('finish', common.mustCall(function () { assert.strictEqual(firstError, true); })); writable.on('prefinish', common.mustCall()); writable.on('error', common.mustCall(function (er) { assert.strictEqual(er.message, 'write test error'); firstError = true; })); writable.end('test'); } { var _writable = new stream.Writable(); _writable._write = function (chunks, encoding, cb) { setImmediate(cb, new Error('write test error')); }; var _firstError = false; _writable.on('finish', common.mustCall(function () { assert.strictEqual(_firstError, true); })); _writable.on('prefinish', common.mustCall()); _writable.on('error', common.mustCall(function (er) { assert.strictEqual(er.message, 'write test error'); _firstError = true; })); _writable.end('test'); } { var _writable2 = new stream.Writable(); _writable2._write = function (chunks, encoding, cb) { cb(new Error('write test error')); }; _writable2._writev = function (chunks, cb) { cb(new Error('writev test error')); }; var _firstError2 = false; _writable2.on('finish', common.mustCall(function () { assert.strictEqual(_firstError2, true); })); _writable2.on('prefinish', common.mustCall()); _writable2.on('error', common.mustCall(function (er) { assert.strictEqual(er.message, 'writev test error'); _firstError2 = true; })); _writable2.cork(); _writable2.write('test'); setImmediate(function () { _writable2.end('test'); }); } { var _writable3 = new stream.Writable(); _writable3._write = function (chunks, encoding, cb) { setImmediate(cb, new Error('write test error')); }; _writable3._writev = function (chunks, cb) { setImmediate(cb, new Error('writev test error')); }; var _firstError3 = false; _writable3.on('finish', common.mustCall(function () { assert.strictEqual(_firstError3, true); })); _writable3.on('prefinish', common.mustCall()); _writable3.on('error', common.mustCall(function (er) { assert.strictEqual(er.message, 'writev test error'); _firstError3 = true; })); _writable3.cork(); _writable3.write('test'); setImmediate(function () { _writable3.end('test'); }); } // Regression test for // https://github.com/nodejs/node/issues/13812 { var rs = new stream.Readable(); rs.push('ok'); rs.push(null); rs._read = function () {}; var ws = new stream.Writable(); var _firstError4 = false; ws.on('finish', common.mustCall(function () { assert.strictEqual(_firstError4, true); })); ws.on('error', common.mustCall(function () { _firstError4 = true; })); ws._write = function (chunk, encoding, done) { setImmediate(done, new Error()); }; rs.pipe(ws); } { var _rs = new stream.Readable(); _rs.push('ok'); _rs.push(null); _rs._read = function () {}; var _ws = new stream.Writable(); _ws.on('finish', common.mustNotCall()); _ws.on('error', common.mustCall()); _ws._write = function (chunk, encoding, done) { done(new Error()); }; _rs.pipe(_ws); }readable-stream-2.3.3/test/parallel/test-stream-writableState-ending.js000066400000000000000000000016141312520600100261720ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var assert = require('assert/'); var stream = require('../../'); var writable = new stream.Writable(); function testStates(ending, finished, ended) { assert.strictEqual(writable._writableState.ending, ending); assert.strictEqual(writable._writableState.finished, finished); assert.strictEqual(writable._writableState.ended, ended); } writable._write = function (chunk, encoding, cb) { // ending, finished, ended start in false. testStates(false, false, false); cb(); }; writable.on('finish', function () { // ending, finished, ended = true. testStates(true, true, true); }); writable.end('testing function end()', function () { // ending, finished, ended = true. testStates(true, true, true); }); // ending, ended = true. // finished = false. testStates(true, false, true);readable-stream-2.3.3/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js000066400000000000000000000033061312520600100327020ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ var common = require('../common'); var assert = require('assert/'); var stream = require('../../'); var writable = new stream.Writable(); writable._writev = common.mustCall(function (chunks, cb) { assert.strictEqual(chunks.length, 2, 'two chunks to write'); cb(); }, 1); writable._write = common.mustCall(function (chunk, encoding, cb) { cb(); }, 1); // first cork writable.cork(); assert.strictEqual(writable._writableState.corked, 1); assert.strictEqual(writable._writableState.bufferedRequestCount, 0); // cork again writable.cork(); assert.strictEqual(writable._writableState.corked, 2); // the first chunk is buffered writable.write('first chunk'); assert.strictEqual(writable._writableState.bufferedRequestCount, 1); // first uncork does nothing writable.uncork(); assert.strictEqual(writable._writableState.corked, 1); assert.strictEqual(writable._writableState.bufferedRequestCount, 1); process.nextTick(uncork); // the second chunk is buffered, because we uncork at the end of tick writable.write('second chunk'); assert.strictEqual(writable._writableState.corked, 1); assert.strictEqual(writable._writableState.bufferedRequestCount, 2); function uncork() { // second uncork flushes the buffer writable.uncork(); assert.strictEqual(writable._writableState.corked, 0); assert.strictEqual(writable._writableState.bufferedRequestCount, 0); // verify that end() uncorks correctly writable.cork(); writable.write('third chunk'); writable.end(); // end causes an uncork() as well assert.strictEqual(writable._writableState.corked, 0); assert.strictEqual(writable._writableState.bufferedRequestCount, 0); }readable-stream-2.3.3/test/parallel/test-stream-write-final.js000066400000000000000000000011341312520600100243340ustar00rootroot00000000000000/**/ 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));readable-stream-2.3.3/test/parallel/test-stream-writev.js000066400000000000000000000070001312520600100234310ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); var queue = []; for (var decode = 0; decode < 2; decode++) { for (var uncork = 0; uncork < 2; uncork++) { for (var multi = 0; multi < 2; multi++) { queue.push([!!decode, !!uncork, !!multi]); } } } run(); function run() { var t = queue.pop(); if (t) test(t[0], t[1], t[2], run);else console.log('ok'); } function test(decode, uncork, multi, next) { console.log('# decode=%j uncork=%j multi=%j', decode, uncork, multi); var counter = 0; var expectCount = 0; function cnt(msg) { expectCount++; var expect = expectCount; return function (er) { assert.ifError(er); counter++; assert.strictEqual(counter, expect); }; } var w = new stream.Writable({ decodeStrings: decode }); w._write = common.mustNotCall('Should not call _write'); var expectChunks = decode ? [{ encoding: 'buffer', chunk: [104, 101, 108, 108, 111, 44, 32] }, { encoding: 'buffer', chunk: [119, 111, 114, 108, 100] }, { encoding: 'buffer', chunk: [33] }, { encoding: 'buffer', chunk: [10, 97, 110, 100, 32, 116, 104, 101, 110, 46, 46, 46] }, { encoding: 'buffer', chunk: [250, 206, 190, 167, 222, 173, 190, 239, 222, 202, 251, 173] }] : [{ encoding: 'ascii', chunk: 'hello, ' }, { encoding: 'utf8', chunk: 'world' }, { encoding: 'buffer', chunk: [33] }, { encoding: 'binary', chunk: '\nand then...' }, { encoding: 'hex', chunk: 'facebea7deadbeefdecafbad' }]; var actualChunks = void 0; w._writev = function (chunks, cb) { actualChunks = chunks.map(function (chunk) { return { encoding: chunk.encoding, chunk: Buffer.isBuffer(chunk.chunk) ? Array.prototype.slice.call(chunk.chunk) : chunk.chunk }; }); cb(); }; w.cork(); w.write('hello, ', 'ascii', cnt('hello')); w.write('world', 'utf8', cnt('world')); if (multi) w.cork(); w.write(bufferShim.from('!'), 'buffer', cnt('!')); w.write('\nand then...', 'binary', cnt('and then')); if (multi) w.uncork(); w.write('facebea7deadbeefdecafbad', 'hex', cnt('hex')); if (uncork) w.uncork(); w.end(cnt('end')); w.on('finish', function () { // make sure finish comes after all the write cb cnt('finish')(); assert.deepStrictEqual(expectChunks, actualChunks); next(); }); }readable-stream-2.3.3/test/parallel/test-stream2-base64-single-char-read-end.js000066400000000000000000000036311312520600100271340ustar00rootroot00000000000000// 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 R = require('../../lib/_stream_readable'); var W = require('../../lib/_stream_writable'); var assert = require('assert/'); var src = new R({ encoding: 'base64' }); var dst = new W(); var hasRead = false; var accum = []; src._read = function (n) { if (!hasRead) { hasRead = true; process.nextTick(function () { src.push(bufferShim.from('1')); src.push(null); }); } }; dst._write = function (chunk, enc, cb) { accum.push(chunk); cb(); }; src.on('end', function () { assert.strictEqual(String(Buffer.concat(accum)), 'MQ=='); clearTimeout(timeout); }); src.pipe(dst); var timeout = setTimeout(function () { assert.fail('timed out waiting for _write'); }, 100);readable-stream-2.3.3/test/parallel/test-stream2-basic.js000066400000000000000000000217001312520600100232570ustar00rootroot00000000000000// 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); }; { // Test basic functionality 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', common.mustCall(function () { assert.deepStrictEqual(reads, expect); })); var readSize = 1; function flow() { var res = void 0; while (null !== (res = r.read(readSize++))) { reads.push(res.toString()); } r.once('readable', flow); } flow(); } { // Verify pipe var _r = new TestReader(5); var _expect = ['xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx']; var w = new TestWriter(); w.on('end', common.mustCall(function (received) { assert.deepStrictEqual(received, _expect); })); _r.pipe(w); } forEach([1, 2, 3, 4, 5, 6, 7, 8, 9], function (SPLIT) { // Verify unpipe 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; w[0].on('end', common.mustCall(function (results) { ended++; assert.strictEqual(ended, 1); assert.deepStrictEqual(results, expect[0]); })); w[1].on('end', common.mustCall(function (results) { ended++; assert.strictEqual(ended, 2); assert.deepStrictEqual(results, expect[1]); })); r.pipe(w[0]); }); { // Verify both writers get the same data when piping to destinations var _r2 = new TestReader(5); var _w = [new TestWriter(), new TestWriter()]; var _expect2 = ['xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx', 'xxxxx']; _w[0].on('end', common.mustCall(function (received) { assert.deepStrictEqual(received, _expect2, 'first'); })); _w[1].on('end', common.mustCall(function (received) { assert.deepStrictEqual(received, _expect2, 'second'); })); _r2.pipe(_w[0]); _r2.pipe(_w[1]); } forEach([1, 2, 3, 4, 5, 6, 7, 8, 9], function (SPLIT) { // Verify multi-unpipe 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', common.mustCall(function (results) { ended++; assert.strictEqual(ended, 1); assert.deepStrictEqual(results, expect[0]); })); w[1].on('end', common.mustCall(function (results) { ended++; assert.strictEqual(ended, 2); assert.deepStrictEqual(results, expect[1]); })); r.pipe(w[0]); r.pipe(w[2]); }); { // Verify that back pressure is respected var _r3 = new R({ objectMode: true }); _r3._read = common.mustNotCall(); var counter = 0; _r3.push(['one']); _r3.push(['two']); _r3.push(['three']); _r3.push(['four']); _r3.push(null); var w1 = new R(); w1.write = function (chunk) { assert.strictEqual(chunk[0], 'one'); w1.emit('close'); process.nextTick(function () { _r3.pipe(w2); _r3.pipe(w3); }); }; w1.end = common.mustNotCall(); _r3.pipe(w1); var expected = ['two', 'two', 'three', 'three', 'four', 'four']; var w2 = new R(); w2.write = function (chunk) { assert.strictEqual(chunk[0], expected.shift()); assert.strictEqual(counter, 0); counter++; if (chunk[0] === 'four') { return true; } setTimeout(function () { counter--; w2.emit('drain'); }, 10); return false; }; w2.end = common.mustCall(); var w3 = new R(); w3.write = function (chunk) { assert.strictEqual(chunk[0], expected.shift()); assert.strictEqual(counter, 1); counter++; if (chunk[0] === 'four') { return true; } setTimeout(function () { counter--; w3.emit('drain'); }, 50); return false; }; w3.end = common.mustCall(function () { assert.strictEqual(counter, 2); assert.strictEqual(expected.length, 0); }); } { // Verify read(0) behavior for ended streams var _r4 = new R(); var written = false; var ended = false; _r4._read = common.mustNotCall(); _r4.push(bufferShim.from('foo')); _r4.push(null); var v = _r4.read(0); assert.strictEqual(v, null); var _w2 = new R(); _w2.write = function (buffer) { written = true; assert.strictEqual(ended, false); assert.strictEqual(buffer.toString(), 'foo'); }; _w2.end = common.mustCall(function () { ended = true; assert.strictEqual(written, true); }); _r4.pipe(_w2); } { // Verify synchronous _read ending var _r5 = new R(); var called = false; _r5._read = function (n) { _r5.push(null); }; _r5.once('end', function () { // Verify that this is called before the next tick called = true; }); _r5.read(); process.nextTick(function () { assert.strictEqual(called, true); }); } { // Verify that adding readable listeners trigger data flow var _r6 = new R({ highWaterMark: 5 }); var onReadable = false; var readCalled = 0; _r6._read = function (n) { if (readCalled++ === 2) _r6.push(null);else _r6.push(bufferShim.from('asdf')); }; _r6.on('readable', function () { onReadable = true; _r6.read(); }); _r6.on('end', common.mustCall(function () { assert.strictEqual(readCalled, 3); assert.ok(onReadable); })); } { // Verify that streams are chainable var _r7 = new R(); _r7._read = common.mustCall(); var r2 = _r7.setEncoding('utf8').pause().resume().pause(); assert.strictEqual(_r7, r2); } function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } }readable-stream-2.3.3/test/parallel/test-stream2-compatibility.js000066400000000000000000000042521312520600100250520ustar00rootroot00000000000000// 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 R = require('../../lib/_stream_readable'); var W = require('../../lib/_stream_writable'); var assert = require('assert/'); var util = require('util'); var ondataCalled = 0; function TestReader() { R.apply(this); this._buffer = bufferShim.alloc(100, 'x'); this.on('data', function () { ondataCalled++; }); } util.inherits(TestReader, R); TestReader.prototype._read = function (n) { this.push(this._buffer); this._buffer = bufferShim.alloc(0); }; var reader = new TestReader(); setImmediate(function () { assert.strictEqual(ondataCalled, 1); console.log('ok'); reader.push(null); }); function TestWriter() { W.apply(this); this.write('foo'); this.end(); } util.inherits(TestWriter, W); TestWriter.prototype._write = function (chunk, enc, cb) { cb(); }; var writer = new TestWriter(); process.on('exit', function () { assert.strictEqual(reader.readable, false); assert.strictEqual(writer.writable, false); console.log('ok'); });readable-stream-2.3.3/test/parallel/test-stream2-decode-partial.js000066400000000000000000000012231312520600100250510ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var Readable = require('../../lib/_stream_readable'); var assert = require('assert/'); var buf = ''; var euro = bufferShim.from([0xE2, 0x82, 0xAC]); var cent = bufferShim.from([0xC2, 0xA2]); var source = Buffer.concat([euro, cent]); var readable = Readable({ encoding: 'utf8' }); readable.push(source.slice(0, 2)); readable.push(source.slice(2, 4)); readable.push(source.slice(4, source.length));; readable.push(null); readable.on('data', function (data) { buf += data; }); process.on('exit', function () { assert.strictEqual(buf, '€¢'); });readable-stream-2.3.3/test/parallel/test-stream2-finish-pipe.js000066400000000000000000000032571312520600100244200ustar00rootroot00000000000000// 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 stream = require('../../'); var Buffer = require('buffer').Buffer; var r = new stream.Readable(); r._read = function (size) { r.push(bufferShim.allocUnsafe(size)); }; var w = new stream.Writable(); w._write = function (data, encoding, cb) { cb(null); }; r.pipe(w); // This might sound unrealistic, but it happens in net.js. When // `socket.allowHalfOpen === false`, EOF will cause `.destroySoon()` call which // ends the writable side of net.Socket. w.end();readable-stream-2.3.3/test/parallel/test-stream2-large-read-stall.js000066400000000000000000000045651312520600100253300ustar00rootroot00000000000000// 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 assert = require('assert/'); // If everything aligns so that you do a read(n) of exactly the // remaining buffer, then make sure that 'end' still emits. var READSIZE = 100; var PUSHSIZE = 20; var PUSHCOUNT = 1000; var HWM = 50; var Readable = require('../../').Readable; var r = new Readable({ highWaterMark: HWM }); var rs = r._readableState; r._read = push; r.on('readable', function () { ;false && console.error('>> readable'); var ret = void 0; do { ;false && console.error(' > read(%d)', READSIZE); ret = r.read(READSIZE); ;false && console.error(' < %j (%d remain)', ret && ret.length, rs.length); } while (ret && ret.length === READSIZE); ;false && console.error('<< after read()', ret && ret.length, rs.needReadable, rs.length); }); r.on('end', common.mustCall(function () { assert.strictEqual(pushes, PUSHCOUNT + 1); })); var pushes = 0; function push() { if (pushes > PUSHCOUNT) return; if (pushes++ === PUSHCOUNT) { ;false && console.error(' push(EOF)'); return r.push(null); } ;false && console.error(' push #%d', pushes); if (r.push(bufferShim.allocUnsafe(PUSHSIZE))) setTimeout(push, 1); }readable-stream-2.3.3/test/parallel/test-stream2-objects.js000066400000000000000000000152341312520600100236340ustar00rootroot00000000000000// 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 Readable = require('../../lib/_stream_readable'); var Writable = require('../../lib/_stream_writable'); var assert = require('assert/'); function toArray(callback) { var stream = new Writable({ objectMode: true }); var list = []; stream.write = function (chunk) { list.push(chunk); }; stream.end = common.mustCall(function () { callback(list); }); return stream; } function fromArray(list) { var r = new Readable({ objectMode: true }); r._read = common.mustNotCall(); forEach(list, function (chunk) { r.push(chunk); }); r.push(null); return r; } { // Verify that objects can be read from the stream var r = fromArray([{ one: '1' }, { two: '2' }]); var v1 = r.read(); var v2 = r.read(); var v3 = r.read(); assert.deepStrictEqual(v1, { one: '1' }); assert.deepStrictEqual(v2, { two: '2' }); assert.deepStrictEqual(v3, null); } { // Verify that objects can be piped into the stream var _r = fromArray([{ one: '1' }, { two: '2' }]); _r.pipe(toArray(common.mustCall(function (list) { assert.deepStrictEqual(list, [{ one: '1' }, { two: '2' }]); }))); } { // Verify that read(n) is ignored var _r2 = fromArray([{ one: '1' }, { two: '2' }]); var value = _r2.read(2); assert.deepStrictEqual(value, { one: '1' }); } { // Verify that objects can be synchronously read var _r3 = new Readable({ objectMode: true }); var list = [{ one: '1' }, { two: '2' }]; _r3._read = function (n) { var item = list.shift(); _r3.push(item || null); }; _r3.pipe(toArray(common.mustCall(function (list) { assert.deepStrictEqual(list, [{ one: '1' }, { two: '2' }]); }))); } { // Verify that objects can be asynchronously read var _r4 = new Readable({ objectMode: true }); var _list = [{ one: '1' }, { two: '2' }]; _r4._read = function (n) { var item = _list.shift(); process.nextTick(function () { _r4.push(item || null); }); }; _r4.pipe(toArray(common.mustCall(function (list) { assert.deepStrictEqual(list, [{ one: '1' }, { two: '2' }]); }))); } { // Verify that strings can be read as objects var _r5 = new Readable({ objectMode: true }); _r5._read = common.mustNotCall(); var _list2 = ['one', 'two', 'three']; forEach(_list2, function (str) { _r5.push(str); }); _r5.push(null); _r5.pipe(toArray(common.mustCall(function (array) { assert.deepStrictEqual(array, _list2); }))); } { // Verify read(0) behavior for object streams var _r6 = new Readable({ objectMode: true }); _r6._read = common.mustNotCall(); _r6.push('foobar'); _r6.push(null); _r6.pipe(toArray(common.mustCall(function (array) { assert.deepStrictEqual(array, ['foobar']); }))); } { // Verify the behavior of pushing falsey values var _r7 = new Readable({ objectMode: true }); _r7._read = common.mustNotCall(); _r7.push(false); _r7.push(0); _r7.push(''); _r7.push(null); _r7.pipe(toArray(common.mustCall(function (array) { assert.deepStrictEqual(array, [false, 0, '']); }))); } { // Verify high watermark _read() behavior var _r8 = new Readable({ highWaterMark: 6, objectMode: true }); var calls = 0; var _list3 = ['1', '2', '3', '4', '5', '6', '7', '8']; _r8._read = function (n) { calls++; }; forEach(_list3, function (c) { _r8.push(c); }); var v = _r8.read(); assert.strictEqual(calls, 0); assert.strictEqual(v, '1'); var _v = _r8.read(); assert.strictEqual(_v, '2'); var _v2 = _r8.read(); assert.strictEqual(_v2, '3'); assert.strictEqual(calls, 1); } { // Verify high watermark push behavior var _r9 = new Readable({ highWaterMark: 6, objectMode: true }); _r9._read = common.mustNotCall(); for (var i = 0; i < 6; i++) { var bool = _r9.push(i); assert.strictEqual(bool, i !== 5); } } { // Verify that objects can be written to stream var w = new Writable({ objectMode: true }); w._write = function (chunk, encoding, cb) { assert.deepStrictEqual(chunk, { foo: 'bar' }); cb(); }; w.on('finish', common.mustCall()); w.write({ foo: 'bar' }); w.end(); } { // Verify that multiple objects can be written to stream var _w = new Writable({ objectMode: true }); var _list4 = []; _w._write = function (chunk, encoding, cb) { _list4.push(chunk); cb(); }; _w.on('finish', common.mustCall(function () { assert.deepStrictEqual(_list4, [0, 1, 2, 3, 4]); })); _w.write(0); _w.write(1); _w.write(2); _w.write(3); _w.write(4); _w.end(); } { // Verify that strings can be written as objects var _w2 = new Writable({ objectMode: true }); var _list5 = []; _w2._write = function (chunk, encoding, cb) { _list5.push(chunk); process.nextTick(cb); }; _w2.on('finish', common.mustCall(function () { assert.deepStrictEqual(_list5, ['0', '1', '2', '3', '4']); })); _w2.write('0'); _w2.write('1'); _w2.write('2'); _w2.write('3'); _w2.write('4'); _w2.end(); } { // Verify that stream buffers finish until callback is called var _w3 = new Writable({ objectMode: true }); var called = false; _w3._write = function (chunk, encoding, cb) { assert.strictEqual(chunk, 'foo'); process.nextTick(function () { called = true; cb(); }); }; _w3.on('finish', common.mustCall(function () { assert.strictEqual(called, true); })); _w3.write('foo'); _w3.end(); } function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } }readable-stream-2.3.3/test/parallel/test-stream2-pipe-error-handling.js000066400000000000000000000057061312520600100260540ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); { var count = 1000; var source = new stream.Readable(); source._read = function (n) { n = Math.min(count, n); count -= n; source.push(bufferShim.allocUnsafe(n)); }; var unpipedDest = void 0; source.unpipe = function (dest) { unpipedDest = dest; stream.Readable.prototype.unpipe.call(this, dest); }; var dest = new stream.Writable(); dest._write = function (chunk, encoding, cb) { cb(); }; source.pipe(dest); var gotErr = null; dest.on('error', function (err) { gotErr = err; }); var unpipedSource = void 0; dest.on('unpipe', function (src) { unpipedSource = src; }); var err = new Error('This stream turned into bacon.'); dest.emit('error', err); assert.strictEqual(gotErr, err); assert.strictEqual(unpipedSource, source); assert.strictEqual(unpipedDest, dest); } { var _count = 1000; var _source = new stream.Readable(); _source._read = function (n) { n = Math.min(_count, n); _count -= n; _source.push(bufferShim.allocUnsafe(n)); }; var _unpipedDest = void 0; _source.unpipe = function (dest) { _unpipedDest = dest; stream.Readable.prototype.unpipe.call(this, dest); }; var _dest = new stream.Writable(); _dest._write = function (chunk, encoding, cb) { cb(); }; _source.pipe(_dest); var _unpipedSource = void 0; _dest.on('unpipe', function (src) { _unpipedSource = src; }); var _err = new Error('This stream turned into bacon.'); var _gotErr = null; try { _dest.emit('error', _err); } catch (e) { _gotErr = e; } assert.strictEqual(_gotErr, _err); assert.strictEqual(_unpipedSource, _source); assert.strictEqual(_unpipedDest, _dest); }readable-stream-2.3.3/test/parallel/test-stream2-pipe-error-once-listener.js000066400000000000000000000036521312520600100270350ustar00rootroot00000000000000// 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 util = require('util'); var stream = require('../../'); function Read() { stream.Readable.call(this); } util.inherits(Read, stream.Readable); Read.prototype._read = function (size) { this.push('x'); this.push(null); }; function Write() { stream.Writable.call(this); } util.inherits(Write, stream.Writable); Write.prototype._write = function (buffer, encoding, cb) { this.emit('error', new Error('boom')); this.emit('alldone'); }; var read = new Read(); var write = new Write(); write.once('error', common.noop); write.once('alldone', function (err) { console.log('ok'); }); process.on('exit', function (c) { console.error('error thrown even with listener'); }); read.pipe(write);readable-stream-2.3.3/test/parallel/test-stream2-push.js000066400000000000000000000062561312520600100231660ustar00rootroot00000000000000// 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 Readable = require('../../').Readable; var Writable = require('../../').Writable; var assert = require('assert/'); var EE = require('events').EventEmitter; // a mock thing a bit like the net.Socket/tcp_wrap.handle interaction var stream = new Readable({ highWaterMark: 16, encoding: 'utf8' }); var source = new EE(); stream._read = function () { console.error('stream._read'); readStart(); }; var ended = false; stream.on('end', function () { ended = true; }); source.on('data', function (chunk) { var ret = stream.push(chunk); console.error('data', stream._readableState.length); if (!ret) readStop(); }); source.on('end', function () { stream.push(null); }); var reading = false; function readStart() { console.error('readStart'); reading = true; } function readStop() { console.error('readStop'); reading = false; process.nextTick(function () { var r = stream.read(); if (r !== null) writer.write(r); }); } var writer = new Writable({ decodeStrings: false }); var written = []; var expectWritten = ['asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg', 'asdfgasdfgasdfgasdfg']; writer._write = function (chunk, encoding, cb) { console.error('WRITE %s', chunk); written.push(chunk); process.nextTick(cb); }; writer.on('finish', finish); // now emit some chunks. var chunk = 'asdfg'; var set = 0; readStart(); data(); function data() { assert(reading); source.emit('data', chunk); assert(reading); source.emit('data', chunk); assert(reading); source.emit('data', chunk); assert(reading); source.emit('data', chunk); assert(!reading); if (set++ < 5) setTimeout(data, 10);else end(); } function finish() { console.error('finish'); assert.deepStrictEqual(written, expectWritten); console.log('ok'); } function end() { source.emit('end'); assert(!reading); writer.end(stream.read()); setImmediate(function () { assert(ended); }); }readable-stream-2.3.3/test/parallel/test-stream2-read-sync-stack.js000066400000000000000000000034141312520600100251700ustar00rootroot00000000000000// 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 Readable = require('../../').Readable; var r = new Readable(); var N = 256 * 1024; // Go ahead and allow the pathological case for this test. // Yes, it's an infinite loop, that's the point. process.maxTickDepth = N + 2; var reads = 0; r._read = function (n) { var chunk = reads++ === N ? null : bufferShim.allocUnsafe(1); r.push(chunk); }; r.on('readable', function onReadable() { if (!(r._readableState.length % 256)) console.error('readable', r._readableState.length); r.read(N * 2); }); r.on('end', common.mustCall()); r.read(0);readable-stream-2.3.3/test/parallel/test-stream2-readable-empty-buffer-no-eof.js000066400000000000000000000070621312520600100275260ustar00rootroot00000000000000// 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 assert = require('assert/'); var Readable = require('../../').Readable; test1(); test2(); function test1() { var r = new Readable(); // should not end when we get a bufferShim.alloc(0) or '' as the _read // result that just means that there is *temporarily* no data, but to // go ahead and try again later. // // note that this is very unusual. it only works for crypto streams // because the other side of the stream will call read(0) to cycle // data through openssl. that's why setImmediate() is used to call // r.read(0) again later, otherwise there is no more work being done // and the process just exits. var buf = bufferShim.alloc(5, 'x'); var reads = 5; r._read = function (n) { switch (reads--) { case 5: return setImmediate(function () { return r.push(buf); }); case 4: setImmediate(function () { return r.push(bufferShim.alloc(0)); }); return setImmediate(r.read.bind(r, 0)); case 3: setTimeout(r.read.bind(r, 0), 50); return process.nextTick(function () { return r.push(bufferShim.alloc(0)); }); case 2: setImmediate(r.read.bind(r, 0)); return r.push(bufferShim.alloc(0)); // Not-EOF! case 1: return r.push(buf); case 0: return r.push(null); // EOF default: throw new Error('unreachable'); } }; var results = []; function flow() { var chunk = void 0; while (null !== (chunk = r.read())) { results.push(String(chunk)); } } r.on('readable', flow); r.on('end', function () { results.push('EOF'); }); flow(); process.on('exit', function () { assert.deepStrictEqual(results, ['xxxxx', 'xxxxx', 'EOF']); console.log('ok'); }); } function test2() { var r = new Readable({ encoding: 'base64' }); var reads = 5; r._read = function (n) { if (!reads--) return r.push(null); // EOF else return r.push(bufferShim.from('x')); }; var results = []; function flow() { var chunk = void 0; while (null !== (chunk = r.read())) { results.push(String(chunk)); } } r.on('readable', flow); r.on('end', function () { results.push('EOF'); }); flow(); process.on('exit', function () { assert.deepStrictEqual(results, ['eHh4', 'eHg=', 'EOF']); console.log('ok'); }); }readable-stream-2.3.3/test/parallel/test-stream2-readable-from-list.js000066400000000000000000000061051312520600100256510ustar00rootroot00000000000000// 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; /**/ require('../common'); var assert = require('assert/'); var fromList = require('../../lib/_stream_readable')._fromList; var BufferList = require('../../lib/internal/streams/BufferList'); function bufferListFromArray(arr) { var bl = new BufferList(); for (var i = 0; i < arr.length; ++i) { bl.push(arr[i]); }return bl; } { // Verify behavior with buffers var list = [bufferShim.from('foog'), bufferShim.from('bark'), bufferShim.from('bazy'), bufferShim.from('kuel')]; list = bufferListFromArray(list); // read more than the first element. var ret = fromList(6, { buffer: list, length: 16 }); assert.strictEqual(ret.toString(), 'foogba'); // read exactly the first element. ret = fromList(2, { buffer: list, length: 10 }); assert.strictEqual(ret.toString(), 'rk'); // read less than the first element. ret = fromList(2, { buffer: list, length: 8 }); assert.strictEqual(ret.toString(), 'ba'); // read more than we have. ret = fromList(100, { buffer: list, length: 6 }); assert.strictEqual(ret.toString(), 'zykuel'); // all consumed. assert.deepStrictEqual(list, new BufferList()); } { // Verify behavior with strings var _list = ['foog', 'bark', 'bazy', 'kuel']; _list = bufferListFromArray(_list); // read more than the first element. var _ret = fromList(6, { buffer: _list, length: 16, decoder: true }); assert.strictEqual(_ret, 'foogba'); // read exactly the first element. _ret = fromList(2, { buffer: _list, length: 10, decoder: true }); assert.strictEqual(_ret, 'rk'); // read less than the first element. _ret = fromList(2, { buffer: _list, length: 8, decoder: true }); assert.strictEqual(_ret, 'ba'); // read more than we have. _ret = fromList(100, { buffer: _list, length: 6, decoder: true }); assert.strictEqual(_ret, 'zykuel'); // all consumed. assert.deepStrictEqual(_list, new BufferList()); }readable-stream-2.3.3/test/parallel/test-stream2-readable-legacy-drain.js000066400000000000000000000037701312520600100263010ustar00rootroot00000000000000// 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 assert = require('assert/'); var Stream = require('../../'); var Readable = require('../../').Readable; var r = new Readable(); var N = 256; var reads = 0; r._read = function (n) { return r.push(++reads === N ? null : bufferShim.allocUnsafe(1)); }; r.on('end', common.mustCall()); var w = new Stream(); w.writable = true; var buffered = 0; w.write = function (c) { buffered += c.length; process.nextTick(drain); return false; }; function drain() { assert(buffered <= 3); buffered = 0; w.emit('drain'); } w.end = common.mustCall(); // Just for kicks, let's mess with the drain count. // This verifies that even if it gets negative in the // pipe() cleanup function, we'll still function properly. r.on('readable', function () { w.emit('drain'); }); r.pipe(w);readable-stream-2.3.3/test/parallel/test-stream2-readable-non-empty-end.js000066400000000000000000000044001312520600100264230ustar00rootroot00000000000000// 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 assert = require('assert/'); var Readable = require('../../lib/_stream_readable'); var len = 0; var chunks = new Array(10); for (var i = 1; i <= 10; i++) { chunks[i - 1] = bufferShim.allocUnsafe(i); len += i; } var test = new Readable(); var n = 0; test._read = function (size) { var chunk = chunks[n++]; setTimeout(function () { test.push(chunk === undefined ? null : chunk); }, 1); }; test.on('end', thrower); function thrower() { throw new Error('this should not happen!'); } var bytesread = 0; test.on('readable', function () { var b = len - bytesread - 1; var res = test.read(b); if (res) { bytesread += res.length; console.error('br=%d len=%d', bytesread, len); setTimeout(next, 1); } test.read(0); }); test.read(0); function next() { // now let's make 'end' happen test.removeListener('end', thrower); test.on('end', common.mustCall()); // one to get the last byte var r = test.read(); assert(r); assert.strictEqual(r.length, 1); r = test.read(); assert.strictEqual(r, null); }readable-stream-2.3.3/test/parallel/test-stream2-readable-wrap-empty.js000066400000000000000000000030551312520600100260430ustar00rootroot00000000000000// 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 Readable = require('../../lib/_stream_readable'); var EE = require('events').EventEmitter; var oldStream = new EE(); oldStream.pause = common.noop; oldStream.resume = common.noop; var newStream = new Readable().wrap(oldStream); newStream.on('readable', common.noop).on('end', common.mustCall()); oldStream.emit('end');readable-stream-2.3.3/test/parallel/test-stream2-set-encoding.js000066400000000000000000000153201312520600100245560ustar00rootroot00000000000000// 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 assert = require('assert/'); var R = require('../../lib/_stream_readable'); var util = require('util'); util.inherits(TestReader, R); function TestReader(n, opts) { R.call(this, opts); this.pos = 0; this.len = n || 100; } TestReader.prototype._read = function (n) { setTimeout(function () { if (this.pos >= this.len) { // double push(null) to test eos handling this.push(null); return this.push(null); } n = Math.min(n, this.len - this.pos); if (n <= 0) { // double push(null) to test eos handling this.push(null); return this.push(null); } this.pos += n; var ret = bufferShim.alloc(n, 'a'); return this.push(ret); }.bind(this), 1); }; { // Verify utf8 encoding var tr = new TestReader(100); tr.setEncoding('utf8'); var out = []; var expect = ['aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa']; tr.on('readable', function flow() { var chunk = void 0; while (null !== (chunk = tr.read(10))) { out.push(chunk); } }); tr.on('end', common.mustCall(function () { assert.deepStrictEqual(out, expect); })); } { // Verify hex encoding var _tr = new TestReader(100); _tr.setEncoding('hex'); var _out = []; var _expect = ['6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161']; _tr.on('readable', function flow() { var chunk = void 0; while (null !== (chunk = _tr.read(10))) { _out.push(chunk); } }); _tr.on('end', common.mustCall(function () { assert.deepStrictEqual(_out, _expect); })); } { // Verify hex encoding with read(13) var _tr2 = new TestReader(100); _tr2.setEncoding('hex'); var _out2 = []; var _expect2 = ['6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '16161']; _tr2.on('readable', function flow() { var chunk = void 0; while (null !== (chunk = _tr2.read(13))) { _out2.push(chunk); } }); _tr2.on('end', common.mustCall(function () { assert.deepStrictEqual(_out2, _expect2); })); } { // Verify base64 encoding var _tr3 = new TestReader(100); _tr3.setEncoding('base64'); var _out3 = []; var _expect3 = ['YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYQ==']; _tr3.on('readable', function flow() { var chunk = void 0; while (null !== (chunk = _tr3.read(10))) { _out3.push(chunk); } }); _tr3.on('end', common.mustCall(function () { assert.deepStrictEqual(_out3, _expect3); })); } { // Verify utf8 encoding var _tr4 = new TestReader(100, { encoding: 'utf8' }); var _out4 = []; var _expect4 = ['aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaa']; _tr4.on('readable', function flow() { var chunk = void 0; while (null !== (chunk = _tr4.read(10))) { _out4.push(chunk); } }); _tr4.on('end', common.mustCall(function () { assert.deepStrictEqual(_out4, _expect4); })); } { // Verify hex encoding var _tr5 = new TestReader(100, { encoding: 'hex' }); var _out5 = []; var _expect5 = ['6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161', '6161616161']; _tr5.on('readable', function flow() { var chunk = void 0; while (null !== (chunk = _tr5.read(10))) { _out5.push(chunk); } }); _tr5.on('end', common.mustCall(function () { assert.deepStrictEqual(_out5, _expect5); })); } { // Verify hex encoding with read(13) var _tr6 = new TestReader(100, { encoding: 'hex' }); var _out6 = []; var _expect6 = ['6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '1616161616161', '6161616161616', '16161']; _tr6.on('readable', function flow() { var chunk = void 0; while (null !== (chunk = _tr6.read(13))) { _out6.push(chunk); } }); _tr6.on('end', common.mustCall(function () { assert.deepStrictEqual(_out6, _expect6); })); } { // Verify base64 encoding var _tr7 = new TestReader(100, { encoding: 'base64' }); var _out7 = []; var _expect7 = ['YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYWFhYWFh', 'YWFhYWFhYW', 'FhYQ==']; _tr7.on('readable', function flow() { var chunk = void 0; while (null !== (chunk = _tr7.read(10))) { _out7.push(chunk); } }); _tr7.on('end', common.mustCall(function () { assert.deepStrictEqual(_out7, _expect7); })); } { // Verify chaining behavior var _tr8 = new TestReader(100); assert.deepStrictEqual(_tr8.setEncoding('utf8'), _tr8); }readable-stream-2.3.3/test/parallel/test-stream2-transform.js000066400000000000000000000303351312520600100242150ustar00rootroot00000000000000// 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 assert = require('assert/'); var PassThrough = require('../../lib/_stream_passthrough'); var Transform = require('../../lib/_stream_transform'); { // Verify writable side consumption var tx = new Transform({ highWaterMark: 10 }); var transformed = 0; tx._transform = function (chunk, encoding, cb) { transformed += chunk.length; tx.push(chunk); cb(); }; for (var i = 1; i <= 10; i++) { tx.write(bufferShim.allocUnsafe(i)); } tx.end(); assert.strictEqual(tx._readableState.length, 10); assert.strictEqual(transformed, 10); assert.strictEqual(tx._transformState.writechunk.length, 5); assert.deepStrictEqual(tx._writableState.getBuffer().map(function (c) { return c.chunk.length; }), [6, 7, 8, 9, 10]); } { // Verify passthrough behavior var pt = new PassThrough(); pt.write(bufferShim.from('foog')); pt.write(bufferShim.from('bark')); pt.write(bufferShim.from('bazy')); pt.write(bufferShim.from('kuel')); pt.end(); assert.strictEqual(pt.read(5).toString(), 'foogb'); assert.strictEqual(pt.read(5).toString(), 'arkba'); assert.strictEqual(pt.read(5).toString(), 'zykue'); assert.strictEqual(pt.read(5).toString(), 'l'); } { // Verify object passthrough behavior var _pt = new PassThrough({ objectMode: true }); _pt.write(1); _pt.write(true); _pt.write(false); _pt.write(0); _pt.write('foo'); _pt.write(''); _pt.write({ a: 'b' }); _pt.end(); assert.strictEqual(_pt.read(), 1); assert.strictEqual(_pt.read(), true); assert.strictEqual(_pt.read(), false); assert.strictEqual(_pt.read(), 0); assert.strictEqual(_pt.read(), 'foo'); assert.strictEqual(_pt.read(), ''); assert.deepStrictEqual(_pt.read(), { a: 'b' }); } { // Verify passthrough constructor behavior var _pt2 = PassThrough(); assert(_pt2 instanceof PassThrough); } { // Perform a simple transform var _pt3 = new Transform(); _pt3._transform = function (c, e, cb) { var ret = bufferShim.alloc(c.length, 'x'); _pt3.push(ret); cb(); }; _pt3.write(bufferShim.from('foog')); _pt3.write(bufferShim.from('bark')); _pt3.write(bufferShim.from('bazy')); _pt3.write(bufferShim.from('kuel')); _pt3.end(); assert.strictEqual(_pt3.read(5).toString(), 'xxxxx'); assert.strictEqual(_pt3.read(5).toString(), 'xxxxx'); assert.strictEqual(_pt3.read(5).toString(), 'xxxxx'); assert.strictEqual(_pt3.read(5).toString(), 'x'); } { // Verify simple object transform var _pt4 = new Transform({ objectMode: true }); _pt4._transform = function (c, e, cb) { _pt4.push(JSON.stringify(c)); cb(); }; _pt4.write(1); _pt4.write(true); _pt4.write(false); _pt4.write(0); _pt4.write('foo'); _pt4.write(''); _pt4.write({ a: 'b' }); _pt4.end(); assert.strictEqual(_pt4.read(), '1'); assert.strictEqual(_pt4.read(), 'true'); assert.strictEqual(_pt4.read(), 'false'); assert.strictEqual(_pt4.read(), '0'); assert.strictEqual(_pt4.read(), '"foo"'); assert.strictEqual(_pt4.read(), '""'); assert.strictEqual(_pt4.read(), '{"a":"b"}'); } { // Verify async passthrough var _pt5 = new Transform(); _pt5._transform = function (chunk, encoding, cb) { setTimeout(function () { _pt5.push(chunk); cb(); }, 10); }; _pt5.write(bufferShim.from('foog')); _pt5.write(bufferShim.from('bark')); _pt5.write(bufferShim.from('bazy')); _pt5.write(bufferShim.from('kuel')); _pt5.end(); _pt5.on('finish', common.mustCall(function () { assert.strictEqual(_pt5.read(5).toString(), 'foogb'); assert.strictEqual(_pt5.read(5).toString(), 'arkba'); assert.strictEqual(_pt5.read(5).toString(), 'zykue'); assert.strictEqual(_pt5.read(5).toString(), 'l'); })); } { // Verify assymetric transform (expand) var _pt6 = new Transform(); // emit each chunk 2 times. _pt6._transform = function (chunk, encoding, cb) { setTimeout(function () { _pt6.push(chunk); setTimeout(function () { _pt6.push(chunk); cb(); }, 10); }, 10); }; _pt6.write(bufferShim.from('foog')); _pt6.write(bufferShim.from('bark')); _pt6.write(bufferShim.from('bazy')); _pt6.write(bufferShim.from('kuel')); _pt6.end(); _pt6.on('finish', common.mustCall(function () { assert.strictEqual(_pt6.read(5).toString(), 'foogf'); assert.strictEqual(_pt6.read(5).toString(), 'oogba'); assert.strictEqual(_pt6.read(5).toString(), 'rkbar'); assert.strictEqual(_pt6.read(5).toString(), 'kbazy'); assert.strictEqual(_pt6.read(5).toString(), 'bazyk'); assert.strictEqual(_pt6.read(5).toString(), 'uelku'); assert.strictEqual(_pt6.read(5).toString(), 'el'); })); } { // Verify assymetric trasform (compress) var _pt7 = new Transform(); // each output is the first char of 3 consecutive chunks, // or whatever's left. _pt7.state = ''; _pt7._transform = function (chunk, encoding, cb) { if (!chunk) chunk = ''; var s = chunk.toString(); setTimeout(function () { this.state += s.charAt(0); if (this.state.length === 3) { _pt7.push(bufferShim.from(this.state)); this.state = ''; } cb(); }.bind(this), 10); }; _pt7._flush = function (cb) { // just output whatever we have. _pt7.push(bufferShim.from(this.state)); this.state = ''; cb(); }; _pt7.write(bufferShim.from('aaaa')); _pt7.write(bufferShim.from('bbbb')); _pt7.write(bufferShim.from('cccc')); _pt7.write(bufferShim.from('dddd')); _pt7.write(bufferShim.from('eeee')); _pt7.write(bufferShim.from('aaaa')); _pt7.write(bufferShim.from('bbbb')); _pt7.write(bufferShim.from('cccc')); _pt7.write(bufferShim.from('dddd')); _pt7.write(bufferShim.from('eeee')); _pt7.write(bufferShim.from('aaaa')); _pt7.write(bufferShim.from('bbbb')); _pt7.write(bufferShim.from('cccc')); _pt7.write(bufferShim.from('dddd')); _pt7.end(); // 'abcdeabcdeabcd' _pt7.on('finish', common.mustCall(function () { assert.strictEqual(_pt7.read(5).toString(), 'abcde'); assert.strictEqual(_pt7.read(5).toString(), 'abcde'); assert.strictEqual(_pt7.read(5).toString(), 'abcd'); })); } // this tests for a stall when data is written to a full stream // that has empty transforms. { // Verify compex transform behavior var count = 0; var saved = null; var _pt8 = new Transform({ highWaterMark: 3 }); _pt8._transform = function (c, e, cb) { if (count++ === 1) saved = c;else { if (saved) { _pt8.push(saved); saved = null; } _pt8.push(c); } cb(); }; _pt8.once('readable', function () { process.nextTick(function () { _pt8.write(bufferShim.from('d')); _pt8.write(bufferShim.from('ef'), common.mustCall(function () { _pt8.end(); })); assert.strictEqual(_pt8.read().toString(), 'abcdef'); assert.strictEqual(_pt8.read(), null); }); }); _pt8.write(bufferShim.from('abc')); } { // Verify passthrough event emission var _pt9 = new PassThrough(); var emits = 0; _pt9.on('readable', function () { emits++; }); _pt9.write(bufferShim.from('foog')); _pt9.write(bufferShim.from('bark')); assert.strictEqual(emits, 1); assert.strictEqual(_pt9.read(5).toString(), 'foogb'); assert.strictEqual(String(_pt9.read(5)), 'null'); _pt9.write(bufferShim.from('bazy')); _pt9.write(bufferShim.from('kuel')); assert.strictEqual(emits, 2); assert.strictEqual(_pt9.read(5).toString(), 'arkba'); assert.strictEqual(_pt9.read(5).toString(), 'zykue'); assert.strictEqual(_pt9.read(5), null); _pt9.end(); assert.strictEqual(emits, 3); assert.strictEqual(_pt9.read(5).toString(), 'l'); assert.strictEqual(_pt9.read(5), null); assert.strictEqual(emits, 3); } { // Verify passthrough event emission reordering var _pt10 = new PassThrough(); var _emits = 0; _pt10.on('readable', function () { _emits++; }); _pt10.write(bufferShim.from('foog')); _pt10.write(bufferShim.from('bark')); assert.strictEqual(_emits, 1); assert.strictEqual(_pt10.read(5).toString(), 'foogb'); assert.strictEqual(_pt10.read(5), null); _pt10.once('readable', common.mustCall(function () { assert.strictEqual(_pt10.read(5).toString(), 'arkba'); assert.strictEqual(_pt10.read(5), null); _pt10.once('readable', common.mustCall(function () { assert.strictEqual(_pt10.read(5).toString(), 'zykue'); assert.strictEqual(_pt10.read(5), null); _pt10.once('readable', common.mustCall(function () { assert.strictEqual(_pt10.read(5).toString(), 'l'); assert.strictEqual(_pt10.read(5), null); assert.strictEqual(_emits, 4); })); _pt10.end(); })); _pt10.write(bufferShim.from('kuel')); })); _pt10.write(bufferShim.from('bazy')); } { // Verify passthrough facade var _pt11 = new PassThrough(); var datas = []; _pt11.on('data', function (chunk) { datas.push(chunk.toString()); }); _pt11.on('end', common.mustCall(function () { assert.deepStrictEqual(datas, ['foog', 'bark', 'bazy', 'kuel']); })); _pt11.write(bufferShim.from('foog')); setTimeout(function () { _pt11.write(bufferShim.from('bark')); setTimeout(function () { _pt11.write(bufferShim.from('bazy')); setTimeout(function () { _pt11.write(bufferShim.from('kuel')); setTimeout(function () { _pt11.end(); }, 10); }, 10); }, 10); }, 10); } { // Verify object transform (JSON parse) var jp = new Transform({ objectMode: true }); jp._transform = function (data, encoding, cb) { try { jp.push(JSON.parse(data)); cb(); } catch (er) { cb(er); } }; // anything except null/undefined is fine. // those are "magic" in the stream API, because they signal EOF. var objects = [{ foo: 'bar' }, 100, 'string', { nested: { things: [{ foo: 'bar' }, 100, 'string'] } }]; var ended = false; jp.on('end', function () { ended = true; }); forEach(objects, function (obj) { jp.write(JSON.stringify(obj)); var res = jp.read(); assert.deepStrictEqual(res, obj); }); jp.end(); // read one more time to get the 'end' event jp.read(); process.nextTick(common.mustCall(function () { assert.strictEqual(ended, true); })); } { // Verify object transform (JSON stringify) var js = new Transform({ objectMode: true }); js._transform = function (data, encoding, cb) { try { js.push(JSON.stringify(data)); cb(); } catch (er) { cb(er); } }; // anything except null/undefined is fine. // those are "magic" in the stream API, because they signal EOF. var _objects = [{ foo: 'bar' }, 100, 'string', { nested: { things: [{ foo: 'bar' }, 100, 'string'] } }]; var _ended = false; js.on('end', function () { _ended = true; }); forEach(_objects, function (obj) { js.write(obj); var res = js.read(); assert.strictEqual(res, JSON.stringify(obj)); }); js.end(); // read one more time to get the 'end' event js.read(); process.nextTick(common.mustCall(function () { assert.strictEqual(_ended, true); })); } function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } }readable-stream-2.3.3/test/parallel/test-stream2-unpipe-drain.js000066400000000000000000000045531312520600100246000ustar00rootroot00000000000000(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; /**/ require('../common'); var assert = require('assert/'); var stream = require('../../'); var util = require('util'); function TestWriter() { stream.Writable.call(this); } util.inherits(TestWriter, stream.Writable); TestWriter.prototype._write = function (buffer, encoding, callback) { console.log('write called'); // super slow write stream (callback never called) }; var dest = new TestWriter(); function TestReader(id) { stream.Readable.call(this); this.reads = 0; } util.inherits(TestReader, stream.Readable); TestReader.prototype._read = function (size) { this.reads += 1; this.push(bufferShim.alloc(size)); }; var src1 = new TestReader(); var src2 = new TestReader(); src1.pipe(dest); src1.once('readable', function () { process.nextTick(function () { src2.pipe(dest); src2.once('readable', function () { process.nextTick(function () { src1.unpipe(dest); }); }); }); }); process.on('exit', function () { assert.strictEqual(src1.reads, 2); assert.strictEqual(src2.reads, 2); }); })();readable-stream-2.3.3/test/parallel/test-stream2-unpipe-leak.js000066400000000000000000000051151312520600100244120ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); var chunk = bufferShim.from('hallo'); var util = require('util'); function TestWriter() { stream.Writable.call(this); } util.inherits(TestWriter, stream.Writable); TestWriter.prototype._write = function (buffer, encoding, callback) { callback(null); }; var dest = new TestWriter(); // Set this high so that we'd trigger a nextTick warning // and/or RangeError if we do maybeReadMore wrong. function TestReader() { stream.Readable.call(this, { highWaterMark: 0x10000 }); } util.inherits(TestReader, stream.Readable); TestReader.prototype._read = function (size) { this.push(chunk); }; var src = new TestReader(); for (var i = 0; i < 10; i++) { src.pipe(dest); src.unpipe(dest); } assert.strictEqual(src.listeners('end').length, 0); assert.strictEqual(src.listeners('readable').length, 0); assert.strictEqual(dest.listeners('unpipe').length, 0); assert.strictEqual(dest.listeners('drain').length, 0); assert.strictEqual(dest.listeners('error').length, 0); assert.strictEqual(dest.listeners('close').length, 0); assert.strictEqual(dest.listeners('finish').length, 0); console.error(src._readableState); process.on('exit', function () { src._readableState.buffer.length = 0; console.error(src._readableState); assert(src._readableState.length >= src._readableState.highWaterMark); console.log('ok'); });readable-stream-2.3.3/test/parallel/test-stream2-writable.js000066400000000000000000000224321312520600100240120ustar00rootroot00000000000000// 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 W = require('../../lib/_stream_writable'); var D = require('../../lib/_stream_duplex'); var assert = require('assert/'); var util = require('util'); util.inherits(TestWriter, W); function TestWriter() { W.apply(this, arguments); this.buffer = []; this.written = 0; } TestWriter.prototype._write = function (chunk, encoding, cb) { // simulate a small unpredictable latency setTimeout(function () { this.buffer.push(chunk.toString()); this.written += chunk.length; cb(); }.bind(this), Math.floor(Math.random() * 10)); }; var chunks = new Array(50); for (var i = 0; i < chunks.length; i++) { chunks[i] = 'x'.repeat(i); } { // Verify fast writing var tw = new TestWriter({ highWaterMark: 100 }); tw.on('finish', common.mustCall(function () { assert.deepStrictEqual(tw.buffer, chunks, 'got chunks in the right order'); })); forEach(chunks, function (chunk) { // Ignore backpressure. Just buffer it all up. tw.write(chunk); }); tw.end(); } { // Verify slow writing var _tw = new TestWriter({ highWaterMark: 100 }); _tw.on('finish', common.mustCall(function () { assert.deepStrictEqual(_tw.buffer, chunks, 'got chunks in the right order'); })); var _i = 0; (function W() { _tw.write(chunks[_i++]); if (_i < chunks.length) setTimeout(W, 10);else _tw.end(); })(); } { // Verify write backpressure var _tw2 = new TestWriter({ highWaterMark: 50 }); var drains = 0; _tw2.on('finish', common.mustCall(function () { assert.deepStrictEqual(_tw2.buffer, chunks, 'got chunks in the right order'); assert.strictEqual(drains, 17); })); _tw2.on('drain', function () { drains++; }); var _i2 = 0; (function W() { var ret = void 0; do { ret = _tw2.write(chunks[_i2++]); } while (ret !== false && _i2 < chunks.length); if (_i2 < chunks.length) { assert(_tw2._writableState.length >= 50); _tw2.once('drain', W); } else { _tw2.end(); } })(); } { // Verify write buffersize var _tw3 = new TestWriter({ highWaterMark: 100 }); var encodings = ['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', undefined]; _tw3.on('finish', function () { assert.deepStrictEqual(_tw3.buffer, chunks, 'got the expected chunks'); }); forEach(chunks, function (chunk, i) { var enc = encodings[i % encodings.length]; chunk = bufferShim.from(chunk); _tw3.write(chunk.toString(enc), enc); }); } { // Verify write with no buffersize var _tw4 = new TestWriter({ highWaterMark: 100, decodeStrings: false }); _tw4._write = function (chunk, encoding, cb) { assert.strictEqual(typeof chunk, 'string'); chunk = bufferShim.from(chunk, encoding); return TestWriter.prototype._write.call(this, chunk, encoding, cb); }; var _encodings = ['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', undefined]; _tw4.on('finish', function () { assert.deepStrictEqual(_tw4.buffer, chunks, 'got the expected chunks'); }); forEach(chunks, function (chunk, i) { var enc = _encodings[i % _encodings.length]; chunk = bufferShim.from(chunk); _tw4.write(chunk.toString(enc), enc); }); } { // Verify write callbacks var callbacks = chunks.map(function (chunk, i) { return [i, function () { callbacks._called[i] = chunk; }]; }).reduce(function (set, x) { set['callback-' + x[0]] = x[1]; return set; }, {}); callbacks._called = []; var _tw5 = new TestWriter({ highWaterMark: 100 }); _tw5.on('finish', common.mustCall(function () { process.nextTick(common.mustCall(function () { assert.deepStrictEqual(_tw5.buffer, chunks, 'got chunks in the right order'); assert.deepStrictEqual(callbacks._called, chunks, 'called all callbacks'); })); })); forEach(chunks, function (chunk, i) { _tw5.write(chunk, callbacks['callback-' + i]); }); _tw5.end(); } { // Verify end() callback var _tw6 = new TestWriter(); _tw6.end(common.mustCall()); } { // Verify end() callback with chunk var _tw7 = new TestWriter(); _tw7.end(bufferShim.from('hello world'), common.mustCall()); } { // Verify end() callback with chunk and encoding var _tw8 = new TestWriter(); _tw8.end('hello world', 'ascii', common.mustCall()); } { // Verify end() callback after write() call var _tw9 = new TestWriter(); _tw9.write(bufferShim.from('hello world')); _tw9.end(common.mustCall()); } { // Verify end() callback after write() callback var _tw10 = new TestWriter(); var writeCalledback = false; _tw10.write(bufferShim.from('hello world'), function () { writeCalledback = true; }); _tw10.end(common.mustCall(function () { assert.strictEqual(writeCalledback, true); })); } { // Verify encoding is ignored for buffers var _tw11 = new W(); var hex = '018b5e9a8f6236ffe30e31baf80d2cf6eb'; _tw11._write = common.mustCall(function (chunk) { assert.strictEqual(chunk.toString('hex'), hex); }); var buf = bufferShim.from(hex, 'hex'); _tw11.write(buf, 'latin1'); } { // Verify writables cannot be piped var w = new W(); w._write = common.mustNotCall(); var gotError = false; w.on('error', function () { gotError = true; }); w.pipe(process.stdout); assert.strictEqual(gotError, true); } { // Verify that duplex streams cannot be piped var d = new D(); d._read = common.mustCall(); d._write = common.mustNotCall(); var _gotError = false; d.on('error', function () { _gotError = true; }); d.pipe(process.stdout); assert.strictEqual(_gotError, false); } { // Verify that end(chunk) twice is an error var _w = new W(); _w._write = common.mustCall(function (msg) { assert.strictEqual(msg.toString(), 'this is the end'); }); var _gotError2 = false; _w.on('error', function (er) { _gotError2 = true; assert.strictEqual(er.message, 'write after end'); }); _w.end('this is the end'); _w.end('and so is this'); process.nextTick(common.mustCall(function () { assert.strictEqual(_gotError2, true); })); } { // Verify stream doesn't end while writing var _w2 = new W(); var wrote = false; _w2._write = function (chunk, e, cb) { assert.strictEqual(this.writing, undefined); wrote = true; this.writing = true; setTimeout(function () { this.writing = false; cb(); }, 1); }; _w2.on('finish', common.mustCall(function () { assert.strictEqual(wrote, true); })); _w2.write(bufferShim.alloc(0)); _w2.end(); } { // Verify finish does not come before write() callback var _w3 = new W(); var writeCb = false; _w3._write = function (chunk, e, cb) { setTimeout(function () { writeCb = true; cb(); }, 10); }; _w3.on('finish', common.mustCall(function () { assert.strictEqual(writeCb, true); })); _w3.write(bufferShim.alloc(0)); _w3.end(); } { // Verify finish does not come before synchronous _write() callback var _w4 = new W(); var _writeCb = false; _w4._write = function (chunk, e, cb) { cb(); }; _w4.on('finish', common.mustCall(function () { assert.strictEqual(_writeCb, true); })); _w4.write(bufferShim.alloc(0), function () { _writeCb = true; }); _w4.end(); } { // Verify finish is emitted if the last chunk is empty var _w5 = new W(); _w5._write = function (chunk, e, cb) { process.nextTick(cb); }; _w5.on('finish', common.mustCall()); _w5.write(bufferShim.allocUnsafe(1)); _w5.end(bufferShim.alloc(0)); } { // Verify that finish is emitted after shutdown var _w6 = new W(); var shutdown = false; _w6._final = common.mustCall(function (cb) { assert.strictEqual(this, _w6); setTimeout(function () { shutdown = true; cb(); }, 100); }); _w6._write = function (chunk, e, cb) { process.nextTick(cb); }; _w6.on('finish', common.mustCall(function () { assert.strictEqual(shutdown, true); })); _w6.write(bufferShim.allocUnsafe(1)); _w6.end(bufferShim.allocUnsafe(0)); } function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } }readable-stream-2.3.3/test/parallel/test-stream3-cork-end.js000066400000000000000000000043601312520600100237040ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var assert = require('assert/'); var stream = require('../../'); var Writable = stream.Writable; // Test the buffering behaviour of Writable streams. // // The call to cork() triggers storing chunks which are flushed // on calling end() and the stream subsequently ended. // // node version target: 0.12 var expectedChunks = ['please', 'buffer', 'me', 'kindly']; var inputChunks = expectedChunks.slice(0); var seenChunks = []; var seenEnd = false; var w = new Writable(); // lets arrange to store the chunks w._write = function (chunk, encoding, cb) { // stream end event is not seen before the last write assert.ok(!seenEnd); // default encoding given none was specified assert.strictEqual(encoding, 'buffer'); seenChunks.push(chunk); cb(); }; // lets record the stream end event w.on('finish', function () { seenEnd = true; }); function writeChunks(remainingChunks, callback) { var writeChunk = remainingChunks.shift(); var writeState = void 0; if (writeChunk) { setImmediate(function () { writeState = w.write(writeChunk); // we were not told to stop writing assert.ok(writeState); writeChunks(remainingChunks, callback); }); } else { callback(); } } // do an initial write w.write('stuff'); // the write was immediate assert.strictEqual(seenChunks.length, 1); // reset the seen chunks seenChunks = []; // trigger stream buffering w.cork(); // write the bufferedChunks writeChunks(inputChunks, function () { // should not have seen anything yet assert.strictEqual(seenChunks.length, 0); // trigger flush and ending the stream w.end(); // stream should not ended in current tick assert.ok(!seenEnd); // buffered bytes should be seen in current tick assert.strictEqual(seenChunks.length, 4); // did the chunks match for (var i = 0, l = expectedChunks.length; i < l; i++) { var seen = seenChunks[i]; // there was a chunk assert.ok(seen); var expected = bufferShim.from(expectedChunks[i]); // it was what we expected assert.deepEqual(seen, expected); } setImmediate(function () { // stream should have ended in next tick assert.ok(seenEnd); }); });readable-stream-2.3.3/test/parallel/test-stream3-cork-uncork.js000066400000000000000000000041231312520600100244340ustar00rootroot00000000000000/**/ var bufferShim = require('safe-buffer').Buffer; /**/ require('../common'); var assert = require('assert/'); var stream = require('../../'); var Writable = stream.Writable; // Test the buffering behaviour of Writable streams. // // The call to cork() triggers storing chunks which are flushed // on calling uncork() in the same tick. // // node version target: 0.12 var expectedChunks = ['please', 'buffer', 'me', 'kindly']; var inputChunks = expectedChunks.slice(0); var seenChunks = []; var seenEnd = false; var w = new Writable(); // lets arrange to store the chunks w._write = function (chunk, encoding, cb) { // default encoding given none was specified assert.strictEqual(encoding, 'buffer'); seenChunks.push(chunk); cb(); }; // lets record the stream end event w.on('finish', function () { seenEnd = true; }); function writeChunks(remainingChunks, callback) { var writeChunk = remainingChunks.shift(); var writeState = void 0; if (writeChunk) { setImmediate(function () { writeState = w.write(writeChunk); // we were not told to stop writing assert.ok(writeState); writeChunks(remainingChunks, callback); }); } else { callback(); } } // do an initial write w.write('stuff'); // the write was immediate assert.strictEqual(seenChunks.length, 1); // reset the chunks seen so far seenChunks = []; // trigger stream buffering w.cork(); // write the bufferedChunks writeChunks(inputChunks, function () { // should not have seen anything yet assert.strictEqual(seenChunks.length, 0); // trigger writing out the buffer w.uncork(); // buffered bytes shoud be seen in current tick assert.strictEqual(seenChunks.length, 4); // did the chunks match for (var i = 0, l = expectedChunks.length; i < l; i++) { var seen = seenChunks[i]; // there was a chunk assert.ok(seen); var expected = bufferShim.from(expectedChunks[i]); // it was what we expected assert.deepEqual(seen, expected); } setImmediate(function () { // the stream should not have been ended assert.ok(!seenEnd); }); });readable-stream-2.3.3/test/parallel/test-stream3-pause-then-read.js000066400000000000000000000102641312520600100251640ustar00rootroot00000000000000// 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 assert = require('assert/'); var stream = require('../../'); var Readable = stream.Readable; var Writable = stream.Writable; var totalChunks = 100; var chunkSize = 99; var expectTotalData = totalChunks * chunkSize; var expectEndingData = expectTotalData; var r = new Readable({ highWaterMark: 1000 }); var chunks = totalChunks; r._read = function (n) { if (!(chunks % 2)) setImmediate(push);else if (!(chunks % 3)) process.nextTick(push);else push(); }; var totalPushed = 0; function push() { var chunk = chunks-- > 0 ? bufferShim.alloc(chunkSize, 'x') : null; if (chunk) { totalPushed += chunk.length; } r.push(chunk); } read100(); // first we read 100 bytes function read100() { readn(100, onData); } function readn(n, then) { console.error('read %d', n); expectEndingData -= n; (function read() { var c = r.read(n); if (!c) r.once('readable', read);else { assert.strictEqual(c.length, n); assert(!r._readableState.flowing); then(); } })(); } // then we listen to some data events function onData() { expectEndingData -= 100; console.error('onData'); var seen = 0; r.on('data', function od(c) { seen += c.length; if (seen >= 100) { // seen enough r.removeListener('data', od); r.pause(); if (seen > 100) { // oh no, seen too much! // put the extra back. var diff = seen - 100; r.unshift(c.slice(c.length - diff)); console.error('seen too much', seen, diff); } // Nothing should be lost in between setImmediate(pipeLittle); } }); } // Just pipe 200 bytes, then unshift the extra and unpipe function pipeLittle() { expectEndingData -= 200; console.error('pipe a little'); var w = new Writable(); var written = 0; w.on('finish', function () { assert.strictEqual(written, 200); setImmediate(read1234); }); w._write = function (chunk, encoding, cb) { written += chunk.length; if (written >= 200) { r.unpipe(w); w.end(); cb(); if (written > 200) { var diff = written - 200; written -= diff; r.unshift(chunk.slice(chunk.length - diff)); } } else { setImmediate(cb); } }; r.pipe(w); } // now read 1234 more bytes function read1234() { readn(1234, resumePause); } function resumePause() { console.error('resumePause'); // don't read anything, just resume and re-pause a whole bunch r.resume(); r.pause(); r.resume(); r.pause(); r.resume(); r.pause(); r.resume(); r.pause(); r.resume(); r.pause(); setImmediate(pipe); } function pipe() { console.error('pipe the rest'); var w = new Writable(); var written = 0; w._write = function (chunk, encoding, cb) { written += chunk.length; cb(); }; w.on('finish', function () { console.error('written', written, totalPushed); assert.strictEqual(written, expectEndingData); assert.strictEqual(totalPushed, expectTotalData); console.log('ok'); }); r.pipe(w); }readable-stream-2.3.3/test/parallel/test-streams-highwatermark.js000066400000000000000000000013041312520600100251320ustar00rootroot00000000000000/**/ 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);readable-stream-2.3.3/test/verify-dependencies.js000066400000000000000000000004721312520600100220050ustar00rootroot00000000000000'use strict' var pack = require('../package.json'); var assert = require('assert'); function verifyNoCaret(deps) { var keys = Object.keys(deps); for (var i = 0; i < keys.length; i++) { assert(deps[keys[i]][0] !== '^', keys[i] + ' must not be depended on using ^') } } verifyNoCaret(pack.dependencies) readable-stream-2.3.3/transform.js000066400000000000000000000000611312520600100171030ustar00rootroot00000000000000module.exports = require('./readable').Transform readable-stream-2.3.3/writable-browser.js000066400000000000000000000000671312520600100203700ustar00rootroot00000000000000module.exports = require('./lib/_stream_writable.js'); readable-stream-2.3.3/writable.js000066400000000000000000000003451312520600100167060ustar00rootroot00000000000000var Stream = require("stream") var Writable = require("./lib/_stream_writable.js") if (process.env.READABLE_STREAM === 'disable') { module.exports = Stream && Stream.Writable || Writable } else { module.exports = Writable }