From d260cd789687dda933622380a8ee08cf3db11441 Mon Sep 17 00:00:00 2001 From: bcharpentier Date: Fri, 19 Aug 2016 14:18:40 +0200 Subject: [PATCH 1/3] Manage multiple folders --- lib/phases/initializers.js | 59 ++++++++++--- .../test-multiple-folders/04_log.js | 3 + .../test-multiple-folders/README.md | 1 + test/phases/initializers.test.js | 87 +++++++++++++++---- 4 files changed, 118 insertions(+), 32 deletions(-) create mode 100644 test/data/initializers/test-multiple-folders/04_log.js create mode 100644 test/data/initializers/test-multiple-folders/README.md diff --git a/lib/phases/initializers.js b/lib/phases/initializers.js index 8c35e21..9800a1d 100644 --- a/lib/phases/initializers.js +++ b/lib/phases/initializers.js @@ -28,33 +28,66 @@ module.exports = function(options) { if ('string' == typeof options) { options = { dirname: options }; } + options = options || {}; - var dirname = options.dirname || 'etc/init' + var dirnames = [] , extensions = options.extensions || Object.keys(require.extensions).map(function(ext) { return ext; }) , exts = extensions.map(function(ext) { if ('.' != ext[0]) { return ext; } return ext.slice(1); }) , regex = new RegExp('\\.(' + exts.join('|') + ')$'); - + + if (Array.isArray(options.dirname)) { + dirnames = options.dirname; + } + else{ + dirnames.push(options.dirname || '/etc/init/'); + } + return function initializers(done) { - var dir = path.resolve(dirname); - if (!existsSync(dir)) { return done(); } - - var self = this - , files = fs.readdirSync(dir).sort() - , idx = 0; + + var dirs = [], + files = [], + self = this, + idx = 0; + + dirs = dirnames.filter(function(dirname){ + var folder = path.resolve(dirname); + if (!existsSync(folder)) { + return false; + } + return true; + }).map(function(dirname){ + return path.resolve(dirname);; + }); + + //Sanity check + if (dirs.length !== dirnames.length) { + return done(new Error('One or more directory does not exist')); + } + + files = dirs.map(function(dir){ + return fs.readdirSync(dir).map(function(file){ + return {filename:file, filePath:path.join(dir, file)} + }); + }); + + //Flatten and sort array of array to one level array. + files = [].concat.apply([], files).sort(); + function next(err) { if (err) { return done(err); } - + var file = files[idx++]; // all done if (!file) { return done(); } - - if (regex.test(file)) { + + if (regex.test(file.filename)) { try { - debug('initializer %s', file); - var mod = require(path.join(dir, file)); + + var mod = require(file.filePath); + if (typeof mod == 'function') { var arity = mod.length; if (arity == 1) { diff --git a/test/data/initializers/test-multiple-folders/04_log.js b/test/data/initializers/test-multiple-folders/04_log.js new file mode 100644 index 0000000..dcdda1e --- /dev/null +++ b/test/data/initializers/test-multiple-folders/04_log.js @@ -0,0 +1,3 @@ +module.exports = function() { + this.order.push('04_log'); +}; diff --git a/test/data/initializers/test-multiple-folders/README.md b/test/data/initializers/test-multiple-folders/README.md new file mode 100644 index 0000000..991efa9 --- /dev/null +++ b/test/data/initializers/test-multiple-folders/README.md @@ -0,0 +1 @@ +# Initializers diff --git a/test/phases/initializers.test.js b/test/phases/initializers.test.js index 6ad43f2..8d3ebc4 100644 --- a/test/phases/initializers.test.js +++ b/test/phases/initializers.test.js @@ -3,20 +3,20 @@ var initializers = require('../../lib/phases/initializers'); describe('phases/initializers', function() { - + it('should export a setup function', function() { expect(initializers).to.be.a('function'); }); - + describe('phase with string argument', function() { var app = new Object(); app.order = []; - + var error; - + before(function(done) { global.__app = app; - + var phase = initializers(__dirname + '/../data/initializers/test'); phase.call(app, function(err) { error = err; @@ -24,7 +24,7 @@ describe('phases/initializers', function() { return done(); }); }); - + it('should call callback', function() { expect(error).to.be.undefined; }); @@ -35,13 +35,13 @@ describe('phases/initializers', function() { expect(app.order[2]).to.equal('03_require'); }); }); - + describe('phase with dirname option', function() { var app = new Object(); app.order = []; - + var error; - + before(function(done) { var phase = initializers({ dirname: __dirname + '/../data/initializers/test' }); phase.call(app, function(err) { @@ -49,23 +49,72 @@ describe('phases/initializers', function() { return done(); }); }); - + it('should call callback', function() { expect(error).to.be.undefined; }); + it('should run initializers in correct order', function() { expect(app.order).to.have.length(2); expect(app.order[0]).to.equal('01_async'); expect(app.order[1]).to.equal('02_sync'); }); }); - + + describe('phase with multiple dirname options', function(){ + var app = new Object(); + app.order = []; + + var error; + + before(function(done) { + var phase = initializers({ dirname: [__dirname + '/../data/initializers/test', __dirname + '/../data/initializers/test-multiple-folders'] }); + phase.call(app, function(err) { + error = err; + return done(); + }); + }); + + it('should call callback', function() { + expect(error).to.be.undefined; + }); + + it('should run initializers in correct order', function() { + expect(app.order).to.have.length(3); + expect(app.order[0]).to.equal('01_async'); + expect(app.order[1]).to.equal('02_sync'); + expect(app.order[2]).to.equal('04_log'); + }); + + describe('error in path, should not be imported', function(){ + var app = new Object(); + app.order = []; + + var error; + + before(function(done) { + var phase = initializers({ dirname: [__dirname + '/../data/initializers/test', __dirname + '/../data/initializers/test-multiple-foldssers'] }); + phase.call(app, function(err) { + error = err; + return done(); + }); + }); + + it('should call callback', function() { + expect(error).to.be.an.instanceOf(Error); + expect(error.message).to.equal('One or more directory does not exist'); + }); + + }); + + }); + describe('phase with initializer that calls done with error', function() { var app = new Object(); app.order = []; - + var error; - + before(function(done) { var phase = initializers(__dirname + '/../data/initializers/error-done'); phase.call(app, function(err) { @@ -73,7 +122,7 @@ describe('phases/initializers', function() { return done(); }); }); - + it('should call callback', function() { expect(error).to.be.an.instanceOf(Error); expect(error.message).to.equal('something went wrong'); @@ -82,13 +131,13 @@ describe('phases/initializers', function() { expect(app.order).to.have.length(0); }); }); - + describe('phase with initializer that throws exception', function() { var app = new Object(); app.order = []; - + var error; - + before(function(done) { var phase = initializers(__dirname + '/../data/initializers/error-throw'); phase.call(app, function(err) { @@ -96,7 +145,7 @@ describe('phases/initializers', function() { return done(); }); }); - + it('should call callback', function() { expect(error).to.be.an.instanceOf(Error); expect(error.message).to.equal('something went horribly wrong'); @@ -105,5 +154,5 @@ describe('phases/initializers', function() { expect(app.order).to.have.length(0); }); }); - + }); From 2a7fd97970125d0e59284dc30f34e85809121061 Mon Sep 17 00:00:00 2001 From: bcharpentier Date: Fri, 19 Aug 2016 14:35:46 +0200 Subject: [PATCH 2/3] Pass array as single argument --- lib/phases/initializers.js | 4 ++++ test/phases/initializers.test.js | 28 +++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/phases/initializers.js b/lib/phases/initializers.js index 9800a1d..64faeac 100644 --- a/lib/phases/initializers.js +++ b/lib/phases/initializers.js @@ -29,6 +29,10 @@ module.exports = function(options) { options = { dirname: options }; } + if (Array.isArray(options)) { + options = {dirname: options}; + } + options = options || {}; var dirnames = [] , extensions = options.extensions || Object.keys(require.extensions).map(function(ext) { return ext; }) diff --git a/test/phases/initializers.test.js b/test/phases/initializers.test.js index 8d3ebc4..fa1e3e4 100644 --- a/test/phases/initializers.test.js +++ b/test/phases/initializers.test.js @@ -36,6 +36,33 @@ describe('phases/initializers', function() { }); }); + describe('phase with Array argument', function() { + var app = new Object(); + app.order = []; + + var error; + + before(function(done) { + + var phase = initializers([__dirname + '/../data/initializers/test', __dirname + '/../data/initializers/test-multiple-folders']); + phase.call(app, function(err) { + error = err; + return done(); + }); + }); + + it('should call callback', function() { + expect(error).to.be.undefined; + }); + + it('should run initializers in correct order', function() { + expect(app.order).to.have.length(3); + expect(app.order[0]).to.equal('01_async'); + expect(app.order[1]).to.equal('02_sync'); + expect(app.order[2]).to.equal('04_log'); + }); + }); + describe('phase with dirname option', function() { var app = new Object(); app.order = []; @@ -106,7 +133,6 @@ describe('phases/initializers', function() { }); }); - }); describe('phase with initializer that calls done with error', function() { From 298c94167a03496d1d81dc11ed173f83c6afe7b5 Mon Sep 17 00:00:00 2001 From: bcharpentier Date: Fri, 19 Aug 2016 15:06:11 +0200 Subject: [PATCH 3/3] Modify test to trigger failure on unordored folder --- lib/phases/initializers.js | 11 ++++++++++- test/phases/initializers.test.js | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/phases/initializers.js b/lib/phases/initializers.js index 64faeac..d04857f 100644 --- a/lib/phases/initializers.js +++ b/lib/phases/initializers.js @@ -78,7 +78,16 @@ module.exports = function(options) { }); //Flatten and sort array of array to one level array. - files = [].concat.apply([], files).sort(); + files = [].concat.apply([], files).sort(function(a, b){ + if (a.filename < b.filename) { + return -1; + } + if (a.filename > b.filename) { + return 1; + } + + return 0; + }); function next(err) { if (err) { return done(err); } diff --git a/test/phases/initializers.test.js b/test/phases/initializers.test.js index fa1e3e4..17b8eaa 100644 --- a/test/phases/initializers.test.js +++ b/test/phases/initializers.test.js @@ -44,7 +44,7 @@ describe('phases/initializers', function() { before(function(done) { - var phase = initializers([__dirname + '/../data/initializers/test', __dirname + '/../data/initializers/test-multiple-folders']); + var phase = initializers([__dirname + '/../data/initializers/test-multiple-folders', __dirname + '/../data/initializers/test']); phase.call(app, function(err) { error = err; return done();