Permalink
Browse files

Add: the ability to stack filter chains, error message when a non-fun…

…ction is added to the chain, and the ability to modify the chain after it has been created
  • Loading branch information...
1 parent 1c10968 commit 69817ee564860de067b5460a2cdde9ca93dad5eb @tmpvar committed Nov 16, 2011
Showing with 119 additions and 65 deletions.
  1. +58 −54 index.js
  2. +61 −11 test.js
View
112 index.js
@@ -1,74 +1,78 @@
(function() {
+ module.exports = {
+ createChain : function(chain, coreFn) {
+ chain = chain || [];
- function FilterChain(array, op) {
- this._chain = array;
- this._op = op;
- }
+ var chainInstance = function(data, fn) {
+ var
+ index = -1,
+ errors = [],
+ bubbles = [],
+ current,
+ capture = function(data) {
+ index++;
- FilterChain.prototype = {
- execute: function(data, fn) {
- var
- index = -1,
- op = this._op,
- that = this,
- chain = this._chain,
- errors = [],
- bubbles = [],
- capture = function(data) {
- index++;
+ if (index>=chain.length) {
+ if (coreFn) {
+ coreFn(data, function(err, data) {
+ if (err) {
+ errors.push(err);
+ }
+ // called when the core of the chain is complete
+ bubble(data);
+ });
+ } else {
+ bubble(data);
+ }
+ } else if (typeof chain[index] === 'function') {
+ chain[index](data, function next(data, bubbleFn) {
+ if (typeof bubbleFn === 'function') {
+ bubbles.push(bubbleFn);
+ } else if (bubbleFn) {
+ // handle the case where flows are being composed
+ // data is the errors
+ if (data) {
+ errors.push(err)
+ return bubble(data);
+ }
+ data = bubbleFn;
+ }
- if (index>=chain.length) {
- if (op) {
- op(data, function(err, data) {
+ capture(data)
+ }, function cancel(err, data) {
if (err) {
- errors.push(err);
+ errors.push(err)
}
- // called when the core of the chain is complete
bubble(data);
});
} else {
- bubble(data);
+ //errors.push(new Error('user error! A link in the chain was not a function'))
+ //bubble(data);
}
- } else {
- chain[index](data, function next(data, bubbleFn) {
- if (bubbleFn) {
- bubbles.push(bubbleFn);
- }
- capture(data)
- }, function cancel(err, data) {
- if (err) {
- errors.push(err)
- }
- bubble(data);
- });
- }
+ }, bubble = function(data) {
- }, bubble = function(data) {
+ if (bubbles.length < 1) {
+ fn((errors.length) ? errors : null, data);
+ } else {
+ var bubbleFn = bubbles.pop();
+ var ret = bubbleFn(data, function done(err, data) {
+ if (err) { errors.push(err); }
+ bubble(data);
+ });
- if (bubbles.length < 1) {
- fn((errors.length) ? errors : null, data);
- } else {
- var bubbleFn = bubbles.pop();
- var ret = bubbleFn(data, function done(err, data) {
- if (err) { errors.push(err); }
- bubble(data);
- });
- if (typeof ret !== 'undefined') {
- bubble(ret);
+ if (typeof ret !== 'undefined') {
+ bubble(ret);
+ }
}
- }
+ };
+
+ capture(data);
};
- this._where = 0;
- capture(data);
- }
- };
+ chainInstance.chain = chain;
- module.exports = {
- createChain : function(array, coreFn) {
- var ret = new FilterChain(array, coreFn);
- return ret;
+ return chainInstance;
}
}
View
72 test.js
@@ -1,13 +1,14 @@
var
fc = require('./'),
-equal = function(expected, actual) {
- if (expected !== actual) {
- console.log(new Error('expected "' + expected + '"; saw "' + actual + '"'));
+ok = function(a, msg) {
+ if (!a) {
+ console.log(new Error(msg));
process.exit(1);
}
-}
-
-
+},
+equal = function(expected, actual) {
+ ok(expected === actual, 'expected "' + expected + '"; saw "' + actual + '"')
+};
// Successful pre + post execution
var basic = fc.createChain([
@@ -20,7 +21,7 @@ var basic = fc.createChain([
},
]);
-basic.execute({ hello : 'world' }, function(errors, data) {
+basic({ hello : 'world' }, function(errors, data) {
equal(null, errors)
equal('pre-world-post', data.hello);
});
@@ -35,7 +36,7 @@ var bubbleReturn = fc.createChain([
}
]);
-bubbleReturn.execute('', function(errors, data) {
+bubbleReturn('', function(errors, data) {
equal(null, errors);
equal('hello world', data);
});
@@ -57,7 +58,7 @@ var cancel = fc.createChain([
}
]);
-cancel.execute('', function(errors, data) {
+cancel('', function(errors, data) {
equal('outer', data);
});
@@ -72,7 +73,56 @@ var captureBubble = fc.createChain([
fn(null, data + '-core-');
});
-captureBubble.execute('', function(errors, data) {
+captureBubble('', function(errors, data) {
equal(null, errors);
equal('capture--core--bubble', data);
-});
+});
+
+
+// Composable chains
+var inner = fc.createChain([
+ function (data, next, cancel) {
+ next(data + ' inner-capture ', function(data, done) {
+ done(null, data + ' inner-bubble ');
+ });
+ }
+], function(data, done) {
+ done(null, data+' inner-core ')
+});
+
+var outer = fc.createChain([
+ function (data, next, cancel) {
+
+ next(data + ' outer-capture ', function(data, done) {
+ done(null, data + ' outer-bubble ');
+ });
+ },
+ inner
+], function(data, done) {
+ done(null, data + ' outer-core ')
+});
+
+outer('', function(errors, data) {
+ equal(null, errors);
+ equal(' outer-capture inner-capture inner-core inner-bubble outer-core outer-bubble ', data);
+});
+
+
+// Manipulate filterchain after creation
+var afterCreation = fc.createChain();
+afterCreation.chain.push(function(data, next, cancel) {
+ next('made it');
+});
+
+afterCreation('', function(errors, data) {
+ equal(null, errors);
+ equal('made it', data);
+});
+
+// User error
+var filterNotAFunction = fc.createChain(['abc']);
+filterNotAFunction('', function(e, data) {
+ ok(e, 'should error');
+ ok(!data, 'data is nothing as it wasnt operated on');
+})
+

0 comments on commit 69817ee

Please sign in to comment.