aboutsummaryrefslogtreecommitdiff
path: root/node_modules/cloneable-readable/test.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/cloneable-readable/test.js')
-rw-r--r--node_modules/cloneable-readable/test.js576
1 files changed, 576 insertions, 0 deletions
diff --git a/node_modules/cloneable-readable/test.js b/node_modules/cloneable-readable/test.js
new file mode 100644
index 000000000..e1d88d4d9
--- /dev/null
+++ b/node_modules/cloneable-readable/test.js
@@ -0,0 +1,576 @@
+'use strict'
+
+var test = require('tape').test
+var from = require('from2')
+var sink = require('flush-write-stream')
+var cloneable = require('./')
+
+test('basic passthrough', function (t) {
+ t.plan(2)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello world')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ t.notOk(read, 'stream not started')
+
+ instance.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ cb()
+ }))
+})
+
+test('clone sync', function (t) {
+ t.plan(4)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello world')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ t.notOk(read, 'stream not started')
+
+ var cloned = instance.clone()
+ t.notOk(read, 'stream not started')
+
+ instance.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ cb()
+ }))
+
+ cloned.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ cb()
+ }))
+})
+
+test('clone async', function (t) {
+ t.plan(4)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello world')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ t.notOk(read, 'stream not started')
+
+ var cloned = instance.clone()
+ t.notOk(read, 'stream not started')
+
+ instance.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ cb()
+ }))
+
+ setImmediate(function () {
+ cloned.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ cb()
+ }))
+ })
+})
+
+test('basic passthrough in obj mode', function (t) {
+ t.plan(2)
+
+ var read = false
+ var source = from.obj(function (size, next) {
+ if (read) {
+ return this.push(null)
+ } else {
+ read = true
+ this.push({ hello: 'world' })
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ t.notOk(read, 'stream not started')
+
+ instance.pipe(sink.obj(function (chunk, enc, cb) {
+ t.deepEqual(chunk, { hello: 'world' }, 'chunk matches')
+ cb()
+ }))
+})
+
+test('multiple clone in object mode', function (t) {
+ t.plan(4)
+
+ var read = false
+ var source = from.obj(function (size, next) {
+ if (read) {
+ return this.push(null)
+ } else {
+ read = true
+ this.push({ hello: 'world' })
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ t.notOk(read, 'stream not started')
+
+ var cloned = instance.clone()
+ t.notOk(read, 'stream not started')
+
+ instance.pipe(sink.obj(function (chunk, enc, cb) {
+ t.deepEqual(chunk, { hello: 'world' }, 'chunk matches')
+ cb()
+ }))
+
+ setImmediate(function () {
+ cloned.pipe(sink.obj(function (chunk, enc, cb) {
+ t.deepEqual(chunk, { hello: 'world' }, 'chunk matches')
+ cb()
+ }))
+ })
+})
+
+test('basic passthrough with data event', function (t) {
+ t.plan(2)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello world')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ t.notOk(read, 'stream not started')
+
+ var data = ''
+ instance.on('data', function (chunk) {
+ data += chunk.toString()
+ })
+
+ instance.on('end', function () {
+ t.equal(data, 'hello world', 'chunk matches')
+ })
+})
+
+test('basic passthrough with data event on clone', function (t) {
+ t.plan(3)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello world')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ var cloned = instance.clone()
+
+ t.notOk(read, 'stream not started')
+
+ var data = ''
+ cloned.on('data', function (chunk) {
+ data += chunk.toString()
+ })
+
+ cloned.on('end', function () {
+ t.equal(data, 'hello world', 'chunk matches in clone')
+ })
+
+ instance.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches in instance')
+ cb()
+ }))
+})
+
+test('errors if cloned after start', function (t) {
+ t.plan(2)
+
+ var source = from(function (size, next) {
+ this.push('hello world')
+ this.push(null)
+ next()
+ })
+
+ var instance = cloneable(source)
+
+ instance.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ t.throws(function () {
+ instance.clone()
+ }, 'throws if cloned after start')
+ cb()
+ }))
+})
+
+test('basic passthrough with readable event', function (t) {
+ t.plan(2)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello world')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ t.notOk(read, 'stream not started')
+
+ var data = ''
+ instance.on('readable', function () {
+ var chunk
+ while ((chunk = this.read()) !== null) {
+ data += chunk.toString()
+ }
+ })
+
+ instance.on('end', function () {
+ t.equal(data, 'hello world', 'chunk matches')
+ })
+})
+
+test('basic passthrough with readable event on clone', function (t) {
+ t.plan(3)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello world')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ var cloned = instance.clone()
+
+ t.notOk(read, 'stream not started')
+
+ var data = ''
+ cloned.on('readable', function () {
+ var chunk
+ while ((chunk = this.read()) !== null) {
+ data += chunk.toString()
+ }
+ })
+
+ cloned.on('end', function () {
+ t.equal(data, 'hello world', 'chunk matches in clone')
+ })
+
+ instance.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches in instance')
+ cb()
+ }))
+})
+
+test('source error destroys all', function (t) {
+ t.plan(5)
+
+ var source = from()
+ var instance = cloneable(source)
+ var clone = instance.clone()
+
+ source.on('error', function (err) {
+ t.ok(err, 'source errors')
+
+ instance.on('error', function (err2) {
+ t.ok(err === err2, 'instance receives same error')
+ })
+
+ instance.on('close', function () {
+ t.pass('instance is closed')
+ })
+
+ clone.on('error', function (err3) {
+ t.ok(err === err3, 'clone receives same error')
+ })
+
+ clone.on('close', function () {
+ t.pass('clone is closed')
+ })
+ })
+
+ source.emit('error', new Error())
+})
+
+test('source destroy destroys all', function (t) {
+ t.plan(2)
+
+ var source = from()
+ var instance = cloneable(source)
+ var clone = instance.clone()
+
+ instance.on('close', function () {
+ t.pass('instance is closed')
+ })
+
+ clone.on('close', function () {
+ t.pass('clone is closed')
+ })
+
+ source.destroy()
+})
+
+test('instance error destroys all but the source', function (t) {
+ t.plan(4)
+
+ var source = from()
+ var instance = cloneable(source)
+ var clone = instance.clone()
+
+ source.on('close', function () {
+ t.fail('source should not be closed')
+ })
+
+ instance.on('error', function (err) {
+ t.is(err.message, 'beep', 'instance errors')
+
+ instance.on('close', function () {
+ t.pass('instance is closed')
+ })
+
+ clone.on('error', function (err3) {
+ t.ok(err === err3, 'clone receives same error')
+ })
+
+ clone.on('close', function () {
+ t.pass('clone is closed')
+ })
+ })
+
+ instance.destroy(new Error('beep'))
+})
+
+test('instance destroy destroys all but the source', function (t) {
+ t.plan(2)
+
+ var source = from()
+ var instance = cloneable(source)
+ var clone = instance.clone()
+
+ source.on('close', function () {
+ t.fail('source should not be closed')
+ })
+
+ instance.on('close', function () {
+ t.pass('instance is closed')
+ })
+
+ clone.on('close', function () {
+ t.pass('clone is closed')
+ })
+
+ instance.destroy()
+})
+
+test('clone destroy does not affect other clones, cloneable or source', function (t) {
+ t.plan(1)
+
+ var source = from()
+ var instance = cloneable(source)
+ var clone = instance.clone()
+ var other = instance.clone()
+
+ source.on('close', function () {
+ t.fail('source should not be closed')
+ })
+
+ instance.on('close', function () {
+ t.fail('instance should not be closed')
+ })
+
+ other.on('close', function () {
+ t.fail('other clone should not be closed')
+ })
+
+ clone.on('close', function () {
+ t.pass('clone is closed')
+ })
+
+ clone.destroy()
+})
+
+test('clone remains readable if other is destroyed', function (t) {
+ t.plan(3)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ var clone = instance.clone()
+ var other = instance.clone()
+
+ instance.pipe(sink.obj(function (chunk, enc, cb) {
+ t.deepEqual(chunk.toString(), 'hello', 'instance chunk matches')
+ cb()
+ }))
+
+ clone.pipe(sink.obj(function (chunk, enc, cb) {
+ t.deepEqual(chunk.toString(), 'hello', 'clone chunk matches')
+ cb()
+ }))
+
+ clone.on('close', function () {
+ t.fail('clone should not be closed')
+ })
+
+ instance.on('close', function () {
+ t.fail('instance should not be closed')
+ })
+
+ other.on('close', function () {
+ t.pass('other is closed')
+ })
+
+ other.destroy()
+})
+
+test('clone of clone', function (t) {
+ t.plan(6)
+
+ var read = false
+ var source = from(function (size, next) {
+ if (read) {
+ this.push(null)
+ } else {
+ read = true
+ this.push('hello world')
+ }
+ next()
+ })
+
+ var instance = cloneable(source)
+ t.notOk(read, 'stream not started')
+
+ var cloned = instance.clone()
+ t.notOk(read, 'stream not started')
+
+ var replica = cloned.clone()
+ t.notOk(read, 'stream not started')
+
+ instance.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ cb()
+ }))
+
+ cloned.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ cb()
+ }))
+
+ replica.pipe(sink(function (chunk, enc, cb) {
+ t.equal(chunk.toString(), 'hello world', 'chunk matches')
+ cb()
+ }))
+})
+
+test('from vinyl', function (t) {
+ t.plan(3)
+
+ var source = from(['wa', 'dup'])
+
+ var instance = cloneable(source)
+ var clone = instance.clone()
+
+ var data = ''
+ var data2 = ''
+ var ends = 2
+
+ function latch () {
+ if (--ends === 0) {
+ t.equal(data, data2)
+ }
+ }
+
+ instance.on('data', function (chunk) {
+ data += chunk.toString()
+ })
+
+ process.nextTick(function () {
+ t.equal('', data, 'nothing was written yet')
+ t.equal('', data2, 'nothing was written yet')
+
+ clone.on('data', function (chunk) {
+ data2 += chunk.toString()
+ })
+ })
+
+ instance.on('end', latch)
+ clone.on('end', latch)
+})
+
+test('waits till all are flowing', function (t) {
+ t.plan(1)
+
+ var source = from(['wa', 'dup'])
+
+ var instance = cloneable(source)
+
+ // we create a clone
+ instance.clone()
+
+ instance.on('data', function (chunk) {
+ t.fail('this should never happen')
+ })
+
+ process.nextTick(function () {
+ t.pass('wait till nextTick')
+ })
+})
+
+test('isCloneable', function (t) {
+ t.plan(4)
+
+ var source = from(['hello', ' ', 'world'])
+ t.notOk(cloneable.isCloneable(source), 'a generic readable is not cloneable')
+
+ var instance = cloneable(source)
+ t.ok(cloneable.isCloneable(instance), 'a cloneable is cloneable')
+
+ var clone = instance.clone()
+ t.ok(cloneable.isCloneable(clone), 'a clone is cloneable')
+
+ var cloneClone = clone.clone()
+ t.ok(cloneable.isCloneable(cloneClone), 'a clone of a clone is cloneable')
+})