From 26d3798309dd473b320bdfb1b82f905d3e6b42f1 Mon Sep 17 00:00:00 2001 From: Andres Suarez Date: Mon, 10 Aug 2015 01:07:07 -0400 Subject: [PATCH] fix input stream handling fixes #64 --- index.js | 24 ++++++++++++--- package.json | 1 + test/bin.js | 63 ++++++++++++++++++++++++++++++++++++++ test/source_fake_stream.js | 60 ++++++++++++++++++++++++++++++++++++ test/source_real_stream.js | 63 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 206 insertions(+), 5 deletions(-) create mode 100644 test/bin.js create mode 100644 test/source_fake_stream.js create mode 100644 test/source_real_stream.js diff --git a/index.js b/index.js index 179a967..ee8206c 100644 --- a/index.js +++ b/index.js @@ -11,6 +11,7 @@ var combine = require('stream-combiner2'); var duplexer = require('duplexer2'); var xtend = require('xtend'); var defined = require('defined'); +var isStream = require('is-stream'); var inherits = require('inherits'); var Transform = require('readable-stream').Transform; @@ -36,6 +37,7 @@ function Deps (opts) { this.walking = {}; this.entries = []; this._input = []; + this._inputOrder = 0; this.paths = opts.paths || process.env.NODE_PATH || ''; if (typeof this.paths === 'string') { @@ -71,9 +73,6 @@ function Deps (opts) { Deps.prototype._transform = function (row, enc, next) { var self = this; - if (typeof row === 'string') { - row = { file: row }; - } if (row.transform && row.global) { this.globalTransforms.push([ row.transform, row.options ]); return next(); @@ -84,8 +83,21 @@ Deps.prototype._transform = function (row, enc, next) { } self.pending ++; + self._inputOrder ++; var basedir = defined(row.basedir, self.basedir); + if (typeof row === 'string') { + row = { file: row }; + } + else if (isStream(row)) { + row = { + file: row.file || path.resolve( + basedir, + '_stream_' + self._inputOrder + '.js' + ), + source: row + }; + } if (row.entry !== false) { self.entries.push(path.resolve(basedir, row.file || row.id)); } @@ -336,7 +348,8 @@ Deps.prototype.walk = function (id, parent, cb) { rec.source = body.toString('utf8'); fromSource(file, rec.source, pkg); })); - return ts.end(rec.source); + if (isStream(rec.source)) return rec.source.pipe(ts); + else return ts.end(rec.source); } if (err && self.options.ignoreMissing) { if (--self.pending === 0) self.push(null); @@ -358,7 +371,8 @@ Deps.prototype.walk = function (id, parent, cb) { rec.source = body.toString('utf8'); fromSource(file, rec.source, pkg); })); - return ts.end(rec.source); + if (isStream(rec.source)) return rec.source.pipe(ts); + else return ts.end(rec.source); } var c = self.cache && self.cache[file]; diff --git a/package.json b/package.json index 28e88ff..e22ed16 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "detective": "^4.0.0", "duplexer2": "0.0.2", "inherits": "^2.0.1", + "is-stream": "^1.0.1", "parents": "^1.0.0", "readable-stream": "^1.1.13", "resolve": "^1.1.3", diff --git a/test/bin.js b/test/bin.js new file mode 100644 index 0000000..dca2b1d --- /dev/null +++ b/test/bin.js @@ -0,0 +1,63 @@ +var test = require('tap').test; +var spawn = require('child_process').spawn; +var path = require('path'); +var fs = require('fs'); + +var files = { + main: path.join(__dirname, '/files/main.js'), + foo: path.join(__dirname, '/files/foo.js'), + bar: path.join(__dirname, '/files/bar.js') +}; +var sources = { + main: fs.readFileSync(files.main, 'utf8'), + foo: fs.readFileSync(files.foo, 'utf8'), + bar: fs.readFileSync(files.bar, 'utf8') +}; + +test('bin', function (t) { + t.plan(3); + + var ps = spawn(process.execPath, [ + path.resolve(__dirname, '../bin/cmd.js'), '-', + ], { + cwd: __dirname + '/files' + }); + + var input = fs.createReadStream(files.main); + input.pipe(ps.stdin); + + var src = ''; + var err = ''; + ps.stdout.on('data', function (buf) { src += buf }); + ps.stderr.on('data', function (buf) { err += buf }); + + ps.on('exit', function (code) { + t.equal(code, 0); + t.equal(err, ''); + + var rows = JSON.parse(src); + t.same(rows.sort(cmp), [ + { + id: __dirname + '/files/_stream_1.js', + file: __dirname + '/files/_stream_1.js', + source: sources.main, + entry: true, + deps: { './foo': files.foo } + }, + { + id: files.foo, + file: files.foo, + source: sources.foo, + deps: { './bar': files.bar } + }, + { + id: files.bar, + file: files.bar, + source: sources.bar, + deps: {} + } + ].sort(cmp)); + }); +}); + +function cmp (a, b) { return a.id < b.id ? -1 : 1 } diff --git a/test/source_fake_stream.js b/test/source_fake_stream.js new file mode 100644 index 0000000..ccd1917 --- /dev/null +++ b/test/source_fake_stream.js @@ -0,0 +1,60 @@ +var parser = require('../'); +var test = require('tap').test; +var fs = require('fs'); +var path = require('path'); +var through = require('through2'); + +var files = { + main: path.join(__dirname, '/files/_stream_1.js'), + foo: path.join(__dirname, '/files/foo.js'), + bar: path.join(__dirname, '/files/bar.js'), + extra: path.join(__dirname, '/files/extra.js') +}; +var sources = { + foo: fs.readFileSync(files.foo, 'utf8'), + bar: fs.readFileSync(files.bar, 'utf8'), + extra: fs.readFileSync(files.extra, 'utf8'), + main: "console.log(require('./foo')(5)); require('./extra.js')" +}; + +test('source fake stream', function (t) { + t.plan(1); + var p = parser({ basedir: __dirname + '/files' }); + var s = through(); + p.end(s); + s.end(sources.main); + + var rows = []; + p.on('data', function (row) { rows.push(row) }); + p.on('end', function () { + t.same(rows.sort(cmp), [ + { + id: files.main, + file: files.main, + source: sources.main, + entry: true, + deps: { './foo': files.foo, './extra.js': files.extra } + }, + { + id: files.foo, + file: files.foo, + source: sources.foo, + deps: { './bar': files.bar } + }, + { + id: files.bar, + file: files.bar, + source: sources.bar, + deps: {} + }, + { + id: files.extra, + file: files.extra, + source: sources.extra, + deps: {} + }, + ].sort(cmp)); + }); +}); + +function cmp (a, b) { return a.id < b.id ? -1 : 1 } diff --git a/test/source_real_stream.js b/test/source_real_stream.js new file mode 100644 index 0000000..88fa10b --- /dev/null +++ b/test/source_real_stream.js @@ -0,0 +1,63 @@ +var parser = require('../'); +var test = require('tap').test; +var fs = require('fs'); +var path = require('path'); +var through = require('through2'); + +var files = { + main: path.join(__dirname, '/files/main.js'), + foo: path.join(__dirname, '/files/foo.js'), + bar: path.join(__dirname, '/files/bar.js'), + extra: path.join(__dirname, '/files/extra.js') +}; +var sources = { + foo: fs.readFileSync(files.foo, 'utf8'), + bar: fs.readFileSync(files.bar, 'utf8'), + extra: fs.readFileSync(files.extra, 'utf8'), + main: "console.log(require('./foo')(5)); require('./extra.js')" +}; + +test('source real stream', function (t) { + t.plan(1); + var p = parser(); + var s = through(); + p.end({ + file: files.main, + source: s + }); + s.end(sources.main); + + var rows = []; + p.on('data', function (row) { rows.push(row) }); + p.on('end', function () { + t.same(rows.sort(cmp), [ + { + id: files.main, + file: files.main, + source: sources.main, + entry: true, + deps: { './foo': files.foo, './extra.js': files.extra } + }, + { + id: files.foo, + file: files.foo, + source: sources.foo, + deps: { './bar': files.bar } + }, + { + id: files.bar, + file: files.bar, + source: sources.bar, + deps: {} + }, + { + id: files.extra, + file: files.extra, + source: sources.extra, + deps: {} + }, + ].sort(cmp)); + }); +}); + +function cmp (a, b) { return a.id < b.id ? -1 : 1 }