Skip to content

Commit 5e6d813

Browse files
committed
Breaking: Use cloneable-readable to clone streams (closes #85) (#99)
1 parent 3e3067a commit 5e6d813

File tree

3 files changed

+100
-7
lines changed

3 files changed

+100
-7
lines changed

index.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ var isStream = require('./lib/isStream');
88
var isNull = require('./lib/isNull');
99
var inspectStream = require('./lib/inspectStream');
1010
var normalize = require('./lib/normalize');
11-
var Stream = require('readable-stream');
1211
var replaceExt = require('replace-ext');
12+
var cloneable = require('cloneable-readable');
1313

1414
var builtInFields = [
1515
'_contents', '_symlink', 'contents', 'stat', 'history', 'path',
@@ -111,8 +111,11 @@ File.prototype.clone = function(opt) {
111111
// Clone our file contents
112112
var contents;
113113
if (this.isStream()) {
114-
contents = this.contents.pipe(new Stream.PassThrough());
115-
this.contents = this.contents.pipe(new Stream.PassThrough());
114+
if (typeof this.contents.clone !== 'function') {
115+
this.contents = cloneable(this.contents);
116+
}
117+
118+
contents = this.contents.clone();
116119
} else if (this.isBuffer()) {
117120
contents = opt.contents ? cloneBuffer(this.contents) : this.contents;
118121
}
@@ -173,6 +176,11 @@ Object.defineProperty(File.prototype, 'contents', {
173176
if (!isBuffer(val) && !isStream(val) && !isNull(val)) {
174177
throw new Error('File.contents can only be a Buffer, a Stream, or null.');
175178
}
179+
180+
if (isStream(val)) {
181+
val = cloneable(val);
182+
}
183+
176184
this._contents = val;
177185
},
178186
});

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"dependencies": {
1414
"clone": "^1.0.0",
1515
"clone-stats": "^1.0.0",
16+
"cloneable-readable": "^0.4.0",
1617
"readable-stream": "^2.1.0",
1718
"replace-ext": "^1.0.0"
1819
},

test/File.js

+88-4
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,90 @@ describe('File', function() {
438438
done();
439439
});
440440

441+
it('should not start flowing until all clones flows', function(done) {
442+
var contents = new Stream.PassThrough();
443+
var options = {
444+
cwd: '/',
445+
base: '/test/',
446+
path: '/test/test.coffee',
447+
contents: contents,
448+
};
449+
var file = new File(options);
450+
var file2 = file.clone();
451+
var ends = 2;
452+
453+
function latch() {
454+
if (--ends === 0) {
455+
done();
456+
}
457+
}
458+
459+
contents.write(new Buffer('wa'));
460+
461+
process.nextTick(function() {
462+
contents.write(new Buffer('dup'));
463+
contents.end();
464+
});
465+
466+
// Start flowing file2
467+
file2.contents.on('data', function() {});
468+
469+
file2.contents.once('data', function() {
470+
process.nextTick(function() {
471+
// Starts flowing file
472+
file.contents.on('data', function() {
473+
ends.should.equal(2);
474+
});
475+
});
476+
});
477+
478+
file2.contents.on('end', latch);
479+
file.contents.on('end', latch);
480+
});
481+
482+
it('should not start flowing until all clones flows', function(done) {
483+
var contents = new Stream.PassThrough();
484+
var options = {
485+
cwd: '/',
486+
base: '/test/',
487+
path: '/test/test.coffee',
488+
contents: contents,
489+
};
490+
var file = new File(options);
491+
var file2 = file.clone();
492+
var ends = 2;
493+
494+
function latch() {
495+
if (--ends === 0) {
496+
done();
497+
}
498+
}
499+
500+
contents.write(new Buffer('wa'));
501+
502+
process.nextTick(function() {
503+
contents.write(new Buffer('dup'));
504+
contents.end();
505+
});
506+
507+
// Start flowing file2
508+
file2.contents.on('readable', function() {
509+
this.read();
510+
});
511+
512+
file2.contents.once('readable', function() {
513+
process.nextTick(function() {
514+
// Starts flowing file
515+
file.contents.on('readable', function() {
516+
ends.should.equal(2);
517+
});
518+
});
519+
});
520+
521+
file2.contents.on('end', latch);
522+
file.contents.on('end', latch);
523+
});
524+
441525
it('should copy all attributes over with null', function(done) {
442526
var options = {
443527
cwd: '/',
@@ -636,7 +720,7 @@ describe('File', function() {
636720
path: '/test/test.coffee',
637721
contents: new Stream.PassThrough(),
638722
});
639-
file.inspect().should.equal('<File "test.coffee" <PassThroughStream>>');
723+
file.inspect().should.equal('<File "test.coffee" <CloneableStream>>');
640724
done();
641725
});
642726

@@ -661,11 +745,11 @@ describe('File', function() {
661745
done();
662746
});
663747

664-
it('should work with Stream', function(done) {
665-
var val = new Stream.PassThrough();
748+
it('should wrap Stream in Cloneable', function(done) {
749+
var val = new Stream();
666750
var file = new File();
667751
file.contents = val;
668-
file.contents.should.equal(val);
752+
(typeof file.contents.clone).should.equal('function');
669753
done();
670754
});
671755

0 commit comments

Comments
 (0)