Skip to content

Commit

Permalink
Adding the ability for the task queue to be cleared more programmatic…
Browse files Browse the repository at this point in the history
…ally via marker.
  • Loading branch information
cowboy committed Apr 6, 2012
1 parent e5c003e commit ded480c
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 16 deletions.
52 changes: 37 additions & 15 deletions lib/util/task.js
Expand Up @@ -20,7 +20,9 @@
// Task queue.
this._queue = [];
// Queue placeholder (for dealing with nested tasks).
this._placeholder = {};
this._placeholder = {placeholder: true};
// Queue marker (for clearing the queue programatically).
this._marker = {marker: true};
// Options.
this._options = {};
// Is the queue running?
Expand Down Expand Up @@ -240,6 +242,19 @@
return {task: task, nameArgs: name, args: args, flags: flags};
};

// Append things to queue in the correct spot.
Task.prototype._push = function(things) {
// Get current placeholder index.
var index = this._queue.indexOf(this._placeholder);
if (index === -1) {
// No placeholder, add task+args objects to end of queue.
this._queue = this._queue.concat(things);
} else {
// Placeholder exists, add task+args objects just before placeholder.
[].splice.apply(this._queue, [index, 0].concat(things));
}
};

// Enqueue a task.
Task.prototype.run = function() {
// Parse arguments into an array, returning an array of task+args objects.
Expand All @@ -250,15 +265,15 @@
this._throwIfRunning(new TaskError('Task "' + fails[0].nameArgs + '" not found.'));
return this;
}
// Get current placeholder index.
var index = this._queue.indexOf(this._placeholder);
if (index === -1) {
// No placeholder, add task+args objects to end of queue.
this._queue = this._queue.concat(things);
} else {
// Placeholder exists, add task+args objects just before placeholder.
[].splice.apply(this._queue, [index, 0].concat(things));
}
// Append things to queue in the correct spot.
this._push(things);
// Make chainable!
return this;
};

// Add a marker to the queue to facilitate clearing it programatically.
Task.prototype.mark = function() {
this._push(this._marker);
// Make chainable!
return this;
};
Expand All @@ -273,8 +288,10 @@
var async = false;
// Get next task+args object from queue.
var thing;
// Skip any placeholders.
do { thing = this._queue.shift(); } while (thing === this._placeholder);
// Skip any placeholders or markers.
do {
thing = this._queue.shift();
} while (thing === this._placeholder || thing === this._marker);
// If queue was empty, we're all done.
if (!thing) {
this._running = false;
Expand Down Expand Up @@ -340,9 +357,14 @@
nextTask();
};

// Clear all remaining tasks from the queue, or a subset.
Task.prototype.clearQueue = function() {
this._queue = [];
// Clear remaining tasks from the queue.
Task.prototype.clearQueue = function(options) {
if (!options) { options = {}; }
if (options.untilMarker) {
this._queue.splice(0, this._queue.indexOf(this._marker) + 1);
} else {
this._queue = [];
}
// Make chainable!
return this;
};
Expand Down
56 changes: 55 additions & 1 deletion test/util/task_test.js
Expand Up @@ -285,7 +285,8 @@ exports['Tasks'] = {
}
});
task.run('a:b:c').start();
}, 'Task#clearQueue': function(test) {
},
'Task#clearQueue': function(test) {
test.expect(1);
var task = this.task;
task.registerTask('a', 'Push task name onto result.', result.pushTaskname);
Expand All @@ -305,6 +306,59 @@ exports['Tasks'] = {
});
task.run('a b c d e').start();
},
'Task#mark': function(test) {
// test.expect(1);
var task = this.task;
task.registerTask('a', 'Explode.', function() {
throw task.taskError('whoops.');
});
task.registerTask('b', 'This task should never run.', result.pushTaskname);
task.registerTask('c', 'This task should never run.', result.pushTaskname);

task.registerTask('d', 'Push task name onto result.', result.pushTaskname);
task.registerTask('e', 'Explode.', function() {
throw task.taskError('whoops.');
});
task.registerTask('f', 'This task should never run.', result.pushTaskname);

task.registerTask('g', 'Push task name onto result.', result.pushTaskname);
task.registerTask('h', 'Push task name onto result.', result.pushTaskname);
task.registerTask('i', 'Explode.', function() {
throw task.taskError('whoops.');
});

task.registerTask('j', 'Run a task and push task name onto result.', function() {
task.run('k');
result.push(this.name);
});
task.registerTask('k', 'Explode.', function() {
throw task.taskError('whoops.');
});
task.registerTask('l', 'This task should never run.', result.pushTaskname);

task.registerTask('m', 'Push task name onto result.', result.pushTaskname);
task.registerTask('n', 'Run a task and push task name onto result.', function() {
task.run('o');
result.push(this.name);
});
task.registerTask('o', 'Explode.', function() {
throw task.taskError('whoops.');
});

task.registerTask('p', 'Push task name onto result.', result.pushTaskname);

task.options({
error: function(e) {
result.push('!' + this.name);
task.clearQueue({untilMarker: true});
},
done: function() {
test.strictEqual(result.getJoined(), '!ad!egh!ij!kmn!op', 'The specified tasks should have run, in-order.');
test.done();
}
});
task.run('a b c').mark().run('d e f').mark().run('g h i').mark().run('j l').mark().run('m n').mark().run('p').mark().start();
},
'Task#requires': function(test) {
test.expect(1);
var task = this.task;
Expand Down

0 comments on commit ded480c

Please sign in to comment.