Skip to content

Commit

Permalink
- Made jumpTo async in all cases.
Browse files Browse the repository at this point in the history
- Fixed bug that caused unwanted infinite loops.
- Added error reporting when user tries to jump to unknown function name.
- Added jumpTo unit test.
  • Loading branch information
xavi- committed Jan 22, 2013
1 parent 64fd739 commit 6504e10
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.markdown
Expand Up @@ -81,7 +81,7 @@ An optional string parameter can passed in to `this.val` as well. This string c
); );
``` ```
- **this.jumpTo(string, [argsArray])** -- allows you to jump to any named function in the current step chain - **this.jumpTo(string, [argsArray])** -- allows you to jump to any named function in the current step chain
- **this.jumpTo(function, [argsArray])** -- used to call an outside function and to exit the current step chain - **this.jumpTo(function, [argsArray])** -- exits the current step chain and asynchronously call an outside function


```javascript ```javascript
function badNews(err) { function badNews(err) {
Expand Down
19 changes: 12 additions & 7 deletions index.js
Expand Up @@ -104,19 +104,24 @@ function TwoStep() {
var data = {}; var data = {};


function jumpTo(func, args) { function jumpTo(func, args) {
this._params._used = true;

if (typeof func === 'function') { if (typeof func === 'function') {
curIdx = Number.MAX_VALUE; curIdx = Number.MAX_VALUE;
func.apply(this, args); func.apply(this, args);
} else { return;
for(var i = 0; i < steps.length; i++) { }
if(steps[i].name !== func) { continue; }


curIdx = i; for(var i = 0; i < steps.length; i++) {
if(steps[i].name !== func) { continue; }


break; curIdx = i;
}
break;
} }
nextStep.apply(null, args); if(i === steps.length) { throw Error("Unknown jumpTo location: " + func); }

process.nextTick(function() { nextStep.apply(null, args); });
} }


function nextStep(err) { function nextStep(err) {
Expand Down
16 changes: 10 additions & 6 deletions test/basic-checks.js
Expand Up @@ -2,6 +2,8 @@ var assert = require("assert");


module.exports = { module.exports = {
save: function(stepObj, args) { save: function(stepObj, args) {
stepObj.data.callSeq = stepObj.data.callSeq || [];
stepObj.data.callSeq.push(stepObj._params.name);
stepObj.data[stepObj._params.name] = { when: Date.now(), args: Array.prototype.slice.call(args) }; stepObj.data[stepObj._params.name] = { when: Date.now(), args: Array.prototype.slice.call(args) };
}, },
coverage: function(names) { coverage: function(names) {
Expand All @@ -11,12 +13,14 @@ module.exports = {
}, },
order: function(names) { order: function(names) {
return function(data) { return function(data) {
for(var i = 1; i < names.length; i++) { names.forEach(function(name) {
var nameA = names[i - 1], nameB = names[i]; assert.ok(data[name] != null, "Unknown function name: '" + name + "'");
assert.ok(data[nameA] != null, "Unknown function name: '" + nameA + "'"); });
assert.ok(data[nameB] != null, "Unknown function name: '" + nameB + "'"); assert.deepEqual(
assert.ok(data[nameA].when <= data[nameB].when, nameA + " was not called before " + nameB); data.callSeq,
} names,
"Functions were not called in order:\n\t\texpected: " + names + "\n\t\tactual: " + data.callSeq
);
}; };
}, },
emptyArgs: function(name) { emptyArgs: function(name) {
Expand Down
17 changes: 17 additions & 0 deletions test/error.js
Expand Up @@ -54,6 +54,23 @@ vows.describe("Test error handling").addBatch({
function lastErr() { throw "Last Error Thrown"; } function lastErr() { throw "Last Error Thrown"; }
); );
}, "Last Error Thrown"); }, "Last Error Thrown");
},
"error thrown when jumpTo non-existant location": function(TwoStep) {
assert.throws(function() {
TwoStep(
function first() { this.jumpTo("no-where"); }
);
}, "Error thrown when trying to jumpTo unknow function name.");
assert.throws(function() {
TwoStep(
function first() { this.jumpTo(5); }
);
}, "Error thrown when trying to jumpTo unknow function index.");
assert.throws(function() {
TwoStep(
function first() { this.jumpTo(null); }
);
}, "Error thrown when trying to jumpTo unknow function.");
} }
} }
}).export(module); }).export(module);
39 changes: 38 additions & 1 deletion test/jumpTo.js
Expand Up @@ -4,7 +4,7 @@ var TwoStep = require("../");
var check = require("./basic-checks"); var check = require("./basic-checks");


vows.describe("Test `this.val`").addBatch({ vows.describe("Test `this.val`").addBatch({
"basic test passing one param": { "basic test passing function name and one param": {
topic: function() { topic: function() {
TwoStep( TwoStep(
function start(err) { function start(err) {
Expand Down Expand Up @@ -32,6 +32,43 @@ vows.describe("Test `this.val`").addBatch({
assert.equal(data["last"].args[1], "hello", "The incorrect arguments were sent"); assert.equal(data["last"].args[1], "hello", "The incorrect arguments were sent");
} }
}, },
"test that step chain continues once a jumpTo is executed": {
topic: function() {
TwoStep(
function first(err) {
check.save(this, arguments);
this.jumpTo("fourth", [ err, "go to fourth" ]);
},
function second(err) {
check.save(this, arguments);
this.syncVal("foo")
},
function third(err) {
check.save(this, arguments);
this.jumpTo("fifth", [ err, "go to fifth" ]);
},
function fourth(err) {
check.save(this, arguments);
this.jumpTo("second", [ err, "go to second" ]);
},
function fifth(err) {
check.save(this, arguments);
this.syncVal(this.data);
},
this.callback
);
},
"no args to first callback": check.emptyArgs("first"),
"correct callbacks were called": check.coverage([ "first", "second", "third", "fourth", "fifth" ]),
"callbacks executed in order": check.order([ "first", "fourth", "second", "third", "fifth" ]),
"check arguments of recieving function": function(data) {
assert.ok(!data["second"].args[0], "The error argument was incorrectly set");
assert.equal(data["second"].args[1], "go to second", "The incorrect arguments were sent");
assert.equal(data["third"].args[1], "foo", "The incorrect arguments were sent");
assert.equal(data["fourth"].args[1], "go to fourth", "The incorrect arguments were sent");
assert.equal(data["fifth"].args[1], "go to fifth", "The incorrect arguments were sent");
}
},
"bail out if a function was specified": { "bail out if a function was specified": {
topic: function() { topic: function() {
var callback = this.callback; var callback = this.callback;
Expand Down

0 comments on commit 6504e10

Please sign in to comment.