UNPKG

fa

Version:

fluent async: functional programming support for asynchronous functions.

320 lines (277 loc) 7.67 kB
fa = if window? then require('fa') else require "#{__dirname}/../lib/fa" suite "fa suite", {serial: false, stopOnFail: true} timeoutFor = (args) -> return (x, cb) -> throw new Error("x is undefined") if x==undefined setTimeout (() -> return cb("Invalid x: #{x}") unless Number(x) args.push(x) cb(null, x*2) ), if Number(x) then x*25 else 0 atest "each", (t) -> args = [] fa.each [1,3,2], timeoutFor(args), (err, result) -> t.eq undefined, err t.eq undefined, result t.same args, [1,2,3] t.done() atest "series", (t) -> args = [] fa.series().each [1,3,2], timeoutFor(args), (err) -> t.same undefined, err t.same args, [1,3,2] t.done() ["queue","concurrent","c"].forEach (name) -> atest name, (t) -> args = [] fa[name](2).each [2,1.5,1], timeoutFor(args), (err) -> t.same undefined, err t.same args, [1.5,2,1] t.done() test "each empty", (t) -> fa.each [], ((x,cb) -> notvalidcode), (err) -> t.ok true test "each error", (t) -> fa.each [1,2,3], ((x,cb) -> cb('error')), (err) -> t.eq err, 'error' atest "each continue", (t) -> args = [] fa.continue().each [1,'invalid',3], timeoutFor(args), (err) -> t.same [1,3], args t.same ['Invalid x: invalid'], err t.done() atest "each continue no error", (t) -> args = [] fa.continue().each [1,3,2], timeoutFor(args), (err) -> t.same [1,2,3], args t.same undefined, err t.done() atest "continue.series.each", (t) -> args = [] fa.continue().series().each [1,3,2], timeoutFor(args), (err) -> t.same [1,3,2], args t.same undefined, err t.done() atest "series.continue.each", (t) -> args = [] fa.series().continue().each [1,3,2], timeoutFor(args), (err) -> t.same [1,3,2], args t.same undefined, err t.done() atest "series.continue.each", (t) -> args = [] fa.series().continue().each [1,3,'invalid'], timeoutFor(args), (err) -> t.same [1,3], args t.same ['Invalid x: invalid'], err t.done() atest "with_index.each", (t) -> args = [] fa.with_index().each [1,2,3], ((x, i, cb) -> t.eq x, i+1 return cb() ), (err) -> t.done() atest "with_index.each object", (t) -> args = [] fa.with_index().each {k1: 1, k2: 2, k3: 3}, ((val, key, i, cb) -> t.eq val, i+1 return cb() ), (err) -> t.done() atest "map", (t) -> args = [] fa.map [1,3,2], timeoutFor(args), (err, result) -> t.same undefined, err t.same result, [2,6,4] # map preserves order t.same args, [1,2,3] t.done() ["map","concat"].forEach (name) -> atest "#{name} empty array", (t) -> args = [] fa[name] [], timeoutFor(args), (err, result) -> t.same undefined, err t.same result, [] t.done() atest "with_index.map", (t) -> args = [] fa.with_index().map [1,2,3], ((x, i, cb) -> return cb(null, i) ), (err, results) -> t.same results, [0,1,2] t.done() ["filter","select"].map (name) -> atest name, (t) -> args = [] fa[name] [1,3,2,4], ((x,cb) -> return cb(x % 2 == 0) cb() ), (err,results) -> t.same results, [2,4] t.same undefined, err t.done() atest "reject", (t) -> args = [] fa.reject [1,3,2,4], ((x,cb) -> return cb(x % 2 == 0) cb() ), (err,results) -> t.same results, [1,3] t.same undefined, err t.done() atest "each with object", (t) -> args = {} fa.each {k1: 1, k2: 2, k3: 3}, ((val,key,cb) -> args[val] = key cb() ), (err) -> t.same undefined, err t.same args, {1: 'k1', 2: 'k2', 3: 'k3'} t.done() atest "Really deep", (t) -> fa.each [x for x in [0..10000]], ((x,cb) -> process.nextTick -> cb() ), (err) -> t.same undefined, err t.done() ["reduce","foldl","inject"].map (name) -> atest name, (t) -> fa[name] [1,3,2,4], 0, ((memo, x, cb) -> cb(null, memo + x)), (err, result) -> t.same undefined, err t.same result, 10 t.done() atest "reduce with errs", (t) -> fa.reduce [1,3,'oops',4], 0, ((memo, x, cb) -> if Number(x) cb(null, memo + x) else cb('oops') ), (err, result) -> t.same 'oops', err t.same undefined, result t.done() atest "continue().reduce with errs", (t) -> fa.continue().reduce [1,3,'oops',4], 0, ((memo, x, cb) -> if Number(x) cb(null, memo + x) else cb('oops', memo) ), (err, result) -> t.same ['oops'], err t.same 8, result t.done() atest "reduce with obj", (t) -> fa.reduce {k1: 1,k2: 3,k3: 2,k4: 4}, 0, ((memo, x, k, cb) -> cb(null, memo + x)), (err, result) -> t.same undefined, err t.same result, 10 t.done() ['find','detect'].map (name) -> atest name, (t) -> fa[name] [3,4,2,1], ((x,cb) -> setTimeout (() -> return cb(x % 2 == 0) return cb() ), x*25 ), (result, i) -> t.same 2, result t.same 1, i t.done() atest "detect empty array", (t) -> fa.detect [], ((x,cb) -> ), (result, i) -> t.same undefined, result t.same undefined, i t.done() atest "any empty array", (t) -> fa.any [], ((x,cb) -> ), (result) -> t.same false, result t.done() ["filter", "reject"].forEach (name) -> atest "#{name} empty array", (t) -> fa[name] [], ((x,cb) -> ), (result) -> t.same [], result t.done() atest "detect series", (t) -> fa.series().detect [3,1,4,2,1], ((x,cb) -> setTimeout (() -> return cb(x % 2 == 0) cb() ), x*25 ), (result, i) -> t.same 4, result t.same 2, i t.done() ["any","some"].map (name) -> atest name, (t) -> fa[name] [3,1,2], ((x,cb) -> cb(x==1) ), (result) -> t.eq true, result fa[name] [3,4,2], ((x,cb) -> cb(x==1) ), (result) -> t.eq false, result t.done() ["all","every"].map (name) -> atest name, (t) -> fa[name] [3,1,2], ((x, cb) -> cb(x < 10) ), (result) -> t.eq true, result fa[name] [3,1,2], ((x, cb) -> cb(x < 3) ), (result) -> t.eq false, result t.done() atest "all empty array", (t) -> fa.all [], ((x,cb) -> ), (result) -> t.same true, result t.done() atest "concat", (t) -> fa.concat ['d1','d2'], ((dir, cb) -> cb(null, [[1,"#{dir}-1"],[2,"#{dir}-2"]]) ), (err, results) -> t.same [[1,'d1-1'],[2,'d1-2'],[1,'d2-1'],[2,'d2-2']], results t.done() atest "concat with nulls", (t) -> fa.concat ['d1',null,'d2'], ((dir, cb) -> return cb(null) unless dir cb(null, [[1,"#{dir}-1"],[2,"#{dir}-2"]]) ), (err, results) -> t.same [[1,'d1-1'],[2,'d1-2'],[1,'d2-1'],[2,'d2-2']], results t.done() atest "concat queue", (t) -> fa.queue(2).concat ['1','2','3','4','5','6'], ((dir, cb) -> setTimeout((() -> cb(null, ["d#{dir}"]) ), 50) ), (err, results) -> t.same ['d1','d2','d3','d4','d5','d6'], results t.done() unless window? # This is *really* slow in the browser with fake process.nextTick atest "don't blow stack", (t) -> fa.reduce [x for x in [0..10000]][0], 0, ((m,x,cb) -> cb(null, m+x)), (err, memo) -> t.equal memo, 50005000 t.done() atest "if", (t) -> x = null fa.if true, ((callback) -> x = true callback() ), (err) -> t.ok x t.done() atest "if falsy", (t) -> fa.if false, ((cb) -> t.ok false), (err) -> t.notError err t.done() atest "if/else", (t) -> fa.if true, ((cb) -> cb(null, "one")), ((cb) -> cb(null, "two")), (err, r) -> t.notError err t.eq r, "one" fa.if false, ((cb) -> cb(null, "one")), ((cb) -> cb(null, "two")), (err, r) -> t.notError err t.eq r, "two" t.done()