async-if-else
Advanced tools
Comparing version 1.0.2 to 1.1.0
55
index.js
@@ -6,37 +6,46 @@ | ||
function extend(async) { | ||
async.if = ifFn; | ||
async.if = builder(ifCheck); | ||
async.ifNot = async.unless = builder(ifNotCheck); | ||
return async; | ||
} | ||
function ifFn(predicate, ifStatement) { | ||
var elseStatement = nopStatement; | ||
function builder(predicateChecker) { | ||
return function ifFn(predicate, ifStatement) { | ||
var elseStatement = nopStatement; | ||
function wrapper() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var asyncCallback = args[args.length - 1 ]; | ||
var predicateArgs = args.slice(0, -1).concat(predicateCb); | ||
function wrapper() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var asyncCallback = args[args.length - 1 ]; | ||
var predicateArgs = args.slice(0, -1).concat(predicateCb); | ||
predicate.apply(null, predicateArgs); | ||
predicate.apply(null, predicateArgs); | ||
function predicateCb(valid, value) { | ||
var applyArguments = args; | ||
function predicateCb(error, valid) { | ||
if (error) | ||
return asyncCallback(error); | ||
if (value) | ||
applyArguments = [ value, asyncCallback ]; | ||
if (predicateChecker(valid)) | ||
ifStatement.apply(null, args); | ||
else | ||
elseStatement.apply(null, args); | ||
} | ||
} | ||
wrapper.else = function(statement) { | ||
elseStatement = statement; | ||
return wrapper; | ||
}; | ||
if (valid) | ||
ifStatement.apply(null, applyArguments); | ||
else | ||
elseStatement.apply(null, applyArguments); | ||
} | ||
} | ||
wrapper.else = function(statement) { | ||
elseStatement = statement; | ||
return wrapper; | ||
}; | ||
} | ||
return wrapper; | ||
function ifCheck(value) { | ||
return value; | ||
} | ||
function ifNotCheck(value) { | ||
return !value; | ||
} | ||
function nopStatement() { | ||
@@ -47,3 +56,1 @@ var args = Array.prototype.slice.call(arguments); | ||
} | ||
{ | ||
"name": "async-if-else", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "'conditional if to async control flow'", | ||
@@ -5,0 +5,0 @@ "repository": { |
# async-if-else | ||
node famous async conditional capabilities | ||
easy way to create conditions on your async waterfall flow | ||
This module adds if else conditional capabilities to [async](https://www.npmjs.com/package/async) module. | ||
Ever came across code like this on your `async.waterfall` flow? | ||
```javascript | ||
var async = require('async'); | ||
var require('async-if-else').extend(async); | ||
async.waterfall([ | ||
async.constant({email: 'thiago@email.com', dogs: 2, money: 0, fun: 100 }), | ||
async.if(emailExists, updateAccount).else(importFromLegacyByEmail), | ||
updateUserEmailOrGetLegacy, | ||
sendEmail | ||
], handler); | ||
function updateUserEmailOrGetLegacy(user, cb) { | ||
emailExists(user.email, function (err, value) { | ||
if (err) | ||
callback(err) | ||
else { | ||
if (user.email) | ||
updateAccount(user, cb); | ||
else | ||
importFromLegacyByEmail(user, cb) | ||
} | ||
}) | ||
} | ||
``` | ||
what about if without else ? | ||
Using `async-if-else` you can have a conditional waterfall without the need of a wrapper function. | ||
And the code is so much more readable, don't you agree? | ||
```javascript | ||
var async = require('async'); | ||
var require('async-if-else').extend(async); | ||
var async = require('async-if-else')(require('async')); | ||
async.waterfall([ | ||
async.constant({email: 'thiago@email.com', dogs: 2, money: 0, fun: 100 }), | ||
async.if(emailExists, updateAccount).else(importFromLegacyByEmail), | ||
sendEmail | ||
], handler); | ||
``` | ||
You can also omit the `else` and the function is only executed if the predicate is true. | ||
```javascript | ||
var async = require('async-if-else')(require('async')); | ||
async.waterfall([ | ||
async.constant({email: 'thiago@email.com', dogs: 2, money: 0, fun: 100 }), | ||
async.if(emailExists, auditLogging), | ||
publishToQueue | ||
], handler); | ||
``` | ||
if you don't want to change the async object, you can always do something like that | ||
```javascript | ||
var async = require('async'); | ||
var conditional = require('async-if-else')({}); | ||
async.waterfall([ | ||
async.constant({email: 'thiago@email.com', dogs: 2, money: 0, fun: 100 }), | ||
conditional.if(emailExists, auditLogging), | ||
publishToQueue | ||
], handler); | ||
``` | ||
#### Hey, if you found a BUG ! | ||
Amazing ! PR are always welcome | ||
#### Hey, did you found an issue? | ||
Let's make the world a better place helping others :) | ||
The best way to get in touch is using the [GitHub issues section](https://github.com/tdantas/async-if-else/issues). | ||
If you can't find someone with the problem you are facing open a [new issue](https://github.com/tdantas/async-if-else/issues/new) and let me know. | ||
If you manage to find a solution for your problem, you can submit a new [PR](https://github.com/tdantas/async-if-else/pulls) :) | ||
Let's make the world a better place by helping others. | ||
# License | ||
[MIT](https://github.com/tdantas/async-if-else/blob/master/LICENSE) |
94
test.js
@@ -6,7 +6,7 @@ var test = require('tape'); | ||
function containsNameSync(payload, validated) { | ||
validated(payload.name === 'thiago'); | ||
validated(null, payload.name === 'thiago'); | ||
} | ||
function containsName(payload, validated) { | ||
setImmediate(validated, payload.name === 'thiago'); | ||
setImmediate(validated, null, payload.name === 'thiago'); | ||
} | ||
@@ -61,3 +61,3 @@ | ||
function notContainsName(payload, validated) { | ||
validated(payload.name === undefined); | ||
validated(null, payload.name === undefined); | ||
} | ||
@@ -96,3 +96,3 @@ | ||
function validateAddressAndName(payload, country, validated) { | ||
validated(payload.name === 'thiago' && country.city === 'lisbon'); | ||
validated(null, payload.name === 'thiago' && country.city === 'lisbon'); | ||
} | ||
@@ -121,3 +121,3 @@ | ||
function forceFail(payload, country, validated) { | ||
validated(false); | ||
validated(null, false); | ||
} | ||
@@ -147,3 +147,3 @@ | ||
function truthyValidation(payload, validated) { | ||
setImmediate(validated, true); | ||
setImmediate(validated, null, true); | ||
} | ||
@@ -178,3 +178,3 @@ | ||
function falsyValidation(payload, validated) { | ||
validated(false); | ||
validated(null, false); | ||
} | ||
@@ -244,17 +244,20 @@ | ||
function changeValidation(payload, validated) { | ||
validated(true, { name: payload.name, age: 30 }); | ||
function validationThrowError(payload, validated) { | ||
var error = new Error('validate-error'); | ||
validated(error); | ||
} | ||
test('predicate function could change the value passed to if statement', function(t){ | ||
test('predicated returns an error the async callback must be called with error', function(t) { | ||
async.waterfall([ | ||
async.constant({name: 'thiago'}), | ||
async.if(changeValidation, createAccount), | ||
async.if(validationThrowError, createAccount).else(notifyAdminASync), | ||
function willNotBeCalled(payload, callback) { | ||
payload.next = true; | ||
callback(null, payload); | ||
} | ||
], verify); | ||
function verify(err, result) { | ||
t.notOk(err, 'there is no error'); | ||
t.equal(result.name, 'thiago', 'payload name is the same as initial'); | ||
t.ok(result.id, 'id must exist'); | ||
t.equal(result.age, 30, 'validate added new field'); | ||
t.ok(err, 'error must be here'); | ||
t.notOk(result, 'must not exist'); | ||
t.end(); | ||
@@ -264,18 +267,53 @@ } | ||
function changeFalseValidation(payload, validated) { | ||
validated(false, { valid: false }); | ||
} | ||
test('ifNot is the same as unless', function(t) { | ||
t.equal(async.ifNot, async.unless); | ||
t.end(); | ||
}); | ||
test('predicate function could change the value passed to else statement', function(t){ | ||
async.waterfall([ | ||
async.constant({name: 'thiago'}), | ||
async.if(changeFalseValidation, nop).else(notifyAdminASync), | ||
], verify); | ||
['ifNot', 'unless'].forEach(function(method) { | ||
function verify(err, result) { | ||
t.notOk(err, 'there is no error'); | ||
t.notOk(result.name, 'must not exist'); | ||
t.notOk(result.valid, 'must be false'); | ||
t.end(); | ||
function girls(payload, validated) { | ||
validated(null, payload.gender === 'female'); | ||
} | ||
function notAllowed(payload, callback) { | ||
payload.allowed = false; | ||
callback(null, payload); | ||
} | ||
function allowed(payload, callback) { | ||
payload.allowed = true; | ||
callback(null, payload); | ||
} | ||
test(method + ' works as expected', function(t) { | ||
async.waterfall([ | ||
async.constant({name: 'thiago', gender: 'male'}), | ||
async[method](girls, notAllowed).else(allowed) | ||
], verify); | ||
function verify(err, result) { | ||
t.notOk(err, 'there is no error'); | ||
t.equal(result.allowed, false, 'must be equals'); | ||
t.end(); | ||
} | ||
}); | ||
function men(payload, validated) { | ||
validated(null, payload.gender === 'male'); | ||
} | ||
test(method + ' works as expected', function(t) { | ||
async.waterfall([ | ||
async.constant({name: 'thiago', gender: 'male'}), | ||
async[method](men, notAllowed).else(allowed) | ||
], verify); | ||
function verify(err, result) { | ||
t.notOk(err, 'there is no error'); | ||
t.equal(result.allowed, true, 'must be equals'); | ||
t.end(); | ||
} | ||
}); | ||
}); |
13765
302
78