Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 59 additions & 13 deletions lib/phases/initializers.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,79 @@ module.exports = function(options) {
if ('string' == typeof options) {
options = { dirname: options };
}

if (Array.isArray(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(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); }

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) {
Expand Down
3 changes: 3 additions & 0 deletions test/data/initializers/test-multiple-folders/04_log.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function() {
this.order.push('04_log');
};
1 change: 1 addition & 0 deletions test/data/initializers/test-multiple-folders/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Initializers
113 changes: 94 additions & 19 deletions test/phases/initializers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@
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;
delete global.__app;
return done();
});
});

it('should call callback', function() {
expect(error).to.be.undefined;
});
Expand All @@ -35,45 +35,120 @@ describe('phases/initializers', function() {
expect(app.order[2]).to.equal('03_require');
});
});


describe('phase with Array argument', function() {
var app = new Object();
app.order = [];

var error;

before(function(done) {

var phase = initializers([__dirname + '/../data/initializers/test-multiple-folders', __dirname + '/../data/initializers/test']);
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 = [];

var error;

before(function(done) {
var phase = initializers({ dirname: __dirname + '/../data/initializers/test' });
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(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) {
error = err;
return done();
});
});

it('should call callback', function() {
expect(error).to.be.an.instanceOf(Error);
expect(error.message).to.equal('something went wrong');
Expand All @@ -82,21 +157,21 @@ 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) {
error = err;
return done();
});
});

it('should call callback', function() {
expect(error).to.be.an.instanceOf(Error);
expect(error.message).to.equal('something went horribly wrong');
Expand All @@ -105,5 +180,5 @@ describe('phases/initializers', function() {
expect(app.order).to.have.length(0);
});
});

});