Skip to content

Commit

Permalink
DI to allow for unit testing the builder
Browse files Browse the repository at this point in the history
  • Loading branch information
WMeldon committed Jun 11, 2014
1 parent 675d247 commit dc382e5
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 27 deletions.
18 changes: 12 additions & 6 deletions lib/commands/test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use strict';

var assign = require('lodash-node/modern/objects/assign');
var quickTemp = require('quick-temp');
var Command = require('../models/command');
var Watcher = require('../models/watcher');
var Builder = require('../models/builder');
var assign = require('lodash-node/modern/objects/assign');
var quickTemp = require('quick-temp');
var Command = require('../models/command');
var Watcher = require('../models/watcher');
var Builder = require('../models/builder');
var loadBrocfile = require('../utilities/load-brocfile');
var broccoli = require('broccoli');

module.exports = Command.extend({
name: 'test',
Expand Down Expand Up @@ -34,7 +36,11 @@ module.exports = Command.extend({

if (commandOptions.server) {
testOptions.liveOutputDir = options.liveOutputDir = this.tmp();
options.builder = new Builder(options);
options.builder = new Builder(assign(options, {
brocLoader: loadBrocfile,
brocBuilder: broccoli.Builder,
process: process
}));

var TestServerTask = this.tasks.TestServer;
var testServer = new TestServerTask(options);
Expand Down
17 changes: 8 additions & 9 deletions lib/models/builder.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
'use strict';

var loadBrocfile = require('../utilities/load-brocfile');
var broccoli = require('broccoli');
var Task = require('./task');

var signalsTrapped = false;

module.exports = Task.extend({
init: function() {
this.tree = loadBrocfile(this.liveOutputDir); // TODO:
this.builder = new broccoli.Builder(this.tree);

process.addListener('exit', this.onExit.bind(this));
this.tree = this.brocLoader(this.liveOutputDir); // TODO:
this.builder = new this.brocBuilder(this.tree);

this.process.addListener('exit', this.onExit.bind(this));

if (!signalsTrapped) {
process.on('SIGINT', this.onSIGINT.bind(this));
process.on('SIGTERM', this.onSIGTERM.bind(this));
this.process.on('SIGINT', this.onSIGINT.bind(this));
this.process.on('SIGTERM', this.onSIGTERM.bind(this));
signalsTrapped = true;
}
},
Expand All @@ -29,9 +28,9 @@ module.exports = Task.extend({
},

onSIGINT: function() {
process.exit(1);
this.process.exit(1);
},
onSIGTERM: function() {
process.exit(1);
this.process.exit(1);
}
});
28 changes: 18 additions & 10 deletions lib/tasks/build.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
'use strict';

var Promise = require('../ext/promise');
var rimraf = Promise.denodeify(require('rimraf'));
var mkdir = Promise.denodeify(require('fs').mkdir);
var ncp = Promise.denodeify(require('ncp'));
var chalk = require('chalk');
var Task = require('../models/task');
var Builder = require('../models/builder');
var Promise = require('../ext/promise');
var rimraf = Promise.denodeify(require('rimraf'));
var mkdir = Promise.denodeify(require('fs').mkdir);
var ncp = Promise.denodeify(require('ncp'));
var chalk = require('chalk');
var Task = require('../models/task');
var Builder = require('../models/builder');
var loadBrocfile = require('../utilities/load-brocfile');
var broccoli = require('broccoli');

module.exports = Task.extend({
// Options: String outputPath
run: function(options) {
var env = options.environment || 'development';
process.env.EMBER_ENV = process.env.EMBER_ENV || env;

var ui = this.ui;
var analytics = this.analytics;
var ui = this.ui;
var analytics = this.analytics;
var brocLoader = loadBrocfile;
var brocBuilder = broccoli.Builder;

ui.pleasantProgress.start(chalk.green('Building'), chalk.green('.'));

var builder = new Builder();
var builder = new Builder({
brocLoader: brocLoader,
brocBuilder: brocBuilder,
process: process
});

return builder.build()
.then(function(results) {
Expand Down
13 changes: 11 additions & 2 deletions lib/tasks/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@ var Promise = require('../ext/promise');
var Task = require('../models/task');
var Watcher = require('../models/watcher');
var Builder = require('../models/builder');
var loadBrocfile = require('../utilities/load-brocfile');
var broccoli = require('broccoli');

module.exports = Task.extend({
run: function(options) {
var env = options.environment || 'development';
var env = options.environment || 'development';
var brocLoader = loadBrocfile;
var brocBuilder = broccoli.Builder;

process.env.EMBER_ENV = process.env.EMBER_ENV || env;
var builder = new Builder();

var builder = new Builder({
brocLoader: brocLoader,
brocBuilder: brocBuilder,
process: process
});

var watcher = new Watcher({
ui: this.ui,
Expand Down
19 changes: 19 additions & 0 deletions tests/helpers/mock-builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

exports.Builder = Builder;

function Builder(tree) {
this.tree = tree;
this.cleanups = 0;
}
Builder.prototype.build = function(){};

Builder.prototype.cleanup = function() {
this.cleanups += 1;
};

function MockBuilder() {

}

MockBuilder.prototype.Builder = Builder;
28 changes: 28 additions & 0 deletions tests/helpers/mock-process.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

module.exports = MockProcess;
function MockProcess() {
this.signals = {};
this.listeners = {};
this.exits = 0;
}

MockProcess.prototype = Object.create({});
MockProcess.prototype.on = function(sig, fn) {
if (typeof this.signals[sig] === 'undefined') {
this.signals[sig] = [];
}
this.signals[sig].push(fn);
};

MockProcess.prototype.addListener = function(evt, fn) {
if (typeof this.listeners[evt] === 'undefined') {
this.listeners[evt] = [];
}
this.listeners[evt].push(fn);
};


MockProcess.prototype.exit = function(code) {
this.exits += code;
};
69 changes: 69 additions & 0 deletions tests/unit/models/builder-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict';

var assert = require('assert');

var MockProcess = require('../../helpers/mock-process');
var MockBrocBuilder = require('../../helpers/mock-builder');
var Builder = require('../../../lib/models/builder');

describe('Builder', function() {
var process;
var subject;
var builder;

before(function() {
builder = MockBrocBuilder;
process = new MockProcess();

subject = new Builder({
brocLoader: function(){},
brocBuilder: builder.Builder,
process: process,
});
});

describe('builder:init', function() {
it('binds signals', function() {
assert.equal(1, subject.process.signals.SIGINT.length);
assert.equal(1, subject.process.signals.SIGTERM.length);
assert.equal(1, subject.process.listeners.exit.length);
});
});

describe('builder:end', function() {
it('handles SIGTERM', function() {
process.signals.SIGTERM[0]();
assert.equal(1, process.exits);
});
it('handles SIGINT', function() {
process.signals.SIGINT[0]();
assert.equal(2, process.exits);
});
it('handles exit', function() {
process.listeners.exit[0]();
assert.equal(1, subject.builder.cleanups);
});
});

describe('builder:additional', function() {
var newSubject;

before(function() {
builder = MockBrocBuilder;
process = new MockProcess();

newSubject = new Builder({
brocLoader: function(){},
brocBuilder: builder.Builder,
process: process,
});
});

it('does not bind additional signal handlers', function() {
assert.ok(!newSubject.process.signals.SIGINT);
assert.ok(!newSubject.process.signals.SIGTERM);
});

});

});

0 comments on commit dc382e5

Please sign in to comment.