| @@ -701,8 +701,8 @@ | ||
|
|
||
| var nativeModule = new NativeModule(id); | ||
|
|
||
| nativeModule.cache(); | ||
| nativeModule.compile(); | ||
|
|
||
| return nativeModule.exports; | ||
| }; | ||
| @@ -0,0 +1 @@ | ||
| xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| @@ -0,0 +1,75 @@ | ||
| // 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 common = require('../common'); | ||
| var assert = require('assert'); | ||
| var fs = require('fs'); | ||
|
|
||
| function check(async, sync) { | ||
| var expected = /Path must be a string without null bytes./; | ||
| var argsSync = Array.prototype.slice.call(arguments, 2); | ||
| var argsAsync = argsSync.concat(function(er) { | ||
| assert(er && er.message.match(expected)); | ||
| }); | ||
|
|
||
| if (sync) | ||
| assert.throws(function() { | ||
| console.error(sync.name, argsSync); | ||
| sync.apply(null, argsSync); | ||
| }, expected); | ||
|
|
||
| if (async) | ||
| async.apply(null, argsAsync); | ||
| } | ||
|
|
||
| check(fs.appendFile, fs.appendFileSync, 'foo\u0000bar'); | ||
| check(fs.chmod, fs.chmodSync, 'foo\u0000bar', '0644'); | ||
| check(fs.chown, fs.chownSync, 'foo\u0000bar', 12, 34); | ||
| check(fs.link, fs.linkSync, 'foo\u0000bar', 'foobar'); | ||
| check(fs.link, fs.linkSync, 'foobar', 'foo\u0000bar'); | ||
| check(fs.lstat, fs.lstatSync, 'foo\u0000bar'); | ||
| check(fs.mkdir, fs.mkdirSync, 'foo\u0000bar', '0755'); | ||
| check(fs.open, fs.openSync, 'foo\u0000bar', 'r'); | ||
| check(fs.readFile, fs.readFileSync, 'foo\u0000bar'); | ||
| check(fs.readdir, fs.readdirSync, 'foo\u0000bar'); | ||
| check(fs.readlink, fs.readlinkSync, 'foo\u0000bar'); | ||
| check(fs.realpath, fs.realpathSync, 'foo\u0000bar'); | ||
| check(fs.rename, fs.renameSync, 'foo\u0000bar', 'foobar'); | ||
| check(fs.rename, fs.renameSync, 'foobar', 'foo\u0000bar'); | ||
| check(fs.rmdir, fs.rmdirSync, 'foo\u0000bar'); | ||
| check(fs.stat, fs.statSync, 'foo\u0000bar'); | ||
| check(fs.symlink, fs.symlinkSync, 'foo\u0000bar', 'foobar'); | ||
| check(fs.symlink, fs.symlinkSync, 'foobar', 'foo\u0000bar'); | ||
| check(fs.truncate, fs.truncateSync, 'foo\u0000bar'); | ||
| check(fs.unlink, fs.unlinkSync, 'foo\u0000bar'); | ||
| check(null, fs.unwatchFile, 'foo\u0000bar', assert.fail); | ||
| check(fs.utimes, fs.utimesSync, 'foo\u0000bar', 0, 0); | ||
| check(null, fs.watch, 'foo\u0000bar', assert.fail); | ||
| check(null, fs.watchFile, 'foo\u0000bar', assert.fail); | ||
| check(fs.writeFile, fs.writeFileSync, 'foo\u0000bar'); | ||
|
|
||
| // an 'error' for exists means that it doesn't exist. | ||
| // one of many reasons why this file is the absolute worst. | ||
| fs.exists('foo\u0000bar', function(exists) { | ||
| assert(!exists); | ||
| }); | ||
| assert(!fs.existsSync('foo\u0000bar')); | ||
|
|
| @@ -0,0 +1,64 @@ | ||
| // 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 common = require('../common'), | ||
| assert = require('assert'), | ||
| http = require('http'); | ||
|
|
||
| var testIndex = 0, | ||
| responses = 0; | ||
|
|
||
| var server = http.createServer(function(req, res) { | ||
| switch (testIndex++) { | ||
| case 0: | ||
| res.writeHead(200, { test: 'foo \r\ninvalid: bar' }); | ||
| break; | ||
| case 1: | ||
| res.writeHead(200, { test: 'foo \ninvalid: bar' }); | ||
| break; | ||
| case 2: | ||
| res.writeHead(200, { test: 'foo \rinvalid: bar' }); | ||
| break; | ||
| case 3: | ||
| res.writeHead(200, { test: 'foo \n\n\ninvalid: bar' }); | ||
| break; | ||
| case 4: | ||
| res.writeHead(200, { test: 'foo \r\n \r\n \r\ninvalid: bar' }); | ||
| server.close(); | ||
| break; | ||
| default: | ||
| assert(false); | ||
| } | ||
| res.end('Hi mars!'); | ||
| }); | ||
| server.listen(common.PORT); | ||
|
|
||
| for (var i = 0; i < 5; i++) { | ||
| var req = http.get({ port: common.PORT, path: '/' }, function(res) { | ||
| assert.strictEqual(res.headers.test, 'foo invalid: bar'); | ||
| assert.strictEqual(res.headers.invalid, undefined); | ||
| responses++; | ||
| }); | ||
| } | ||
|
|
||
| process.on('exit', function() { | ||
| assert.strictEqual(responses, 5); | ||
| }); |
| @@ -0,0 +1,320 @@ | ||
| // 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 common = require('../common.js'); | ||
| var R = require('_stream_readable'); | ||
| var assert = require('assert'); | ||
|
|
||
| var util = require('util'); | ||
| var EE = require('events').EventEmitter; | ||
|
|
||
| function TestReader(n) { | ||
| R.apply(this); | ||
| this._buffer = new Buffer(n || 100); | ||
| this._buffer.fill('x'); | ||
| this._pos = 0; | ||
| this._bufs = 10; | ||
| } | ||
|
|
||
| util.inherits(TestReader, R); | ||
|
|
||
| TestReader.prototype.read = function(n) { | ||
| var max = this._buffer.length - this._pos; | ||
| n = n || max; | ||
| 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.emit('end'); | ||
| this.ended = true; | ||
| } | ||
| } else { | ||
| this.emit('readable'); | ||
| } | ||
| }.bind(this), 10); | ||
| return null; | ||
| } | ||
|
|
||
| var ret = this._buffer.slice(this._pos, this._pos + toRead); | ||
| this._pos += toRead; | ||
| return 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; | ||
|
|
||
| // flip back and forth between immediate acceptance and not. | ||
| this.flush = !this.flush; | ||
| if (!this.flush) setTimeout(this.emit.bind(this, 'drain'), 10); | ||
| return this.flush; | ||
| }; | ||
|
|
||
| TestWriter.prototype.end = function(c) { | ||
| if (c) this.write(c); | ||
| this.emit('end', this.received); | ||
| }; | ||
|
|
||
| //////// | ||
|
|
||
| // tiny node-tap lookalike. | ||
| var tests = []; | ||
| function test(name, fn) { | ||
| tests.push([name, fn]); | ||
| } | ||
|
|
||
| function run() { | ||
| var next = tests.shift(); | ||
| if (!next) | ||
| return console.error('ok'); | ||
|
|
||
| var name = next[0]; | ||
| var fn = next[1]; | ||
| console.log('# %s', name); | ||
| fn({ | ||
| same: assert.deepEqual, | ||
| equal: assert.equal, | ||
| end: run | ||
| }); | ||
| } | ||
|
|
||
| process.nextTick(run); | ||
|
|
||
|
|
||
| test('a most basic test', function(t) { | ||
| var r = new TestReader(20); | ||
|
|
||
| var reads = []; | ||
| var expect = [ 'x', | ||
| 'xx', | ||
| 'xxx', | ||
| 'xxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxxxxx', | ||
| 'xxxxxxxxx', | ||
| 'xxx', | ||
| 'xxxxxxxxxxxx', | ||
| 'xxxxxxxx', | ||
| 'xxxxxxxxxxxxxxx', | ||
| 'xxxxx', | ||
| 'xxxxxxxxxxxxxxxxxx', | ||
| 'xx', | ||
| 'xxxxxxxxxxxxxxxxxxxx', | ||
| 'xxxxxxxxxxxxxxxxxxxx', | ||
| 'xxxxxxxxxxxxxxxxxxxx', | ||
| 'xxxxxxxxxxxxxxxxxxxx', | ||
| 'xxxxxxxxxxxxxxxxxxxx' ]; | ||
|
|
||
| r.on('end', function() { | ||
| t.same(reads, expect); | ||
| t.end(); | ||
| }); | ||
|
|
||
| var readSize = 1; | ||
| function flow() { | ||
| var res; | ||
| while (null !== (res = r.read(readSize++))) { | ||
| reads.push(res.toString()); | ||
| } | ||
| r.once('readable', flow); | ||
| } | ||
|
|
||
| flow(); | ||
| }); | ||
|
|
||
| test('pipe', function(t) { | ||
| var r = new TestReader(5); | ||
|
|
||
| var expect = [ 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx' ] | ||
|
|
||
| var w = new TestWriter; | ||
| var flush = true; | ||
| w.on('end', function(received) { | ||
| t.same(received, expect); | ||
| t.end(); | ||
| }); | ||
|
|
||
| r.pipe(w); | ||
| }); | ||
|
|
||
|
|
||
|
|
||
| [1,2,3,4,5,6,7,8,9].forEach(function(SPLIT) { | ||
| test('unpipe', function(t) { | ||
| var r = new TestReader(5); | ||
|
|
||
| // unpipe after 3 writes, then write to another stream instead. | ||
| var expect = [ 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx' ]; | ||
| expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; | ||
|
|
||
| var w = [ new TestWriter(), new TestWriter() ]; | ||
|
|
||
| var writes = SPLIT; | ||
| w[0].on('write', function() { | ||
| if (--writes === 0) { | ||
| r.unpipe(); | ||
| t.equal(r._readableState.pipes, null); | ||
| w[0].end(); | ||
| r.pipe(w[1]); | ||
| t.equal(r._readableState.pipes, w[1]); | ||
| } | ||
| }); | ||
|
|
||
| var ended = 0; | ||
|
|
||
| var ended0 = false; | ||
| var ended1 = false; | ||
| w[0].on('end', function(results) { | ||
| t.equal(ended0, false); | ||
| ended0 = true; | ||
| ended++; | ||
| t.same(results, expect[0]); | ||
| }); | ||
|
|
||
| w[1].on('end', function(results) { | ||
| t.equal(ended1, false); | ||
| ended1 = true; | ||
| ended++; | ||
| t.equal(ended, 2); | ||
| t.same(results, expect[1]); | ||
| t.end(); | ||
| }); | ||
|
|
||
| r.pipe(w[0]); | ||
| }); | ||
| }); | ||
|
|
||
|
|
||
| // both writers should get the same exact data. | ||
| test('multipipe', function(t) { | ||
| var r = new TestReader(5); | ||
| var w = [ new TestWriter, new TestWriter ]; | ||
|
|
||
| var expect = [ 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx' ]; | ||
|
|
||
| var c = 2; | ||
| w[0].on('end', function(received) { | ||
| t.same(received, expect, 'first'); | ||
| if (--c === 0) t.end(); | ||
| }); | ||
| w[1].on('end', function(received) { | ||
| t.same(received, expect, 'second'); | ||
| if (--c === 0) t.end(); | ||
| }); | ||
|
|
||
| r.pipe(w[0]); | ||
| r.pipe(w[1]); | ||
| }); | ||
|
|
||
|
|
||
| [1,2,3,4,5,6,7,8,9].forEach(function(SPLIT) { | ||
| test('multi-unpipe', function(t) { | ||
| var r = new TestReader(5); | ||
|
|
||
| // unpipe after 3 writes, then write to another stream instead. | ||
| var expect = [ 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx', | ||
| 'xxxxx' ]; | ||
| expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; | ||
|
|
||
| var w = [ new TestWriter(), new TestWriter(), new TestWriter() ]; | ||
|
|
||
| var writes = SPLIT; | ||
| w[0].on('write', function() { | ||
| if (--writes === 0) { | ||
| r.unpipe(); | ||
| w[0].end(); | ||
| r.pipe(w[1]); | ||
| } | ||
| }); | ||
|
|
||
| var ended = 0; | ||
|
|
||
| w[0].on('end', function(results) { | ||
| ended++; | ||
| t.same(results, expect[0]); | ||
| }); | ||
|
|
||
| w[1].on('end', function(results) { | ||
| ended++; | ||
| t.equal(ended, 2); | ||
| t.same(results, expect[1]); | ||
| t.end(); | ||
| }); | ||
|
|
||
| r.pipe(w[0]); | ||
| r.pipe(w[2]); | ||
| }); | ||
| }); |
| @@ -0,0 +1,76 @@ | ||
| // 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 common = require('../common.js'); | ||
| var R = require('_stream_readable'); | ||
| var assert = require('assert'); | ||
|
|
||
| var fs = require('fs'); | ||
| var FSReadable = fs.ReadStream; | ||
|
|
||
| var path = require('path'); | ||
| var file = path.resolve(common.fixturesDir, 'x1024.txt'); | ||
|
|
||
| var size = fs.statSync(file).size; | ||
|
|
||
| // expect to see chunks no more than 10 bytes each. | ||
| var expectLengths = []; | ||
| for (var i = size; i > 0; i -= 10) { | ||
| expectLengths.push(Math.min(i, 10)); | ||
| } | ||
|
|
||
| var util = require('util'); | ||
| var Stream = require('stream'); | ||
|
|
||
| util.inherits(TestWriter, Stream); | ||
|
|
||
| function TestWriter() { | ||
| Stream.apply(this); | ||
| this.buffer = []; | ||
| this.length = 0; | ||
| } | ||
|
|
||
| TestWriter.prototype.write = function(c) { | ||
| this.buffer.push(c.toString()); | ||
| this.length += c.length; | ||
| return true; | ||
| }; | ||
|
|
||
| TestWriter.prototype.end = function(c) { | ||
| if (c) this.buffer.push(c.toString()); | ||
| this.emit('results', this.buffer); | ||
| } | ||
|
|
||
| var r = new FSReadable(file, { bufferSize: 10 }); | ||
| var w = new TestWriter(); | ||
|
|
||
| w.on('results', function(res) { | ||
| console.error(res, w.length); | ||
| assert.equal(w.length, size); | ||
| var l = 0; | ||
| assert.deepEqual(res.map(function (c) { | ||
| return c.length; | ||
| }), expectLengths); | ||
| console.log('ok'); | ||
| }); | ||
|
|
||
| r.pipe(w, { chunkSize: 10 }); |
| @@ -0,0 +1,105 @@ | ||
| // 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 common = require('../common'); | ||
| var assert = require('assert'); | ||
| var stream = require('stream'); | ||
|
|
||
| (function testErrorListenerCatches() { | ||
| var count = 1000; | ||
|
|
||
| var source = new stream.Readable(); | ||
| source._read = function(n, cb) { | ||
| n = Math.min(count, n); | ||
| count -= n; | ||
| cb(null, 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, 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); | ||
| assert.strictEqual(gotErr, err); | ||
| assert.strictEqual(unpipedSource, source); | ||
| assert.strictEqual(unpipedDest, dest); | ||
| })(); | ||
|
|
||
| (function testErrorWithoutListenerThrows() { | ||
| var count = 1000; | ||
|
|
||
| var source = new stream.Readable(); | ||
| source._read = function(n, cb) { | ||
| n = Math.min(count, n); | ||
| count -= n; | ||
| cb(null, 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, 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; | ||
| } | ||
| assert.strictEqual(gotErr, err); | ||
| assert.strictEqual(unpipedSource, source); | ||
| assert.strictEqual(unpipedDest, dest); | ||
| })(); |
| @@ -0,0 +1,109 @@ | ||
| // 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 assert = require('assert'); | ||
| var common = require('../common.js'); | ||
| var fromList = require('_stream_readable')._fromList; | ||
|
|
||
| // tiny node-tap lookalike. | ||
| var tests = []; | ||
| function test(name, fn) { | ||
| tests.push([name, fn]); | ||
| } | ||
|
|
||
| function run() { | ||
| var next = tests.shift(); | ||
| if (!next) | ||
| return console.error('ok'); | ||
|
|
||
| var name = next[0]; | ||
| var fn = next[1]; | ||
| console.log('# %s', name); | ||
| fn({ | ||
| same: assert.deepEqual, | ||
| equal: assert.equal, | ||
| end: run | ||
| }); | ||
| } | ||
|
|
||
| process.nextTick(run); | ||
|
|
||
|
|
||
|
|
||
| test('buffers', function(t) { | ||
| // have a length | ||
| var len = 16; | ||
| var list = [ new Buffer('foog'), | ||
| new Buffer('bark'), | ||
| new Buffer('bazy'), | ||
| new Buffer('kuel') ]; | ||
|
|
||
| // read more than the first element. | ||
| var ret = fromList(6, list, 16); | ||
| t.equal(ret.toString(), 'foogba'); | ||
|
|
||
| // read exactly the first element. | ||
| ret = fromList(2, list, 10); | ||
| t.equal(ret.toString(), 'rk'); | ||
|
|
||
| // read less than the first element. | ||
| ret = fromList(2, list, 8); | ||
| t.equal(ret.toString(), 'ba'); | ||
|
|
||
| // read more than we have. | ||
| ret = fromList(100, list, 6); | ||
| t.equal(ret.toString(), 'zykuel'); | ||
|
|
||
| // all consumed. | ||
| t.same(list, []); | ||
|
|
||
| t.end(); | ||
| }); | ||
|
|
||
| test('strings', function(t) { | ||
| // have a length | ||
| var len = 16; | ||
| var list = [ 'foog', | ||
| 'bark', | ||
| 'bazy', | ||
| 'kuel' ]; | ||
|
|
||
| // read more than the first element. | ||
| var ret = fromList(6, list, 16, true); | ||
| t.equal(ret, 'foogba'); | ||
|
|
||
| // read exactly the first element. | ||
| ret = fromList(2, list, 10, true); | ||
| t.equal(ret, 'rk'); | ||
|
|
||
| // read less than the first element. | ||
| ret = fromList(2, list, 8, true); | ||
| t.equal(ret, 'ba'); | ||
|
|
||
| // read more than we have. | ||
| ret = fromList(100, list, 6, true); | ||
| t.equal(ret, 'zykuel'); | ||
|
|
||
| // all consumed. | ||
| t.same(list, []); | ||
|
|
||
| t.end(); | ||
| }); |
| @@ -0,0 +1,299 @@ | ||
| // 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 common = require('../common.js'); | ||
| var assert = require('assert'); | ||
| var R = require('_stream_readable'); | ||
| var util = require('util'); | ||
|
|
||
| // tiny node-tap lookalike. | ||
| var tests = []; | ||
| function test(name, fn) { | ||
| tests.push([name, fn]); | ||
| } | ||
|
|
||
| function run() { | ||
| var next = tests.shift(); | ||
| if (!next) | ||
| return console.error('ok'); | ||
|
|
||
| var name = next[0]; | ||
| var fn = next[1]; | ||
| console.log('# %s', name); | ||
| fn({ | ||
| same: assert.deepEqual, | ||
| equal: assert.equal, | ||
| end: run | ||
| }); | ||
| } | ||
|
|
||
| process.nextTick(run); | ||
|
|
||
| ///// | ||
|
|
||
| util.inherits(TestReader, R); | ||
|
|
||
| function TestReader(n, opts) { | ||
| R.call(this, util._extend({ | ||
| bufferSize: 5 | ||
| }, opts)); | ||
|
|
||
| this.pos = 0; | ||
| this.len = n || 100; | ||
| } | ||
|
|
||
| TestReader.prototype._read = function(n, cb) { | ||
| setTimeout(function() { | ||
|
|
||
| if (this.pos >= this.len) { | ||
| return cb(); | ||
| } | ||
|
|
||
| n = Math.min(n, this.len - this.pos); | ||
| if (n <= 0) { | ||
| return cb(); | ||
| } | ||
|
|
||
| this.pos += n; | ||
| var ret = new Buffer(n); | ||
| ret.fill('a'); | ||
|
|
||
| return cb(null, 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(); | ||
| }); | ||
|
|
||
| // just kick it off. | ||
| tr.emit('readable'); | ||
| }); | ||
|
|
||
|
|
||
| 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(); | ||
| }); | ||
|
|
||
| // just kick it off. | ||
| tr.emit('readable'); | ||
| }); | ||
|
|
||
| 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() { | ||
| var chunk; | ||
| while (null !== (chunk = tr.read(13))) | ||
| out.push(chunk); | ||
| }); | ||
|
|
||
| tr.on('end', function() { | ||
| t.same(out, expect); | ||
| t.end(); | ||
| }); | ||
|
|
||
| // just kick it off. | ||
| tr.emit('readable'); | ||
| }); | ||
|
|
||
| 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(); | ||
| }); | ||
|
|
||
| // just kick it off. | ||
| tr.emit('readable'); | ||
| }); | ||
|
|
||
|
|
||
| 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(); | ||
| }); | ||
|
|
||
| // just kick it off. | ||
| tr.emit('readable'); | ||
| }); | ||
|
|
||
| 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(); | ||
| }); | ||
|
|
||
| // just kick it off. | ||
| tr.emit('readable'); | ||
| }); |
| @@ -0,0 +1,314 @@ | ||
| // 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 assert = require('assert'); | ||
| var common = require('../common.js'); | ||
| var PassThrough = require('_stream_passthrough'); | ||
| var Transform = require('_stream_transform'); | ||
|
|
||
| // tiny node-tap lookalike. | ||
| var tests = []; | ||
| function test(name, fn) { | ||
| tests.push([name, fn]); | ||
| } | ||
|
|
||
| function run() { | ||
| var next = tests.shift(); | ||
| if (!next) | ||
| return console.error('ok'); | ||
|
|
||
| var name = next[0]; | ||
| var fn = next[1]; | ||
| console.log('# %s', name); | ||
| fn({ | ||
| same: assert.deepEqual, | ||
| equal: assert.equal, | ||
| end: run | ||
| }); | ||
| } | ||
|
|
||
| process.nextTick(run); | ||
|
|
||
| ///// | ||
|
|
||
| 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(); | ||
| }); | ||
|
|
||
| test('simple transform', function(t) { | ||
| var pt = new Transform; | ||
| pt._transform = function(c, output, cb) { | ||
| var ret = new Buffer(c.length); | ||
| ret.fill('x'); | ||
| output(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(); | ||
| }); | ||
|
|
||
| test('async passthrough', function(t) { | ||
| var pt = new Transform; | ||
| pt._transform = function(chunk, output, cb) { | ||
| setTimeout(function() { | ||
| output(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(); | ||
|
|
||
| setTimeout(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(); | ||
| }, 100); | ||
| }); | ||
|
|
||
| test('assymetric transform (expand)', function(t) { | ||
| var pt = new Transform; | ||
|
|
||
| // emit each chunk 2 times. | ||
| pt._transform = function(chunk, output, cb) { | ||
| setTimeout(function() { | ||
| output(chunk); | ||
| setTimeout(function() { | ||
| output(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(); | ||
|
|
||
| setTimeout(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(); | ||
| }, 200); | ||
| }); | ||
|
|
||
| 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, output, cb) { | ||
| if (!chunk) | ||
| chunk = ''; | ||
| var s = chunk.toString(); | ||
| setTimeout(function() { | ||
| this.state += s.charAt(0); | ||
| if (this.state.length === 3) { | ||
| output(new Buffer(this.state)); | ||
| this.state = ''; | ||
| } | ||
| cb(); | ||
| }.bind(this), 10); | ||
| }; | ||
|
|
||
| pt._flush = function(output, cb) { | ||
| // just output whatever we have. | ||
| setTimeout(function() { | ||
| output(new Buffer(this.state)); | ||
| this.state = ''; | ||
| cb(); | ||
| }.bind(this), 10); | ||
| }; | ||
|
|
||
| pt._writableState.lowWaterMark = 3; | ||
|
|
||
| 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' | ||
| setTimeout(function() { | ||
| t.equal(pt.read(5).toString(), 'abcde'); | ||
| t.equal(pt.read(5).toString(), 'abcde'); | ||
| t.equal(pt.read(5).toString(), 'abcd'); | ||
| t.end(); | ||
| }, 200); | ||
| }); | ||
|
|
||
|
|
||
| test('passthrough event emission', function(t) { | ||
| var pt = new PassThrough({ | ||
| lowWaterMark: 0 | ||
| }); | ||
| 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')); | ||
| pt.write(new Buffer('bark')); | ||
|
|
||
| t.equal(pt.read(5).toString(), 'foogb'); | ||
| t.equal(pt.read(5) + '', 'null'); | ||
|
|
||
| console.error('need emit 0'); | ||
|
|
||
| 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 1 === %d', emits); | ||
| t.equal(emits, 1); | ||
|
|
||
| t.equal(pt.read(5).toString(), 'arkba'); | ||
| t.equal(pt.read(5).toString(), 'zykue'); | ||
| t.equal(pt.read(5), null); | ||
|
|
||
| console.error('need emit 1'); | ||
|
|
||
| pt.end(); | ||
|
|
||
| t.equal(emits, 2); | ||
|
|
||
| t.equal(pt.read(5).toString(), 'l'); | ||
| t.equal(pt.read(5), null); | ||
|
|
||
| console.error('should not have emitted again'); | ||
| t.equal(emits, 2); | ||
| t.end(); | ||
| }); | ||
|
|
||
| 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')); | ||
| pt.write(new Buffer('bark')); | ||
|
|
||
| t.equal(pt.read(5).toString(), 'foogb'); | ||
| t.equal(pt.read(5), null); | ||
|
|
||
| console.error('need emit 0'); | ||
| pt.once('readable', function() { | ||
| t.equal(pt.read(5).toString(), 'arkba'); | ||
|
|
||
| t.equal(pt.read(5), null); | ||
|
|
||
| console.error('need emit 1'); | ||
| 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, 3); | ||
| t.end(); | ||
| }); | ||
| pt.end(); | ||
| }); | ||
| pt.write(new Buffer('kuel')); | ||
| }); | ||
|
|
||
| pt.write(new Buffer('bazy')); | ||
| }); | ||
|
|
||
| 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); | ||
| }); |
| @@ -0,0 +1,246 @@ | ||
| // 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 common = require('../common.js'); | ||
| var W = require('_stream_writable'); | ||
| 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, 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] = new Array(i + 1).join('x'); | ||
| } | ||
|
|
||
| // tiny node-tap lookalike. | ||
| var tests = []; | ||
| function test(name, fn) { | ||
| tests.push([name, fn]); | ||
| } | ||
|
|
||
| function run() { | ||
| var next = tests.shift(); | ||
| if (!next) | ||
| return console.log('ok'); | ||
|
|
||
| var name = next[0]; | ||
| var fn = next[1]; | ||
|
|
||
| if (!fn) | ||
| return run(); | ||
|
|
||
| console.log('# %s', name); | ||
| fn({ | ||
| same: assert.deepEqual, | ||
| equal: assert.equal, | ||
| end: run | ||
| }); | ||
| } | ||
|
|
||
| process.nextTick(run); | ||
|
|
||
| test('write fast', function(t) { | ||
| var tw = new TestWriter({ | ||
| lowWaterMark: 5, | ||
| highWaterMark: 100 | ||
| }); | ||
|
|
||
| tw.on('finish', function() { | ||
| t.same(tw.buffer, chunks, 'got chunks in the right order'); | ||
| t.end(); | ||
| }); | ||
|
|
||
| chunks.forEach(function(chunk) { | ||
| // screw backpressure. Just buffer it all up. | ||
| tw.write(chunk); | ||
| }); | ||
| tw.end(); | ||
| }); | ||
|
|
||
| test('write slow', function(t) { | ||
| var tw = new TestWriter({ | ||
| lowWaterMark: 5, | ||
| 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({ | ||
| lowWaterMark: 5, | ||
| 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) { | ||
| assert(tw._writableState.length >= 50); | ||
| tw.once('drain', W); | ||
| } else { | ||
| tw.end(); | ||
| } | ||
| })(); | ||
| }); | ||
|
|
||
| test('write bufferize', function(t) { | ||
| var tw = new TestWriter({ | ||
| lowWaterMark: 5, | ||
| 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'); | ||
| }); | ||
|
|
||
| chunks.forEach(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({ | ||
| lowWaterMark: 5, | ||
| highWaterMark: 100, | ||
| decodeStrings: false | ||
| }); | ||
|
|
||
| tw._write = function(chunk, cb) { | ||
| assert(Array.isArray(chunk)); | ||
| assert(typeof chunk[0] === 'string'); | ||
| chunk = new Buffer(chunk[0], chunk[1]); | ||
| return TestWriter.prototype._write.call(this, chunk, 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'); | ||
| }); | ||
|
|
||
| chunks.forEach(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({ | ||
| lowWaterMark: 5, | ||
| 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(); | ||
| }); | ||
| }); | ||
|
|
||
| chunks.forEach(function(chunk, i) { | ||
| tw.write(chunk, callbacks['callback-' + i]); | ||
| }); | ||
| tw.end(); | ||
| }); |
| @@ -50,13 +50,6 @@ unzips.forEach(function (uz, i) { | ||
| uz.on('error', function(er) { | ||
| console.error('Error event', er); | ||
| hadError[i] = true; | ||
| }); | ||
|
|
||
| uz.on('end', function(er) { | ||