Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

- Made `jumpTo` async in all cases.

- 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...
commit 6504e10eba890a2a255244b75f0717f48cc33b6a 1 parent 64fd739
@xavi- authored
View
2  README.markdown
@@ -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(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
function badNews(err) {
View
19 index.js
@@ -104,19 +104,24 @@ function TwoStep() {
var data = {};
function jumpTo(func, args) {
+ this._params._used = true;
+
if (typeof func === 'function') {
curIdx = Number.MAX_VALUE;
func.apply(this, args);
- } else {
- for(var i = 0; i < steps.length; i++) {
- if(steps[i].name !== func) { continue; }
+ return;
+ }
- 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) {
View
16 test/basic-checks.js
@@ -2,6 +2,8 @@ var assert = require("assert");
module.exports = {
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) };
},
coverage: function(names) {
@@ -11,12 +13,14 @@ module.exports = {
},
order: function(names) {
return function(data) {
- for(var i = 1; i < names.length; i++) {
- var nameA = names[i - 1], nameB = names[i];
- assert.ok(data[nameA] != null, "Unknown function name: '" + nameA + "'");
- assert.ok(data[nameB] != null, "Unknown function name: '" + nameB + "'");
- assert.ok(data[nameA].when <= data[nameB].when, nameA + " was not called before " + nameB);
- }
+ names.forEach(function(name) {
+ assert.ok(data[name] != null, "Unknown function name: '" + name + "'");
+ });
+ assert.deepEqual(
+ data.callSeq,
+ names,
+ "Functions were not called in order:\n\t\texpected: " + names + "\n\t\tactual: " + data.callSeq
+ );
};
},
emptyArgs: function(name) {
View
17 test/error.js
@@ -54,6 +54,23 @@ vows.describe("Test error handling").addBatch({
function lastErr() { throw "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);
View
39 test/jumpTo.js
@@ -4,7 +4,7 @@ var TwoStep = require("../");
var check = require("./basic-checks");
vows.describe("Test `this.val`").addBatch({
- "basic test passing one param": {
+ "basic test passing function name and one param": {
topic: function() {
TwoStep(
function start(err) {
@@ -32,6 +32,43 @@ vows.describe("Test `this.val`").addBatch({
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": {
topic: function() {
var callback = this.callback;
Please sign in to comment.
Something went wrong with that request. Please try again.