<|start_filename|>test/data/initializers/error-throw/01_throw.js<|end_filename|>
module.exports = function() {
  throw new Error('something went horribly wrong');
};


<|start_filename|>test/mixin.test.js<|end_filename|>
/* global describe, it, before, expect */

var bootable = require('..');

describe('mixin', function() {
    
  it('should export function', function() {
    expect(bootable).to.be.a('function');
  });
  
  describe('mixing into application', function() {
    var app = new Object();
    app.name = 'AppFoo';
    
    bootable(app);
    
    it('should mixin phase function', function() {
      expect(app.phase).to.be.a('function');
    });
    
    it('should mixin boot function', function() {
      expect(app.boot).to.be.a('function');
    });
    
    describe('registering and running phases', function() {
      var order = [];
      
      app.phase(function() {
        var name = this !== global ? this.name : 'global';
        order.push('1:' + name);
      });
      app.phase(function(done) {
        var self = this;
        process.nextTick(function() {
          var name = self !== global ? self.name : 'global';
          order.push('2:' + name);
          return done();
        });
      });
      app.phase(function() {
        var name = this !== global ? this.name : 'global';
        order.push('3:' + name);
      });
      
      
      var error;
    
      before(function(done) {
        app.boot(function(err) {
          error = err;
          return done();
        });
      });
    
      it('should call callback', function() {
        expect(error).to.be.undefined;
      });
      it('should run phases in correct order', function() {
        expect(order).to.have.length(3);
        expect(order[0]).to.equal('1:AppFoo');
        expect(order[1]).to.equal('2:AppFoo');
        expect(order[2]).to.equal('3:AppFoo');
      });
    });
  });
  
  describe('mixing in with phases', function() {
    var app = new Object();
    app.name = 'AppFoo';
    var order = [];
    
    function phase1() {
      var name = this !== global ? this.name : 'global';
      order.push('1:' + name);
    }
    function phase2(done) {
      var self = this;
      process.nextTick(function() {
        var name = self !== global ? self.name : 'global';
        order.push('2:' + name);
        return done();
      });
    }
    function phase3() {
      var name = this !== global ? this.name : 'global';
      order.push('3:' + name);
    }
    
    bootable(app, phase1, phase2, phase3);
    
    describe('running phases', function() {
      var error;
    
      before(function(done) {
        app.boot(function(err) {
          error = err;
          return done();
        });
      });
    
      it('should call callback', function() {
        expect(error).to.be.undefined;
      });
      it('should run phases in correct order', function() {
        expect(order).to.have.length(3);
        expect(order[0]).to.equal('1:AppFoo');
        expect(order[1]).to.equal('2:AppFoo');
        expect(order[2]).to.equal('3:AppFoo');
      });
    });
  });
  
});


<|start_filename|>test/package.test.js<|end_filename|>
/* global describe, it, expect */

var bootable = require('..');

describe('bootable', function() {
    
  it('should export function', function() {
    expect(bootable).to.be.a('function');
  });
  
  it('should export Initializer constructor', function() {
    expect(bootable.Initializer).to.be.a('function');
  });
  
  it('should export phases', function() {
    expect(bootable.initializers).to.be.a('function');
    expect(bootable.routes).to.be.a('function');
  });
  
  it('should export DI phases', function() {
    expect(bootable.di.initializers).to.be.a('function');
    expect(bootable.di.routes).to.be.a('function');
  });
  
});


<|start_filename|>test/phases/routes.test.js<|end_filename|>
/* global describe, it, expect */

var routes = require('../../lib/phases/routes');

describe('phases/routes', function() {
  
  it('should export a setup function', function() {
    expect(routes).to.be.a('function');
  });
  
  describe('phase with string argument', function() {
    var app = new Object();
    app.routes = {};
    app.get = function(path, handler) {
      app.routes[path] = handler;
    };
    
    var phase = routes(__dirname + '/../data/routes/test');
    phase.call(app);
    
    it('should draw routes', function() {
      expect(Object.keys(app.routes)).to.have.length(1);
      var handler = app.routes['/test'];
      expect(handler).to.be.a('function');
      expect(handler()).to.equal('GET /test');
    });
  });
  
  describe('phase with filename option', function() {
    var app = new Object();
    app.routes = {};
    app.get = function(path, handler) {
      app.routes[path] = handler;
    };
    
    var phase = routes({ filename: __dirname + '/../data/routes/test' });
    phase.apply(app);
    
    it('should draw routes', function() {
      expect(Object.keys(app.routes)).to.have.length(1);
      var handler = app.routes['/test'];
      expect(handler).to.be.a('function');
      expect(handler()).to.equal('GET /test');
    });
  });
  
});


<|start_filename|>test/data/initializers/error-done/01_error.js<|end_filename|>
module.exports = function(done) {
  process.nextTick(function() {
    done(new Error('something went wrong'));
  });
};


<|start_filename|>test/data/initializers/test/03_require.js<|end_filename|>
if (global.__app) { global.__app.order.push('03_require'); }


<|start_filename|>test/data/initializers/test/01_async.js<|end_filename|>
module.exports = function(done) {
  var self = this;
  process.nextTick(function() {
    self.order.push('01_async');
    done();
  });
};


<|start_filename|>test/phases/initializers.test.js<|end_filename|>
/* global describe, it, before, expect */

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;
    });
    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('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) {
        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 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');
    });
    it('should halt initializers after error', 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');
    });
    it('should halt initializers after error', function() {
      expect(app.order).to.have.length(0);
    });
  });
  
});
