Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 1 commit
  • 6 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jul 04, 2012
Benjamin Lupton v1.11.1. balUtilFlow improvements to Group, and fixes to Block
- v1.11.1 July 4, 2012
	- `balUtilFlow` changes:
		- `Group` changes:
			- Cleaned up the context handling code
		- `Block` changes:
			- Block constructor as well as `createSubBlock` arguments is now a
single `opts` object, accepting the options `name`, `fn`, `parentBlock`
and the new `complete`
			- Fixed bug introduced in v1.11.0 causing blocks to complete
instantly (instead of once their tasks are finished)
4bd2c2c
8 History.md
View
@@ -1,5 +1,13 @@
## History
+- v1.11.1 July 4, 2012
+ - `balUtilFlow` changes:
+ - `Group` changes:
+ - Cleaned up the context handling code
+ - `Block` changes:
+ - Block constructor as well as `createSubBlock` arguments is now a single `opts` object, acceping the options `name`, `fn`, `parentBlock` and the new `complete`
+ - Fixed bug introduced in v1.11.0 causing blocks to complete instantly (instead of once their tasks are finished)
+
- v1.11.0 July 1, 2012
- Added `balUtilHTML`:
- `getAttribute(attributes,attribute)`
123 out/lib/flow.js
View
@@ -217,13 +217,20 @@
return this.exited === true;
};
+ _Class.prototype.logError = function(err) {
+ if (this.errors[this.errors.length - 1] !== err) {
+ this.errors.push(err);
+ }
+ return this;
+ };
+
_Class.prototype.complete = function() {
var args, err;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
err = args[0] || void 0;
this.lastResult = args;
if (err) {
- this.errors.push(err);
+ this.logError(err);
}
this.results.push(args);
if (this.running !== 0) {
@@ -260,15 +267,21 @@
if (err == null) {
err = null;
}
+ if (err) {
+ this.logError(err);
+ }
if (this.hasExited()) {
} else {
lastResult = this.lastResult;
- errors = this.errors.length !== 0 ? this.errors : null;
- if (this.errors.length === 1) {
- errors = errors[0];
- }
results = this.results;
+ if (this.errors.length === 0) {
+ errors = null;
+ } else if (this.errors.length === 1) {
+ errors = this.errors[0];
+ } else {
+ errors = this.errors;
+ }
if (this.autoClear) {
this.clear();
} else {
@@ -289,39 +302,21 @@
};
_Class.prototype.push = function() {
- var args, context, task, _task;
+ var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
++this.total;
- if (args.length === 2) {
- context = args[0];
- _task = args[1];
- task = function(complete) {
- return balUtilFlow.fireWithOptionalCallback(_task, [complete], context);
- };
- } else {
- task = args[0];
- }
- this.queue.push(task);
+ this.queue.push(args);
return this;
};
_Class.prototype.pushAndRun = function() {
- var args, context, task, _task;
+ var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
- if (args.length === 2) {
- context = args[0];
- _task = args[1];
- task = function(complete) {
- return balUtilFlow.fireWithOptionalCallback(_task, [complete], context);
- };
- } else {
- task = args[0];
- }
if (this.mode === 'sync' && this.isRunning()) {
- this.push(task);
+ this.push.apply(this, args);
} else {
++this.total;
- this.runTask(task);
+ this.runTask(args);
}
return this;
};
@@ -340,10 +335,23 @@
me = this;
try {
run = function() {
- var complete;
+ var complete, _context, _task;
++me.running;
complete = me.completer();
- return balUtilFlow.fireWithOptionalCallback(task, [complete]);
+ if (balUtilFlow.isArray(task)) {
+ if (task.length === 2) {
+ _context = task[0];
+ _task = task[1];
+ } else if (task.length === 1) {
+ _task = task[0];
+ _context = null;
+ } else {
+ throw new Error('balUtilFlow.Group an invalid task was pushed');
+ }
+ } else {
+ _task = task;
+ }
+ return balUtilFlow.fireWithOptionalCallback(_task, [complete], _context);
};
if (this.completed !== 0 && (this.mode === 'async' || (this.completed % 100) === 0)) {
setTimeout(run, 0);
@@ -405,39 +413,39 @@
_Class.prototype.blockTaskAfter = function(block, task, err) {};
- function _Class(name, initFunction, parentBlock) {
- var block;
+ function _Class(opts) {
+ var block, complete, fn, name, parentBlock;
block = this;
- _Class.__super__.constructor.call(this, function(err) {
- var _ref;
- block.blockAfter(block, err);
- return (_ref = block.parentBlock) != null ? _ref.complete(err) : void 0;
- });
+ name = opts.name, fn = opts.fn, parentBlock = opts.parentBlock, complete = opts.complete;
block.blockName = name;
if (parentBlock != null) {
block.parentBlock = parentBlock;
}
block.mode = 'sync';
- block.initFunction = initFunction;
+ block.fn = fn;
+ _Class.__super__.constructor.call(this, function(err) {
+ block.blockAfter(block, err);
+ return typeof complete === "function" ? complete(err) : void 0;
+ });
block.blockBefore(block);
- if (block.initFunction != null) {
- if (block.initFunction.length === 3) {
+ if (block.fn != null) {
+ if (block.fn.length === 3) {
block.total = Infinity;
}
try {
- block.initFunction(function(name, fn) {
+ block.fn(function(name, fn) {
return block.block(name, fn);
}, function(name, fn) {
return block.task(name, fn);
}, function(err) {
return block.exit(err);
});
+ if (block.fn.length !== 3) {
+ block.run();
+ }
} catch (err) {
block.exit(err);
}
- if (block.initFunction.length !== 3) {
- block.run();
- }
} else {
block.total = Infinity;
}
@@ -446,34 +454,39 @@
}
_Class.prototype.block = function(name, fn) {
- var block, push;
+ var block, pushBlock;
block = this;
- push = function(complete) {
+ pushBlock = function(fn) {
if (block.total === Infinity) {
- return block.pushAndRun(complete);
+ return block.pushAndRun(fn);
} else {
- return block.push(complete);
+ return block.push(fn);
}
};
- push(function() {
+ pushBlock(function(complete) {
var subBlock;
- return subBlock = block.createSubBlock(name, fn, block);
+ return subBlock = block.createSubBlock({
+ name: name,
+ fn: fn,
+ complete: complete
+ });
});
return this;
};
- _Class.prototype.createSubBlock = function(name, fn, parentBlock) {
- return new balUtilFlow.Block(name, fn, parentBlock);
+ _Class.prototype.createSubBlock = function(opts) {
+ opts.parentBlock = this;
+ return new balUtilFlow.Block(opts);
};
_Class.prototype.task = function(name, fn) {
var block, pushTask;
block = this;
- pushTask = function(complete) {
+ pushTask = function(fn) {
if (block.total === Infinity) {
- return block.pushAndRun(complete);
+ return block.pushAndRun(fn);
} else {
- return block.push(complete);
+ return block.push(fn);
}
};
pushTask(function(complete) {
193 out/test/flow.test.js
View
@@ -51,14 +51,17 @@
joe.describe('Group', function(describe, it) {
it('should work when tasks are specified manually', function(done) {
- var finished, firstTaskFinished, secondTaskFinished, tasks;
+ var finished, firstTaskFinished, secondTaskFinished, tasks, total;
firstTaskFinished = false;
secondTaskFinished = false;
finished = false;
+ total = 2;
tasks = new balUtil.Group(function(err) {
+ if (err) {
+ return done(err);
+ }
assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
+ return finished = true;
});
tasks.total = 2;
wait(1000, function() {
@@ -73,7 +76,7 @@
});
assert.equal(0, tasks.completed, 'no tasks should have started yet');
return wait(2000, function() {
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran');
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
@@ -81,16 +84,19 @@
});
});
it('should work when run synchronously', function(done) {
- var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks;
+ var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks, total;
firstTaskRun = false;
secondTaskRun = false;
firstTaskFinished = false;
secondTaskFinished = false;
finished = false;
+ total = 2;
tasks = new balUtil.Group(function(err) {
+ if (err) {
+ return done(err);
+ }
assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
+ return finished = true;
});
tasks.push(function(complete) {
firstTaskRun = true;
@@ -114,7 +120,7 @@
tasks.sync();
assert.equal(true, tasks.isRunning(), 'isRunning() returned true');
return wait(2000, function() {
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran');
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
@@ -122,16 +128,19 @@
});
});
it('should work when run asynchronously', function(done) {
- var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks;
+ var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks, total;
firstTaskRun = false;
secondTaskRun = false;
firstTaskFinished = false;
secondTaskFinished = false;
finished = false;
+ total = 2;
tasks = new balUtil.Group(function(err) {
+ if (err) {
+ return done(err);
+ }
assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
+ return finished = true;
});
tasks.push(function(complete) {
firstTaskRun = true;
@@ -155,7 +164,7 @@
tasks.async();
assert.equal(true, tasks.isRunning(), 'isRunning() returned true');
return wait(2000, function() {
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran');
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
@@ -163,16 +172,17 @@
});
});
it('should handle errors correctly', function(done) {
- var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks;
+ var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks, total;
firstTaskRun = false;
secondTaskRun = false;
firstTaskFinished = false;
secondTaskFinished = false;
finished = false;
+ total = 1;
tasks = new balUtil.Group(function(err) {
+ assert.equal(true, err !== null, 'an error is present');
assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(true, err != null, 'an error is present');
+ return finished = true;
});
tasks.push(function(complete) {
firstTaskRun = true;
@@ -196,7 +206,7 @@
tasks.sync();
assert.equal(true, tasks.isRunning(), 'isRunning() returned true');
return wait(2000, function() {
- assert.equal(1, tasks.completed, 'only the expected number of tasks ran');
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
assert.equal(false, tasks.hasCompleted(), 'hasCompleted() returned true');
assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
@@ -205,12 +215,14 @@
});
it('should work with optional completion callbacks', function(done) {
var finished, tasks, total;
- total = 2;
finished = false;
+ total = 2;
tasks = new balUtil.Group(function(err) {
+ if (err) {
+ return done(err);
+ }
assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
+ return finished = true;
});
tasks.push(function(done) {
return done();
@@ -228,12 +240,14 @@
});
it('should work when specifying contexts', function(done) {
var finished, tasks, total;
- total = 2;
finished = false;
+ total = 2;
tasks = new balUtil.Group(function(err) {
+ if (err) {
+ return done(err);
+ }
assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
+ return finished = true;
});
tasks.push({
blah: 1
@@ -255,65 +269,20 @@
return done();
});
});
- it('should work when running ten thousand tasks synchronously', function(done) {
- var finished, i, tasks, total, _i;
- total = 10000;
- finished = false;
- tasks = new balUtil.Group(function(err) {
- assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
- });
- for (i = _i = 0; 0 <= total ? _i < total : _i > total; i = 0 <= total ? ++_i : --_i) {
- tasks.push(function(complete) {
- return complete();
- });
- }
- assert.equal(0, tasks.completed, 'no tasks should have started yet');
- tasks.sync();
- return wait(5000, function() {
- assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
- assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
- assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
- assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
- return done();
- });
- });
- it('should work when running ten thousand tasks asynchronously', function(done) {
- var finished, i, tasks, total, _i;
- total = 10000;
- finished = false;
- tasks = new balUtil.Group(function(err) {
- assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
- });
- for (i = _i = 0; 0 <= total ? _i < total : _i > total; i = 0 <= total ? ++_i : --_i) {
- tasks.push(function(complete) {
- return setTimeout(complete, 50);
- });
- }
- assert.equal(0, tasks.completed, 'no tasks should have started yet');
- tasks.async();
- return wait(5000, function() {
- assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
- assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
- assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
- assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
- return done();
- });
- });
it('should push and run synchronous tasks correctly', function(done) {
- var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks;
+ var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks, total;
firstTaskRun = false;
secondTaskRun = false;
firstTaskFinished = false;
secondTaskFinished = false;
finished = false;
+ total = 2;
tasks = new balUtil.Group('sync', function(err) {
+ if (err) {
+ return done(err);
+ }
assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
+ return finished = true;
});
assert.equal('sync', tasks.mode, 'mode was correctly set to sync');
tasks.pushAndRun(function(complete) {
@@ -336,7 +305,7 @@
});
});
return wait(4000, function() {
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran');
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
@@ -344,16 +313,19 @@
});
});
it('should push and run asynchronous tasks correctly (queued)', function(done) {
- var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks;
+ var finished, firstTaskFinished, firstTaskRun, secondTaskFinished, secondTaskRun, tasks, total;
firstTaskRun = false;
secondTaskRun = false;
firstTaskFinished = false;
secondTaskFinished = false;
finished = false;
+ total = 2;
tasks = new balUtil.Group('async', function(err) {
+ if (err) {
+ return done(err);
+ }
assert.equal(false, finished, 'the group of tasks only finished once');
- finished = true;
- return assert.equal(false, err != null, 'no error is present');
+ return finished = true;
});
assert.equal('async', tasks.mode, 'mode was correctly set to async');
tasks.pushAndRun(function(complete) {
@@ -376,21 +348,24 @@
});
});
return wait(4000, function() {
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran');
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
return done();
});
});
- return it('should push and run synchronous tasks correctly (multiple times)', function(done) {
- var finished, tasks;
+ it('should push and run synchronous tasks correctly (multiple times)', function(done) {
+ var finished, tasks, total;
finished = 0;
+ total = 2;
tasks = new balUtil.Group('sync', {
autoClear: true
}, function(err) {
- ++finished;
- return assert.equal(false, err != null, 'no error is present');
+ if (err) {
+ return done(err);
+ }
+ return ++finished;
});
assert.equal('sync', tasks.mode, 'mode was correctly set to sync');
assert.equal(true, tasks.autoClear, 'autoClear was correctly set to true');
@@ -406,13 +381,65 @@
return assert.equal(true, tasks.isRunning(), 'isRunning() returned true');
});
return wait(2000, function() {
- assert.equal(2, finished, 'it exited the correct number of times');
+ assert.equal(total, finished, 'it exited the correct number of times');
assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
assert.equal(false, tasks.hasCompleted(), 'hasCompleted() returned false');
assert.equal(false, tasks.hasExited(), 'hasExited() returned false');
return done();
});
});
+ it('should work when running ten thousand tasks synchronously', function(done) {
+ var finished, i, tasks, total, _i;
+ finished = false;
+ total = 10000;
+ tasks = new balUtil.Group(function(err) {
+ if (err) {
+ return done(err);
+ }
+ assert.equal(false, finished, 'the group of tasks only finished once');
+ return finished = true;
+ });
+ for (i = _i = 0; 0 <= total ? _i < total : _i > total; i = 0 <= total ? ++_i : --_i) {
+ tasks.push(function(complete) {
+ return complete();
+ });
+ }
+ assert.equal(0, tasks.completed, 'no tasks should have started yet');
+ tasks.sync();
+ return wait(5000, function() {
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
+ assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
+ assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
+ assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
+ return done();
+ });
+ });
+ return it('should work when running ten thousand tasks asynchronously', function(done) {
+ var finished, i, tasks, total, _i;
+ finished = false;
+ total = 10000;
+ tasks = new balUtil.Group(function(err) {
+ if (err) {
+ return done(err);
+ }
+ assert.equal(false, finished, 'the group of tasks only finished once');
+ return finished = true;
+ });
+ for (i = _i = 0; 0 <= total ? _i < total : _i > total; i = 0 <= total ? ++_i : --_i) {
+ tasks.push(function(complete) {
+ return setTimeout(complete, 50);
+ });
+ }
+ assert.equal(0, tasks.completed, 'no tasks should have started yet');
+ tasks.async();
+ return wait(5000, function() {
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran ' + ("" + tasks.completed + "/" + total));
+ assert.equal(false, tasks.isRunning(), 'isRunning() returned false');
+ assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true');
+ assert.equal(true, tasks.hasExited(), 'hasExited() returned true');
+ return done();
+ });
+ });
});
}).call(this);
4 package.json
View
@@ -1,6 +1,6 @@
{
"name": "bal-util",
- "version": "1.11.0",
+ "version": "1.11.1",
"description": "Common utility functions for Node.js used and maintained by Benjamin Lupton",
"homepage": "https://github.com/balupton/bal-util",
"keywords": [
@@ -50,7 +50,7 @@
"lib": "./out/lib"
},
"scripts": {
- "test": "node ./out/test/everything.test.js --joe-reporter=list"
+ "test": "node ./out/test/everything.test.js --joe-reporter=console"
},
"main": "./out/lib/balutil"
}
128 src/lib/flow.coffee
View
@@ -234,13 +234,20 @@ balUtilFlow.Group = class
@exited = value if value?
return @exited is true
+ # Log an error
+ logError: (err) ->
+ # Only push the error if we haven't already added it
+ if @errors[@errors.length-1] isnt err
+ @errors.push(err)
+ # Chain
+ @
+
# A task has completed
complete: (args...) ->
# Push the result
err = args[0] or undefined
- # console.log(err) if err
@lastResult = args
- @errors.push(err) if err
+ @logError(err) if err
@results.push(args)
# We are one less running task
@@ -249,7 +256,7 @@ balUtilFlow.Group = class
# Check if we have already completed
if @hasExited()
- # if so, do nothing
+ # do nothing
# Otherwise
else
@@ -276,6 +283,9 @@ balUtilFlow.Group = class
# The group has finished
exit: (err=null) ->
+ # Push the error if we were passed one
+ @logError(err) if err
+
# Check if we have already exited, if so, ignore
if @hasExited()
# do nothing
@@ -284,10 +294,18 @@ balUtilFlow.Group = class
else
# Fetch the results
lastResult = @lastResult
- errors = if @errors.length isnt 0 then @errors else null
- errors = errors[0] if @errors.length is 1
results = @results
+ # If have multiple errors, return an array
+ # If we have one error, return that error
+ # If we have no errors, retur null
+ if @errors.length is 0
+ errors = null
+ else if @errors.length is 1
+ errors = @errors[0]
+ else
+ errors = @errors
+
# Clear, and exit with the results
if @autoClear
@clear()
@@ -311,40 +329,22 @@ balUtilFlow.Group = class
# Add the task and increment the count
++@total
- # Bind
- if args.length is 2
- context = args[0]
- _task = args[1]
- task = (complete) ->
- balUtilFlow.fireWithOptionalCallback(_task,[complete],context)
- else
- task = args[0]
-
# Queue
- @queue.push(task)
+ @queue.push(args)
# Chain
@
# Push and run
pushAndRun: (args...) ->
- # Bind
- if args.length is 2
- context = args[0]
- _task = args[1]
- task = (complete) ->
- balUtilFlow.fireWithOptionalCallback(_task,[complete],context)
- else
- task = args[0]
-
# Check if we are currently running in sync mode
if @mode is 'sync' and @isRunning()
# push the task for later
- @push(task)
+ @push(args...)
else
# run the task now
++@total
- @runTask(task)
+ @runTask(args)
# Chain
@
@@ -369,7 +369,18 @@ balUtilFlow.Group = class
run = ->
++me.running
complete = me.completer()
- balUtilFlow.fireWithOptionalCallback(task,[complete])
+ if balUtilFlow.isArray(task)
+ if task.length is 2
+ _context = task[0]
+ _task = task[1]
+ else if task.length is 1
+ _task = task[0]
+ _context = null
+ else
+ throw new Error('balUtilFlow.Group an invalid task was pushed')
+ else
+ _task = task
+ balUtilFlow.fireWithOptionalCallback(_task,[complete],_context)
# Fire with an immediate timeout for async loads, and every hundredth sync task, except for the first
# otherwise if we are under a stressful load node will crash with
@@ -426,47 +437,53 @@ balUtilFlow.Block = class extends balUtilFlow.Group
# Create a new block and run it
# fn(block.block, block.task, block.exit)
- constructor: (name, initFunction, parentBlock) ->
+ # complete(err)
+ constructor: (opts) ->
# Prepare
block = @
+ {name, fn, parentBlock, complete} = opts
- # Apply
- super (err) ->
- block.blockAfter(block,err)
- block.parentBlock?.complete(err)
+ # Apply options
block.blockName = name
block.parentBlock = parentBlock if parentBlock?
block.mode = 'sync'
- block.initFunction = initFunction
+ block.fn = fn
+
+ # Create group
+ super (err) ->
+ block.blockAfter(block,err)
+ complete?(err)
# Event
block.blockBefore(block)
- # If we have an initFunction
- if block.initFunction?
- # If our initFunction has a completion callback
+ # If we have an fn
+ if block.fn?
+ # If our fn has a completion callback
# then set the total tasks to infinity
# so we wait for the competion callback instead of completeling automatically
- if block.initFunction.length is 3
+ if block.fn.length is 3
block.total = Infinity
# Fire the init function
try
- block.initFunction(
+ block.fn(
+ # Create sub block
(name,fn) -> block.block(name,fn)
+ # Create sub task
(name,fn) -> block.task(name,fn)
+ # Complete
(err) -> block.exit(err)
)
+
+ # If our fn completion callback is synchronous
+ # then fire our tasks right away
+ if block.fn.length isnt 3
+ block.run()
catch err
block.exit(err)
-
- # If our initFunction completion callback
- # then fire our tasks right away
- if block.initFunction.length isnt 3
- block.run()
-
else
- # We don't have an initFunction
+ # We don't have an fn
# So lets set our total tasks to infinity
block.total = Infinity
@@ -478,29 +495,30 @@ balUtilFlow.Block = class extends balUtilFlow.Group
block: (name,fn) ->
# Push the creation of our subBlock to our block's queue
block = @
- push = (complete) ->
+ pushBlock = (fn) ->
if block.total is Infinity
- block.pushAndRun(complete)
+ block.pushAndRun(fn)
else
- block.push(complete)
- push ->
- subBlock = block.createSubBlock(name,fn,block)
+ block.push(fn)
+ pushBlock (complete) ->
+ subBlock = block.createSubBlock({name,fn,complete})
@
# Create a sub block
- createSubBlock: (name,fn,parentBlock) ->
- new balUtilFlow.Block(name,fn,parentBlock)
+ createSubBlock: (opts) ->
+ opts.parentBlock = @
+ new balUtilFlow.Block(opts)
# Create a task for our current block
# fn(complete)
task: (name,fn) ->
# Prepare
block = @
- pushTask = (complete) ->
+ pushTask = (fn) ->
if block.total is Infinity
- block.pushAndRun(complete)
+ block.pushAndRun(fn)
else
- block.push(complete)
+ block.push(fn)
# Push the task to the correct place
pushTask (complete) ->
167 src/test/flow.test.coffee
View
@@ -53,12 +53,13 @@ joe.describe 'Group', (describe,it) ->
firstTaskFinished = false
secondTaskFinished = false
finished = false
+ total = 2
# Create our group
tasks = new balUtil.Group (err) ->
+ return done(err) if err
assert.equal(false, finished, 'the group of tasks only finished once')
finished = true
- assert.equal(false, err?, 'no error is present')
tasks.total = 2
# Make the first task finish after the second task
@@ -78,7 +79,7 @@ joe.describe 'Group', (describe,it) ->
# Check all tasks ran
wait 2000, ->
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran')
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
@@ -92,12 +93,13 @@ joe.describe 'Group', (describe,it) ->
firstTaskFinished = false
secondTaskFinished = false
finished = false
+ total = 2
# Create our group
tasks = new balUtil.Group (err) ->
+ return done(err) if err
assert.equal(false, finished, 'the group of tasks only finished once')
finished = true
- assert.equal(false, err?, 'no error is present')
# Make the first task take longer than the second task, but as we run synchronously, it should still finish first
tasks.push (complete) ->
@@ -126,7 +128,7 @@ joe.describe 'Group', (describe,it) ->
# Check all tasks ran
wait 2000, ->
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran')
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
@@ -140,12 +142,13 @@ joe.describe 'Group', (describe,it) ->
firstTaskFinished = false
secondTaskFinished = false
finished = false
+ total = 2
# Create our group
tasks = new balUtil.Group (err) ->
+ return done(err) if err
assert.equal(false, finished, 'the group of tasks only finished once')
finished = true
- assert.equal(false, err?, 'no error is present')
# Make the first task take longer than the second task, and as we run asynchronously, it should finish last
tasks.push (complete) ->
@@ -174,7 +177,7 @@ joe.describe 'Group', (describe,it) ->
# Check all tasks ran
wait 2000, ->
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran')
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
@@ -189,12 +192,13 @@ joe.describe 'Group', (describe,it) ->
firstTaskFinished = false
secondTaskFinished = false
finished = false
+ total = 1
# Create our group
tasks = new balUtil.Group (err) ->
+ assert.equal(true, err != null, 'an error is present');
assert.equal(false, finished, 'the group of tasks only finished once')
finished = true
- assert.equal(true, err?, 'an error is present')
# Make the first task take longer than the second task, but as we run synchronously, it should still finish first
tasks.push (complete) ->
@@ -223,7 +227,7 @@ joe.describe 'Group', (describe,it) ->
# Check all tasks ran
wait 2000, ->
- assert.equal(1, tasks.completed, 'only the expected number of tasks ran')
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
assert.equal(false, tasks.hasCompleted(), 'hasCompleted() returned true')
assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
@@ -232,14 +236,14 @@ joe.describe 'Group', (describe,it) ->
it 'should work with optional completion callbacks', (done) ->
# Prepare
- total = 2
finished = false
+ total = 2
# Create our group
tasks = new balUtil.Group (err) ->
+ return done(err) if err
assert.equal(false, finished, 'the group of tasks only finished once')
finished = true
- assert.equal(false, err?, 'no error is present')
# Add the first task
tasks.push (done) -> done()
@@ -263,14 +267,14 @@ joe.describe 'Group', (describe,it) ->
it 'should work when specifying contexts', (done) ->
# Prepare
- total = 2
finished = false
+ total = 2
# Create our group
tasks = new balUtil.Group (err) ->
+ return done(err) if err
assert.equal(false, finished, 'the group of tasks only finished once')
finished = true
- assert.equal(false, err?, 'no error is present')
# Add the first task
tasks.push {blah:1}, ->
@@ -295,67 +299,6 @@ joe.describe 'Group', (describe,it) ->
done()
- it 'should work when running ten thousand tasks synchronously', (done) ->
- # Prepare
- total = 10000
- finished = false
-
- # Create our group
- tasks = new balUtil.Group (err) ->
- assert.equal(false, finished, 'the group of tasks only finished once')
- finished = true
- assert.equal(false, err?, 'no error is present')
-
- # Add the tasks
- for i in [0...total]
- tasks.push (complete) ->
- complete()
-
- # Check no tasks have run
- assert.equal(0, tasks.completed, 'no tasks should have started yet')
-
- # Run the tasks
- tasks.sync()
-
- # Check all tasks ran
- wait 5000, ->
- assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
- assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
- assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
- assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
- done()
-
-
- it 'should work when running ten thousand tasks asynchronously', (done) ->
- # Prepare
- total = 10000
- finished = false
-
- # Create our group
- tasks = new balUtil.Group (err) ->
- assert.equal(false, finished, 'the group of tasks only finished once')
- finished = true
- assert.equal(false, err?, 'no error is present')
-
- # Add the tasks
- for i in [0...total]
- tasks.push (complete) ->
- setTimeout(complete,50)
-
- # Check no tasks have run
- assert.equal(0, tasks.completed, 'no tasks should have started yet')
-
- # Run the tasks
- tasks.async()
-
- # Check all tasks ran
- wait 5000, ->
- assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
- assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
- assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
- assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
- done()
-
it 'should push and run synchronous tasks correctly', (done) ->
# Prepare
@@ -364,12 +307,13 @@ joe.describe 'Group', (describe,it) ->
firstTaskFinished = false
secondTaskFinished = false
finished = false
+ total = 2
# Create our group
tasks = new balUtil.Group 'sync', (err) ->
+ return done(err) if err
assert.equal(false, finished, 'the group of tasks only finished once')
finished = true
- assert.equal(false, err?, 'no error is present')
assert.equal('sync', tasks.mode, 'mode was correctly set to sync')
# Make the first task take longer than the second task, but as we run synchronously, it should still finish first
@@ -395,7 +339,7 @@ joe.describe 'Group', (describe,it) ->
# Check all tasks ran
wait 4000, ->
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran')
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
@@ -410,12 +354,13 @@ joe.describe 'Group', (describe,it) ->
firstTaskFinished = false
secondTaskFinished = false
finished = false
+ total = 2
# Create our group
tasks = new balUtil.Group 'async', (err) ->
+ return done(err) if err
assert.equal(false, finished, 'the group of tasks only finished once')
finished = true
- assert.equal(false, err?, 'no error is present')
assert.equal('async', tasks.mode, 'mode was correctly set to async')
# Make the first task take longer than the second task, but as we run synchronously, it should still finish first
@@ -441,7 +386,7 @@ joe.describe 'Group', (describe,it) ->
# Check all tasks ran
wait 4000, ->
- assert.equal(2, tasks.completed, 'only the expected number of tasks ran')
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
@@ -451,11 +396,12 @@ joe.describe 'Group', (describe,it) ->
it 'should push and run synchronous tasks correctly (multiple times)', (done) ->
# Prepare
finished = 0
+ total = 2
# Create our group
tasks = new balUtil.Group 'sync', {autoClear: true}, (err) ->
+ return done(err) if err
++finished
- assert.equal(false, err?, 'no error is present')
assert.equal('sync', tasks.mode, 'mode was correctly set to sync')
assert.equal(true, tasks.autoClear, 'autoClear was correctly set to true')
@@ -469,8 +415,71 @@ joe.describe 'Group', (describe,it) ->
# Check all tasks ran
wait 2000, ->
- assert.equal(2, finished, 'it exited the correct number of times')
+ assert.equal(total, finished, 'it exited the correct number of times')
assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
assert.equal(false, tasks.hasCompleted(), 'hasCompleted() returned false')
assert.equal(false, tasks.hasExited(), 'hasExited() returned false')
done()
+
+
+
+ it 'should work when running ten thousand tasks synchronously', (done) ->
+ # Prepare
+ finished = false
+ total = 10000
+
+ # Create our group
+ tasks = new balUtil.Group (err) ->
+ return done(err) if err
+ assert.equal(false, finished, 'the group of tasks only finished once')
+ finished = true
+
+ # Add the tasks
+ for i in [0...total]
+ tasks.push (complete) ->
+ complete()
+
+ # Check no tasks have run
+ assert.equal(0, tasks.completed, 'no tasks should have started yet')
+
+ # Run the tasks
+ tasks.sync()
+
+ # Check all tasks ran
+ wait 5000, ->
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
+ assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
+ assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
+ assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
+ done()
+
+
+ it 'should work when running ten thousand tasks asynchronously', (done) ->
+ # Prepare
+ finished = false
+ total = 10000
+
+ # Create our group
+ tasks = new balUtil.Group (err) ->
+ return done(err) if err
+ assert.equal(false, finished, 'the group of tasks only finished once')
+ finished = true
+
+ # Add the tasks
+ for i in [0...total]
+ tasks.push (complete) ->
+ setTimeout(complete,50)
+
+ # Check no tasks have run
+ assert.equal(0, tasks.completed, 'no tasks should have started yet')
+
+ # Run the tasks
+ tasks.async()
+
+ # Check all tasks ran
+ wait 5000, ->
+ assert.equal(total, tasks.completed, 'the expected number of tasks ran '+"#{tasks.completed}/#{total}")
+ assert.equal(false, tasks.isRunning(), 'isRunning() returned false')
+ assert.equal(true, tasks.hasCompleted(), 'hasCompleted() returned true')
+ assert.equal(true, tasks.hasExited(), 'hasExited() returned true')
+ done()

No commit comments for this range

Something went wrong with that request. Please try again.