Comparing version 1.0.0 to 2.0.0
73
index.js
@@ -1,4 +0,36 @@ | ||
module.exports = function(predicate, trueFn, falseFn) { | ||
var util = require('util') | ||
var OK = 0 | ||
var THEN = 1 | ||
module.exports = function() { | ||
var clauses = Array.prototype.slice.call(arguments, 0) | ||
var elseClause = elseNoop | ||
var fluentState = OK | ||
if (clauses.length === 0) { | ||
throw new Error('at least one predicate and one consequent are required') | ||
} | ||
// using fluent interface, we expect the user will call then() before invoking the functor | ||
if (clauses.length === 1) { | ||
fluentState = THEN | ||
} else if (clauses.length % 2 === 1) { | ||
elseClause = clauses.pop() | ||
} | ||
var functor = function(callback) { | ||
if (fluentState !== OK) { | ||
throw new Error('missing at least one consequent, you forgot to call then() ?') | ||
} | ||
var predicate = clauses.shift() | ||
if (!predicate) { | ||
return elseClause(callback) | ||
} | ||
var consequent = clauses.shift() | ||
predicate(function(err, result) { | ||
@@ -8,5 +40,5 @@ if (err) return callback(err) | ||
if (result) { | ||
return trueFn(callback) | ||
return consequent(callback) | ||
} else { | ||
return falseFn(callback) | ||
functor(callback) | ||
} | ||
@@ -16,13 +48,34 @@ }) | ||
functor.then = function (fn) { | ||
trueFn = fn | ||
return this | ||
functor.then = function(fn) { | ||
fluentState = OK | ||
clauses.push(fn) | ||
return functor | ||
} | ||
functor.else = function (fn) { | ||
falseFn = fn | ||
return this | ||
functor.else = function(fn) { | ||
if (fluentState === THEN) { | ||
throw new Error('only then() may be called after elseIf()') | ||
} | ||
elseClause = fn | ||
return functor | ||
} | ||
return functor | ||
functor.elseif = functor.elseIf = function(fn) { | ||
if (fluentState === THEN) { | ||
throw new Error('only then() may be called after elseIf()') | ||
} | ||
clauses.push(fn) | ||
// allow only then after a call to elseif | ||
fluentState = THEN | ||
return functor | ||
} | ||
return functor | ||
} | ||
function elseNoop(callback) { | ||
setImmediate(callback) | ||
} |
{ | ||
"name": "if-async", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"keywords": [ | ||
@@ -5,0 +5,0 @@ "async" |
# if-async | ||
async conditional execution for standalone or async.js use | ||
### Example 1: Using with Async.js | ||
```javascript | ||
@@ -10,5 +12,3 @@ var async = require('async') | ||
foo, | ||
ifAsync(predicateFoo, trueFoo, falseFoo), | ||
// this also | ||
ifAsync(predicateFoo).then(trueFoo).else(falseFoo) | ||
ifAsync(predicate1).then(consequent1).else(else1), | ||
bar | ||
@@ -18,6 +18,33 @@ ]) | ||
function foo(callback) { ... } | ||
function predicateFoo(callback) { callback(null, true) } | ||
function trueFoo(callback) { ... } | ||
function falseFoo(callback) { ... } | ||
function predicate1(callback) { fs.stat(... callback ...) } | ||
function consequent1(callback) { ... } | ||
function else1(callback) { ... } | ||
function bar(callback) { ... } | ||
``` | ||
``` | ||
### Example 2: Standalone usage | ||
```javascript | ||
var ifAsync = require('if-async') | ||
var functor = ifAsync(predicate).then(consequent).else(elseClause) | ||
functor(function(err) { | ||
console.log('done') | ||
}) | ||
function predicate(callback) { fs.stat(... callback ...) } | ||
function consequent(callback) { ... } | ||
function elseClause(callback) { ... } | ||
``` | ||
### API Reference | ||
#### Using fluent interface | ||
var functor = ifAsync(predicate1).then(consequent1).elseIf(predicate2).then(consequent2).else(defaultConsequent) | ||
#### Using function arguments | ||
var functor = ifAsync(predicate1, consequent1, predicate2, consequent2, defaultConsequent) |
176
test.js
var ifAsync = require('./index.js') | ||
var should = require('should') | ||
describe('async if', function() { | ||
it('use the first function as predicate', function (done) { | ||
ifAsync(function(callback) { | ||
describe('ifAsync', function() { | ||
it('requires at least one predicate', function () { | ||
(function () { | ||
ifAsync() | ||
}).should.throw('at least one predicate and one consequent are required') | ||
}) | ||
it('throws an error if at least one consequent is not provided', function () { | ||
(function () { | ||
ifAsync(function (callback) { callback(null, true) })(function () { | ||
}) | ||
}).should.throw('missing at least one consequent, you forgot to call then() ?') | ||
}) | ||
it('invokes the predicate', function (done) { | ||
var predicateInvoked = false | ||
var functor = ifAsync( | ||
function predicate(callback) { | ||
predicateInvoked = true | ||
callback(null, 1) | ||
}, | ||
function consequent(callback) { | ||
callback() | ||
} | ||
) | ||
functor(function callback(err) { | ||
predicateInvoked.should.be.true | ||
done() | ||
})() | ||
}) | ||
}) | ||
it('calls the second function if predicate calls back with a value that does not evaluate to false', function (done) { | ||
ifAsync(function (callback) { | ||
callback(null, 1) | ||
}, done)() | ||
it('invokes the consequent if the predicate evaluates to "true"', function (done) { | ||
var consequentInvoked = false | ||
var functor = ifAsync( | ||
function predicate(callback) { | ||
callback(null, 1) | ||
}, | ||
function consequent(callback) { | ||
consequentInvoked = true | ||
callback() | ||
} | ||
) | ||
functor(function callback(err) { | ||
consequentInvoked.should.be.true | ||
done() | ||
}) | ||
}) | ||
it('calls the third function if predicate calls back with a value that evaluates to false', function (done) { | ||
ifAsync(function (callback) { | ||
callback(null, 0) | ||
}, undefined, done)() | ||
it('invokes the default consequent if predicate evaluates to "false"', function (done) { | ||
var consequentInvoked = false | ||
var defaultConsequentInvoked = false | ||
var functor = ifAsync( | ||
function predicate(callback) { | ||
callback(null, 0) | ||
}, | ||
function consequent(callback) { | ||
consequentInvoked = true | ||
callback() | ||
}, | ||
function defaultConsequent(callback) { | ||
defaultConsequentInvoked = true | ||
callback() | ||
} | ||
) | ||
functor(function callback(err) { | ||
consequentInvoked.should.be.false | ||
defaultConsequentInvoked.should.be.true | ||
done() | ||
}) | ||
}) | ||
it('calls back with an error from the predicate', function (done) { | ||
ifAsync(function (callback) { | ||
callback(new Error()) | ||
})(function (err) { | ||
err.should.be.an.Error | ||
it('invokes a second predicate if it is provided when the first predicate does not evaluate to true', function (done) { | ||
var p1Invoked = false | ||
var p2Invoked = false | ||
var c1Invoked = false | ||
var c2Invoked = false | ||
var functor = ifAsync( | ||
function predicate1(callback) { | ||
p1Invoked = true | ||
callback(null, 0) | ||
}, | ||
function consequent1(callback) { | ||
c1Invoked = true | ||
callback() | ||
}, | ||
function predicate2(callback) { | ||
p2Invoked = true | ||
callback(null, 1) | ||
}, | ||
function consequent2(callback) { | ||
c2Invoked = true | ||
callback() | ||
} | ||
) | ||
functor(function (err) { | ||
p1Invoked.should.be.true | ||
c1Invoked.should.be.false | ||
p2Invoked.should.be.true | ||
c2Invoked.should.be.true | ||
done() | ||
@@ -32,18 +116,52 @@ }) | ||
it('hands the callback supplied by the caller to the action functions', function (done) { | ||
ifAsync(function (callback) { | ||
callback(null, true) | ||
}, function(callback) { | ||
callback.should.eql(done) | ||
it('has fluent interface', function (done) { | ||
var p1Invoked = false | ||
var p2Invoked = false | ||
var c1Invoked = false | ||
var c2Invoked = false | ||
var functor = ifAsync(function predicate1(callback) { | ||
p1Invoked = true | ||
callback(null, 0) | ||
}) | ||
.then(function consequent1(callback) { | ||
c1Invoked = true | ||
callback() | ||
})(done) | ||
}) | ||
}) | ||
.elseIf(function predicate2(callback) { | ||
p2Invoked = true | ||
callback(null, 1) | ||
}) | ||
.then(function consequent2(callback) { | ||
c2Invoked = true | ||
callback() | ||
}) | ||
it('exposes fluent interface', function (done) { | ||
ifAsync(function(callback) { | ||
callback(null, true) | ||
}).then(function(callback) { | ||
functor(function (err) { | ||
p1Invoked.should.be.true | ||
c1Invoked.should.be.false | ||
p2Invoked.should.be.true | ||
c2Invoked.should.be.true | ||
done() | ||
})() | ||
}) | ||
}) | ||
it('cannot call elseIf() after elseIf()', function () { | ||
(function () { | ||
ifAsync(pFalse).then(foo).elseIf(pFalse).elseIf(pFalse) | ||
}).should.throw('only then() may be called after elseIf()') | ||
}) | ||
function pTrue (callback) { | ||
callback(null, true) | ||
} | ||
function pFalse (callback) { | ||
callback(null, false) | ||
} | ||
function foo (callback) { | ||
callback() | ||
} | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8176
201
48
1