Permalink
Browse files

Adding job tests

  • Loading branch information...
1 parent 192fcf7 commit 4a4b3365c001c0f677663df7f5e18bb46138fed0 @tmrudick committed Sep 14, 2013
Showing with 264 additions and 22 deletions.
  1. +2 −0 .gitignore
  2. +16 −20 lib/job.js
  3. +4 −2 package.json
  4. +3 −0 test/fixtures/test-config.json
  5. +3 −0 test/fixtures/test-data-cache.json
  6. +162 −0 test/job-tests.js
  7. +74 −0 test/tonic-tests.js
View
@@ -13,3 +13,5 @@ results
npm-debug.log
node_modules/
+
+coverage.html
View
@@ -46,7 +46,7 @@ Job.prototype.start = function() {
}
// If we have more than 0 intervals and we aren't defered, run now
- if (this.intervals.length > 0 && !this.deferred) {
+ if (this.intervals.length > 0 && !this.deferred && this.enabled) {
this.run();
}
};
@@ -55,9 +55,9 @@ Job.prototype.stop = function() {
if (this.started) {
this.started = false;
- for (var idx = 0; i < this.intervals.length; i++) {
- this.intervals[idx].stop();
- }
+ this.intervals.forEach(function(interval) {
+ interval.stop();
+ });
}
};
@@ -144,29 +144,25 @@ Job.prototype.defer = function() {
}
function _textToCron(text) {
+ var regex = /^(\d+)\s{0,1}(\w)\w*$/;
+
// If a user types 5min then we want the job to run every 5 minutes.
// Same with hours or days. Acceptable values are:
// 10m, 10minutes, 10 minutes, 1 day, once
var units = {
- "m": '*/%d * * * *',
- "h": '0 */%d * * *',
- "d": '0 0 */%d * *',
- "s": '*/%d * * * * *'
+ 'm': '*/%d * * * *',
+ 'h': '0 */%d * * *',
+ 'd': '0 0 */%d * *',
+ 's': '*/%d * * * * *'
};
- // Return null if the user only wants to run something once
- if (text === "once") {
- return null;
- }
-
- Object.keys(units).forEach(function(key) {
- var idx = text.indexOf(key);
+ if (regex.test(text)) {
+ var matches = regex.exec(text),
+ value = matches[1],
+ key = matches[2];
- if (idx > 0) {
- var value = text.substring(0, idx);
- text = util.format(units[key], value);
- }
- });
+ text = util.format(units[key], value);
+ }
return text;
}
View
@@ -4,7 +4,8 @@
"description": "A static site generator based on scheduled tasks",
"main": "lib/tonic.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "test": "node_modules/mocha/bin/mocha",
+ "blanket": { "pattern": "/tonic/lib" }
},
"bin": {
"tonic": "./bin/tonic"
@@ -23,6 +24,7 @@
"lodash": "~1.3.1"
},
"devDependencies": {
- "mocha": "1.12.0"
+ "mocha": "1.12.0",
+ "blanket": "1.1.5"
}
}
@@ -0,0 +1,3 @@
+{
+ "option": "value"
+}
@@ -0,0 +1,3 @@
+{
+ "job": "Some previous value"
+}
View
@@ -0,0 +1,162 @@
+var assert = require('assert'),
+ Job = require('../lib/job');
+
+var emptyFunc = function() {};
+
+describe('Chaining Job API', function() {
+ describe('Time based functions', function() {
+ it('every translates into cron time', function(done) {
+ var job = new Job('Test', {}, emptyFunc);
+
+ // Seconds
+ job.every('10s').every('10 seconds').every('10 sec');
+
+ // Minutes
+ job.every('5m').every('5 minutes').every('5 min');
+
+ // Hours
+ job.every('2h').every('2 hour').every('2 hr');
+
+ // Days
+ job.every('3d').every('3 days');
+
+ // Seconds
+ assert.equal(job.intervals[0], '*/10 * * * * *');
+ assert.equal(job.intervals[1], '*/10 * * * * *');
+ assert.equal(job.intervals[2], '*/10 * * * * *');
+
+ assert.equal(job.intervals[3], '*/5 * * * *');
+ assert.equal(job.intervals[4], '*/5 * * * *');
+ assert.equal(job.intervals[5], '*/5 * * * *');
+
+ assert.equal(job.intervals[6], '0 */2 * * *');
+ assert.equal(job.intervals[7], '0 */2 * * *');
+ assert.equal(job.intervals[8], '0 */2 * * *');
+
+ assert.equal(job.intervals[9], '0 0 */3 * *');
+ assert.equal(job.intervals[10], '0 0 */3 * *');
+
+ assert.equal(job.intervals.length, 11);
+
+ done();
+ });
+
+ it('at creates an interval', function(done) {
+ var job = new Job('Test', {}, emptyFunc);
+
+ job.at('10 * * * *');
+
+ assert.equal(job.intervals[0], '10 * * * *');
+
+ assert.equal(job.intervals.length, 1);
+
+ done();
+ });
+
+ it('once creates a null interval', function(done) {
+ var job = new Job('Test', {}, emptyFunc);
+
+ job.once();
+
+ assert.equal(job.intervals[0], null);
+
+ assert.equal(job.intervals.length, 1);
+
+ done();
+ });
+ });
+
+ describe('Deferred property', function() {
+
+ });
+
+ describe('Job control states', function() {
+ it('jobs can be started', function(done) {
+ var job = new Job('Test', {}, function() {
+ done();
+ });
+
+ job.once();
+ job.start();
+ });
+
+ it('jobs can be stopped', function(done) {
+ var counter = 0;
+ var job = new Job('Test', {}, function(d) {
+ counter += 1;
+ d();
+ });
+
+ job.every('1s').start();
+ assert.ok(job.intervals[0].running);
+ job.stop();
+
+ setTimeout(function() {
+ assert.equal(counter, 1);
+ assert.ok(!job.intervals[0].running);
+ done();
+ }, 10);
+
+ });
+
+ it('disabled jobs are not run', function(done) {
+ var job = new Job('Test', {}, function() {
+ assert.fail('Job code runs', 'Job code should not run');
+ });
+
+ job.once().disable();
+ job.start();
+
+ setTimeout(function() {
+ done();
+ }, 10);
+ });
+
+ it('re-enabled jobs still run', function(done) {
+ var job = new Job('Test', {}, function() {
+ done();
+ });
+
+ job.once().disable().enable();
+ job.start();
+ });
+ });
+
+ describe('Job initial startup', function() {
+ it('deferred jobs are not run', function(done) {
+ var job = new Job('Test', {}, function() {
+ // If this code runs, the test fails.
+ assert.fail('Job code runs', 'Job code should not run');
+ });
+
+ job.once().defer();
+
+ job.start();
+
+ // setTimeout so we wait for nextTick
+ setTimeout(function() {
+ done();
+ }, 10);
+ });
+
+ it('will run time-based jobs immediately', function(done) {
+ var job = new Job('Test', {}, function() {
+ done();
+ }).once();
+
+ job.start();
+ });
+
+ it('will not run jobs that do not have time-based triggers', function(done) {
+ var job = new Job('Test', {}, function() {
+ assert.fail('Job code runs', 'Job code should not run.');
+ });
+
+ job.start();
+
+ setTimeout(function() {
+ done();
+ }, 10);
+ });
+ });
+});
View
@@ -0,0 +1,74 @@
+
+var assert = require('assert'),
+ Tonic = require('../lib/tonic'),
+ Job = require('../lib/job'),
+ path = require('path');
+
+describe('Configuration', function() {
+ it('will assume default file paths if config is not given', function(done) {
+ var options = {};
+
+ var tonic = new Tonic(options); // no options
+
+ // Options defaults are working
+ assert.equal(options.config, 'config.json');
+ assert.equal(options.cache, 'data_cache.json');
+
+ // Config is an object (empty)
+ assert.equal(typeof(tonic._config), 'object');
+ assert.equal(Object.keys(tonic._config).length, 0);
+
+ // Cache object exists and is empty
+ assert.ok(tonic._cache.filename);
+ assert.equal(typeof(tonic._cache.data), 'object');
+ assert.equal(Object.keys(tonic._cache.data).length, 0);
+
+ done();
+ });
+
+ it('should override the defaults with provided options', function(done) {
+ // TODO: Override require for json loading instead of this
+ var options = {
+ config: 'test/fixtures/test-config.json',
+ cache: 'test/fixtures/test-data-cache.json'
+ };
+
+ var tonic = new Tonic(options);
+ assert.equal(tonic._config.option, 'value');
+ assert.equal(tonic._cache.data.job, 'Some previous value');
+
+ done();
+ });
+
+ it('will create an empty config if config file does not exist', function(done) {
+ var options = {
+ config: 'some-file-that-doesnt-exist.json'
+ };
+
+ var tonic = new Tonic(options);
+ assert.equal(typeof(tonic._config), 'object');
+ assert.equal(Object.keys(tonic._config).length, 0);
+
+ done();
+ });
+});
+
+describe('Loading Jobs', function() {
+ it('will load a single job file');
+ it('will load a directory of job files');
+ it('will load modules from node_module directory');
+});
+
+describe('Job creation', function() {
+ it('should create jobs without a name');
+ it('should verify that job names are unique');
+});
+
+describe('Run state', function() {
+ it('should be able to start running');
+ it('should be able to stop running');
+});
+
+describe('Job dependency graph creation', function() {
+
+});

0 comments on commit 4a4b336

Please sign in to comment.