var cps = require('../lib/cps.js'); var fib = require('./fib'); var assert = require("assert"); describe('cps', function() { describe('seq', function() { it('should return 3 for 1+2', function(cb) { var a, b; cps.seq([ function(_, cb) { setTimeout(function() { cb(null, 1); }, 0); }, function(_, cb) { a = _; setTimeout(function() { cb(null, 2); }, 0); }, function(_, cb) { b = _; cb(null, a + b); }, function(_, cb) { assert.equal(_, 3); cb(); } ], cb); }); }); describe('pwhile', function() { it('should return 2 for fib(2)', function(cb) { cps.seq([ function(_, cb) { fib(5, cb); }, function(_, cb) { assert.equal(_, 8); cb(); } ], cb); }); it('should not fail for huge loops', function(cb) { this.timeout(0); var i; cps.seq([ function(_, cb) { i = 0; cps.rescue({ 'try': function(cb) { cps.pwhile( function(cb) { cb(null, i < 10000); }, function(cb) { i++; cb(); }, cb ) }, 'catch': function(e, cb) { console.log('ERROR: ', e); throw e; } }, cb); }, function(_, cb) { console.log('i is: ', i); cb(); } ], cb); }); }); describe('pfor', function() { it('should return 45 for the sum of 0 through 9', function(cb) { var sum = 0; cps.seq([ function(_, cb) { cps.pfor(10, function(i, cb) { setTimeout(function() { sum += i; cb(); }, 0); }, cb); }, function(_, cb) { assert.equal(sum, 45); cb(); } ], cb); }); }); describe('peach', function() { it('should return 55 for the sum of 1 through 10', function(cb) { var sum = 0; cps.seq([ function(_, cb) { cps.peach( [1,2,3,4,5,6,7,8,9,10], function(el, cb) { sum += el; cb(); }, cb ); }, function(_, cb) { assert.equal(sum, 55); cb(); } ], cb); }); }); describe('pmap', function() { it('should return the list of squares of [1..10]', function(cb) { cps.seq([ function(_, cb) { cps.pmap( [1,2,3,4,5,6,7,8,9,10], function(el, cb) { setTimeout(function() { cb(null, el*el); }, 0); }, cb ); }, function(_, cb) { for (var i = 1; i <= 10; i++) { assert.equal(_[i-1], i*i); } cb(); } ], cb); }); }); describe('parallel', function() { it('should work for 3 parallel threads', function(cb) { this.timeout(0); var output = []; var start, end; cps.seq([ function(_, cb) { start = new Date(); cps.parallel([ function(cb) { setTimeout(function() { output.push(3); cb(new Error('kaz')); }, 3000); }, function(cb) { setTimeout(function() { output.push(2); cb(null, 'ok'); }, 2000); }, function(cb) { setTimeout(function() { output.push(1); cb(new Error('foobar')); }, 1000); } ], cb); }, function(_, cb) { end = new Date(); assert(end-start < 3100, 'parallel is taking too long to run'); for (var i = 1; i <= 3; i++) { assert.equal(output[i-1], i); } assert.equal(_[0].status, 'error'); assert.equal(_[0].error.message, 'kaz'); assert.equal(_[1].status, 'ok'); assert.equal(_[1].data, 'ok'); assert.equal(_[2].status, 'error'); assert.equal(_[2].error.message, 'foobar'); cb(); } ], cb); }); }); describe('noFail', function() { it('should not fail on success', function(cb) { cps.noFail(function(cb) { cb(null, 1); }, cb); }); it('should not fail on failure', function(cb) { cps.noFail(function(cb) { cb(new Error('foobar')); }, cb); }); }); describe('rescue', function() { it('should catch errors', function(cb) { cps.seq([ function(_, cb) { cps.rescue({ 'try': function(cb) { setTimeout(function() { cb(new Error('foobar')); }, 0); }, 'catch': function(err, cb) { cb(null, 'ok'); } }, cb); }, function(_, cb) { assert.equal(_, 'ok'); cb(); } ], cb); }); it('should be able to throw errors', function(cb) { cps.seq([ function(_, cb) { cps.rescue({ 'try': function(cb) { setTimeout(function() { cb(new Error('foobar')); }, 0); } }, cb); } ], function(err, res) { try { assert.equal(err.message, 'foobar'); cb(); } catch(e) { cb(e); } }); }); it('should be able to rethrow errors', function(cb) { cps.seq([ function(_, cb) { cps.rescue({ 'try': function(cb) { setTimeout(function() { cb(new Error('foobar')); }, 0); }, 'catch': function(err, cb) { throw new Error('kaz'); } }, cb); } ], function(err, res) { try { assert.equal(err.message, 'kaz'); cb(); } catch(e) { cb(e); } }); }); it('should execute finally clause on success', function(cb) { var finallyDone = false; cps.seq([ function(_, cb) { cps.rescue({ 'try': function(cb) { setTimeout(function() { cb(null, 'ok'); }, 0); }, 'finally': function(cb) { finallyDone = true; cb(); } }, cb); }, function(_, cb) { assert.equal(_, 'ok'); assert(finallyDone); cb(); } ], cb); }); it('should execute finally clause on exception being caught', function(cb) { var finallyDone = false; cps.seq([ function(_, cb) { cps.rescue({ 'try': function(cb) { setTimeout(function() { cb(new Error('foobar')); }, 0); }, 'catch': function(err, cb) { cb(null, 'exception caught'); }, 'finally': function(cb) { finallyDone = true; cb(); } }, cb); }, function(_, cb) { assert.equal(_, 'exception caught'); assert(finallyDone); cb(); } ], cb); }); it('should execute finally clause on exception', function(cb) { var finallyDone = false; cps.seq([ function(_, cb) { cps.rescue({ 'try': function(cb) { setTimeout(function() { cb(new Error('foobar')); }, 0); }, 'finally': function(cb) { finallyDone = true; cb(); } }, cb); } ], function(err, res) { try{ assert.equal(err.message, 'foobar'); assert(finallyDone); cb(); } catch(e) { cb(e); } }); }); it('should throw exception in finally clause on success', function(cb) { cps.seq([ function(_, cb) { cps.rescue({ 'try': function(cb) { setTimeout(function() { cb(null, 'ok'); }, 0); }, 'finally': function(cb) { throw new Error('error in finally'); cb(); } }, cb); } ], function(err, res) { try{ assert.equal(err.message, 'error in finally'); cb(); } catch(e) { cb(e); } }); }); it('should throw exception in finally clause on exception', function(cb) { cps.seq([ function(_, cb) { cps.rescue({ 'try': function(cb) { setTimeout(function() { cb(new Error('foobar')); }, 0); }, 'finally': function(cb) { throw new Error('error in finally'); cb(); } }, cb); } ], function(err, res) { try{ assert.equal(err.message, 'error in finally'); cb(); } catch(e) { cb(e); } }); }); }); });