Skip to content

Commit

Permalink
Adding tonic runner tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tmrudick committed Sep 18, 2013
1 parent a05441e commit 94199aa
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -15,3 +15,4 @@ npm-debug.log
node_modules/

coverage.html
data_cache.json
4 changes: 3 additions & 1 deletion lib/job.js
Expand Up @@ -56,7 +56,9 @@ Job.prototype.stop = function() {
this.started = false;

this.intervals.forEach(function(interval) {
interval.stop();
if (interval != null) {
interval.stop();
}
});
}
};
Expand Down
12 changes: 6 additions & 6 deletions lib/tonic.js
Expand Up @@ -45,10 +45,10 @@ Tonic.prototype.jobs = function(directoryOrFileOrJob) {
// If path ends in .js, we will only load a single file
if (directoryOrFileOrJob instanceof Job) {
// TODO: Add validation logic here
this._jobs[job.name] = directoryOrFileOrJob;
this._jobs[directoryOrFileOrJob.name] = directoryOrFileOrJob;
return this;
} else if (path.extname(directoryOrFileOrJob) === '.js') {
files.push(directoryOrFileOrJob);
files.push(path.basename(directoryOrFileOrJob));
directoryOrFileOrJob = path.dirname(directoryOrFileOrJob);
} else {
// Otherwise, we will load a whole directory of files
Expand Down Expand Up @@ -110,8 +110,7 @@ Tonic.prototype.start = function() {

// Loop over each job
ids.forEach(function(id) {
var job = self._jobs[id],
wildcard = false;
var job = self._jobs[id];

// If we have a valid cache, attach and writer event handler
// to continuously write cached data to the filesystem
Expand All @@ -126,8 +125,7 @@ Tonic.prototype.start = function() {

// If we have a wild card dependency, add everything
if (_.contains(job.dependencies, '*')) {
job.dependencies = _.uniq(job.dependencies.concat(ids));
wildcard = true;
job.dependencies = _.without(_.uniq(job.dependencies.concat(ids)), job.name);
}

// Loop over each dependency and hook up the event listener
Expand Down Expand Up @@ -167,6 +165,8 @@ Tonic.prototype.stop = function() {
ids.forEach(function(id) {
self._jobs[id].stop();
});

this.running = false;
}
};

Expand Down
9 changes: 9 additions & 0 deletions test/fixtures/duplicate-jobs.js
@@ -0,0 +1,9 @@
job('BadJob', function(done) {
global.singleJob = true;
done();
});

job('BadJob', function(done) {
global.singleJob = true;
done();
});
4 changes: 4 additions & 0 deletions test/fixtures/job-without-id.js
@@ -0,0 +1,4 @@
job(function(done) {
global.jobWithNoName = true;
done();
}).once();
5 changes: 5 additions & 0 deletions test/fixtures/jobs/job-one.js
@@ -0,0 +1,5 @@
job('Job One', function(done) {
global.jobone = true;

done();
}).once();
5 changes: 5 additions & 0 deletions test/fixtures/jobs/job-two.js
@@ -0,0 +1,5 @@
job('Job Two', function(done) {
global.jobtwo = true;

done();
}).once();
4 changes: 4 additions & 0 deletions test/fixtures/single-job.js
@@ -0,0 +1,4 @@
job('Single Job', function(done) {
global.singleJob = true;
done();
}).once();
197 changes: 191 additions & 6 deletions test/tonic-tests.js
Expand Up @@ -4,6 +4,8 @@ var assert = require('assert'),
Job = require('../lib/job'),
path = require('path');

var emptyFunc = function(d) { d(); };

describe('Configuration', function() {
it('will assume default file paths if config is not given', function(done) {
var options = {};
Expand Down Expand Up @@ -54,21 +56,204 @@ describe('Configuration', function() {
});

describe('Loading Jobs', function() {
it('will load a single job file');
it('will load a directory of job files');
it('will load a single job file', function(done) {
var tonic = new Tonic();
tonic.jobs('test/fixtures/single-job.js');
tonic.start();

setTimeout(function() {
assert.ok(global.singleJob);
done();
}, 25);
});

it('will load a directory of job files', function(done) {
var tonic = new Tonic();
tonic.jobs('test/fixtures/jobs');
tonic.start();

setTimeout(function() {
assert.ok(global.jobone);
assert.ok(global.jobtwo);
done();
}, 25);
});

it('will load modules from node_module directory');

it('will load an already constructed job object', function(done) {
var tonic = new Tonic();
var job = new Job('Name', {}, function() {
global.constructedJob = true;
}).once();

tonic.jobs(job);
tonic.start();

setTimeout(function() {
assert.ok(global.constructedJob);
done();
}, 25);
});
});

describe('Job creation', function() {
it('should create jobs without a name');
it('should verify that job names are unique');
it('should create jobs without a name', function(done) {
var tonic = new Tonic();
tonic.jobs('test/fixtures/job-without-id.js');

var jobIds = Object.keys(tonic._jobs);

// Only one job
assert.equal(jobIds.length, 1);

// 5 character 'id'
assert.equal(jobIds[0].length, 5);

// No name
assert.equal(tonic._jobs[jobIds[0]].name, null);

// Still runs!
tonic.start();

setTimeout(function() {
assert.ok(global.jobWithNoName);
done();
}, 25);
});

it('will not load two jobs with the same id', function(done) {
var tonic = new Tonic();

assert.throws(function() {
tonic.jobs('test/fixtures/duplicate-jobs.js');
}, /Job 'BadJob' already defined/);

done();
});
});

describe('Run state', function() {
it('should be able to start running');
it('should be able to stop running');
it('should be able to start and stop running', function(done) {
var tonic = new Tonic();

global.runStateCount = 0;
var job = new Job(null, {}, function() {
if (global.runStateCount == 1) {
assert.fail('Should not be here');
}
global.runStateCount++;
}).once().every('1s');

tonic.jobs(job);

assert.ok(!tonic.running);
tonic.start();
assert.ok(tonic.running);
tonic.stop();
assert.ok(!tonic.running);

setTimeout(function() {
assert.equal(global.runStateCount, 1);
done();
}, 1000);
});
});

describe('Job dependency graph creation', function() {
it('should not allow taking a dependency on an undefined job', function(done) {
var jobA = new Job('A', {}, emptyFunc).after('DoesNotExist');

var tonic = new Tonic();
tonic.jobs(jobA);
assert.throws(function() { tonic.start(); }, /Job 'DoesNotExist' does not exist/);
done();
});

it('should allow jobs to take direct dependencies on other jobs', function(done) {
var jobA = new Job('A', {}, emptyFunc);
var jobB = new Job('B', {}, emptyFunc).after('A');

var tonic = new Tonic();
tonic.jobs(jobA);
tonic.jobs(jobB);

tonic.start();

assert.equal(jobB.dependencies[0], jobA.name);
done();
});

it('should allow a job to take a dependency on all other jobs using *', function(done) {
var jobA = new Job('A', {}, emptyFunc);
var jobB = new Job('B', {}, emptyFunc);
var jobC = new Job('C', {}, emptyFunc).after('*');

var tonic = new Tonic();
tonic.jobs(jobA);
tonic.jobs(jobB);
tonic.jobs(jobC);

assert.equal(jobC.dependencies.length, 1);
assert.equal(jobC.dependencies[0], '*');

tonic.start();

assert.equal(jobC.dependencies.length, 3);
assert.equal(jobC.dependencies[0], '*');
assert.equal(jobC.dependencies[1], jobA.name);
assert.equal(jobC.dependencies[2], jobB.name);

done();
});

it('should disallow * jobs from taking a dependency on each other', function(done) {
var jobA = new Job('A', {}, emptyFunc).after('*');
var jobB = new Job('B', {}, emptyFunc).after('*');

var tonic = new Tonic();
tonic.jobs(jobA).jobs(jobB);

// Before we start tonic
assert.equal(jobA.dependencies.length, 1);
assert.equal(jobB.dependencies.length, 1);
assert.equal(jobA.dependencies[0], '*');
assert.equal(jobB.dependencies[0], '*');

tonic.start();

// Only one tonic listener which writes data to disk
assert.equal(jobA.listeners('done').length, 1);
assert.equal(jobB.listeners('done').length, 1);

done();
});

it('should allow jobs to take a dependeny on more than one other job', function(done) {
var jobA = new Job('A', {}, emptyFunc);
var jobB = new Job('B', {}, emptyFunc);
var jobC = new Job('C', {}, emptyFunc).after('A').after('B');

var tonic = new Tonic();
tonic.jobs(jobA).jobs(jobB).jobs(jobC);
tonic.start();

assert.equal(jobC.dependencies.length, 2);
assert.equal(jobC.dependencies[0], jobA.name);
assert.equal(jobC.dependencies[1], jobB.name);

done();
});

it('should start dependent jobs when the parent job finishes', function(done) {
var jobA = new Job('A', {}, emptyFunc).once();;
var jobB = new Job('B', {}, function() {
assert.equal(this.parent, jobA.name);
done();
}).after('A');

var tonic = new Tonic();
tonic.jobs(jobA).jobs(jobB);
tonic.start();
});
});

0 comments on commit 94199aa

Please sign in to comment.