diff options
-rw-r--r-- | mocha_test/auto.js | 329 | ||||
-rwxr-xr-x | test/test-async.js | 328 |
2 files changed, 329 insertions, 328 deletions
diff --git a/mocha_test/auto.js b/mocha_test/auto.js new file mode 100644 index 0000000..244f121 --- /dev/null +++ b/mocha_test/auto.js @@ -0,0 +1,329 @@ +var async = require('../lib'); +var expect = require('chai').expect; +var _ = require("lodash"); + +describe("auto", function () { + + it('auto', function(done){ + var callOrder = []; + async.auto({ + task1: ['task2', function(callback){ + setTimeout(function(){ + callOrder.push('task1'); + callback(); + }, 25); + }], + task2: function(callback){ + setTimeout(function(){ + callOrder.push('task2'); + callback(); + }, 50); + }, + task3: ['task2', function(callback){ + callOrder.push('task3'); + callback(); + }], + task4: ['task1', 'task2', function(callback){ + callOrder.push('task4'); + callback(); + }], + task5: ['task2', function(callback){ + setTimeout(function(){ + callOrder.push('task5'); + callback(); + }, 0); + }], + task6: ['task2', function(callback){ + callOrder.push('task6'); + callback(); + }] + }, + function(err){ + expect(err).to.equal(null); + expect(callOrder).to.eql(['task2','task6','task3','task5','task1','task4']); + done(); + }); + }); + + it('auto concurrency', function (done) { + var concurrency = 2; + var runningTasks = []; + + function makeCallback(taskName) { + return function(callback) { + runningTasks.push(taskName); + setTimeout(function(){ + // Each task returns the array of running tasks as results. + var result = runningTasks.slice(0); + runningTasks.splice(runningTasks.indexOf(taskName), 1); + callback(null, result); + }); + }; + } + + async.auto({ + task1: ['task2', makeCallback('task1')], + task2: makeCallback('task2'), + task3: ['task2', makeCallback('task3')], + task4: ['task1', 'task2', makeCallback('task4')], + task5: ['task2', makeCallback('task5')], + task6: ['task2', makeCallback('task6')] + }, concurrency, function(err, results){ + _.each(results, function(result) { + expect(result.length).to.be.below(concurrency + 1); + }); + done(); + }); + }); + + it('auto petrify', function (done) { + var callOrder = []; + async.auto({ + task1: ['task2', function (callback) { + setTimeout(function () { + callOrder.push('task1'); + callback(); + }, 100); + }], + task2: function (callback) { + setTimeout(function () { + callOrder.push('task2'); + callback(); + }, 200); + }, + task3: ['task2', function (callback) { + callOrder.push('task3'); + callback(); + }], + task4: ['task1', 'task2', function (callback) { + callOrder.push('task4'); + callback(); + }] + }, + function (err) { + if (err) throw err; + expect(callOrder).to.eql(['task2', 'task3', 'task1', 'task4']); + done(); + }); + }); + + it('auto results', function(done){ + var callOrder = []; + async.auto({ + task1: ['task2', function(callback, results){ + expect(results.task2).to.eql('task2'); + setTimeout(function(){ + callOrder.push('task1'); + callback(null, 'task1a', 'task1b'); + }, 25); + }], + task2: function(callback){ + setTimeout(function(){ + callOrder.push('task2'); + callback(null, 'task2'); + }, 50); + }, + task3: ['task2', function(callback, results){ + expect(results.task2).to.eql('task2'); + callOrder.push('task3'); + callback(null); + }], + task4: ['task1', 'task2', function(callback, results){ + expect(results.task1).to.eql(['task1a','task1b']); + expect(results.task2).to.eql('task2'); + callOrder.push('task4'); + callback(null, 'task4'); + }] + }, + function(err, results){ + expect(callOrder).to.eql(['task2','task3','task1','task4']); + expect(results).to.eql({task1: ['task1a','task1b'], task2: 'task2', task3: undefined, task4: 'task4'}); + done(); + }); + }); + + it('auto empty object', function(done){ + async.auto({}, function(err){ + expect(err).to.equal(null); + done(); + }); + }); + + it('auto error', function(done){ + async.auto({ + task1: function(callback){ + callback('testerror'); + }, + task2: ['task1', function(callback){ + throw new Error('task2 should not be called'); + }], + task3: function(callback){ + callback('testerror2'); + } + }, + function(err){ + expect(err).to.equal('testerror'); + }); + setTimeout(done, 100); + }); + + it('auto no callback', function(done){ + async.auto({ + task1: function(callback){callback();}, + task2: ['task1', function(callback){callback(); done();}] + }); + }); + + it('auto concurrency no callback', function(done){ + async.auto({ + task1: function(callback){callback();}, + task2: ['task1', function(callback){callback(); done();}] + }, 1); + }); + + it('auto error should pass partial results', function(done) { + async.auto({ + task1: function(callback){ + callback(false, 'result1'); + }, + task2: ['task1', function(callback){ + callback('testerror', 'result2'); + }], + task3: ['task2', function(){ + throw new Error('task3 should not be called'); + }] + }, + function(err, results){ + expect(err).to.equal('testerror'); + expect(results.task1).to.equal('result1'); + expect(results.task2).to.equal('result2'); + done(); + }); + }); + + // Issue 24 on github: https://github.com/caolan/async/issues#issue/24 + // Issue 76 on github: https://github.com/caolan/async/issues#issue/76 + it('auto removeListener has side effect on loop iterator', function(done) { + async.auto({ + task1: ['task3', function(/*callback*/) { done(); }], + task2: ['task3', function(/*callback*/) { /* by design: DON'T call callback */ }], + task3: function(callback) { callback(); } + }); + }); + + // Issue 410 on github: https://github.com/caolan/async/issues/410 + it('auto calls callback multiple times', function(done) { + if (process.browser) { + // node only test + return done(); + } + var finalCallCount = 0; + var domain = require('domain').create(); + domain.on('error', function (e) { + // ignore test error + if (!e._test_error) { + return done(e); + } + }); + domain.run(function () { + async.auto({ + task1: function(callback) { callback(null); }, + task2: ['task1', function(callback) { callback(null); }] + }, + + // Error throwing final callback. This should only run once + function() { + finalCallCount++; + var e = new Error("An error"); + e._test_error = true; + throw e; + }); + }); + setTimeout(function () { + expect(finalCallCount).to.equal(1); + done(); + }, 10); + }); + + + it('auto calls callback multiple times with parallel functions', function(done) { + async.auto({ + task1: function(callback) { setTimeout(callback,0,"err"); }, + task2: function(callback) { setTimeout(callback,0,"err"); } + }, + // Error throwing final callback. This should only run once + function(err) { + expect(err).to.equal("err"); + done(); + }); + }); + + + // Issue 462 on github: https://github.com/caolan/async/issues/462 + it('auto modifying results causes final callback to run early', function(done) { + async.auto({ + task1: function(callback, results){ + results.inserted = true; + callback(null, 'task1'); + }, + task2: function(callback){ + setTimeout(function(){ + callback(null, 'task2'); + }, 50); + }, + task3: function(callback){ + setTimeout(function(){ + callback(null, 'task3'); + }, 100); + } + }, + function(err, results){ + expect(results.inserted).to.equal(true); + expect(results.task3).to.equal('task3'); + done(); + }); + }); + + // Issue 263 on github: https://github.com/caolan/async/issues/263 + it('auto prevent dead-locks due to inexistant dependencies', function(done) { + expect(function () { + async.auto({ + task1: ['noexist', function(callback){ + callback(null, 'task1'); + }] + }); + }).to.throw; + done(); + }); + + // Issue 263 on github: https://github.com/caolan/async/issues/263 + it('auto prevent dead-locks due to cyclic dependencies', function(done) { + expect(function () { + async.auto({ + task1: ['task2', function(callback){ + callback(null, 'task1'); + }], + task2: ['task1', function(callback){ + callback(null, 'task2'); + }] + }); + }).to.throw; + done(); + }); + + // Issue 988 on github: https://github.com/caolan/async/issues/988 + it('auto stops running tasks on error', function(done) { + async.auto({ + task1: function (callback) { + callback('error'); + }, + task2: function (callback) { + throw new Error('test2 should not be called'); + } + }, 1, function (error) { + expect(error).to.equal('error'); + done(); + }); + }); + +}); diff --git a/test/test-async.js b/test/test-async.js index c8a1c7c..1110012 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -278,334 +278,6 @@ exports['seq without callback'] = function (test) { add2mul3.call(testcontext, 3); }; -exports['auto'] = function(test){ - test.expect(2); - var callOrder = []; - async.auto({ - task1: ['task2', function(callback){ - setTimeout(function(){ - callOrder.push('task1'); - callback(); - }, 25); - }], - task2: function(callback){ - setTimeout(function(){ - callOrder.push('task2'); - callback(); - }, 50); - }, - task3: ['task2', function(callback){ - callOrder.push('task3'); - callback(); - }], - task4: ['task1', 'task2', function(callback){ - callOrder.push('task4'); - callback(); - }], - task5: ['task2', function(callback){ - setTimeout(function(){ - callOrder.push('task5'); - callback(); - }, 0); - }], - task6: ['task2', function(callback){ - callOrder.push('task6'); - callback(); - }] - }, - function(err){ - test.ok(err === null, err + " passed instead of 'null'"); - test.same(callOrder, ['task2','task6','task3','task5','task1','task4']); - test.done(); - }); -}; - -exports['auto concurrency'] = function (test) { - var concurrency = 2; - var runningTasks = []; - var makeCallback = function(taskName) { - return function(callback) { - runningTasks.push(taskName); - setTimeout(function(){ - // Each task returns the array of running tasks as results. - var result = runningTasks.slice(0); - runningTasks.splice(runningTasks.indexOf(taskName), 1); - callback(null, result); - }); - }; - }; - async.auto({ - task1: ['task2', makeCallback('task1')], - task2: makeCallback('task2'), - task3: ['task2', makeCallback('task3')], - task4: ['task1', 'task2', makeCallback('task4')], - task5: ['task2', makeCallback('task5')], - task6: ['task2', makeCallback('task6')] - }, concurrency, function(err, results){ - Object.keys(results).forEach(function(taskName) { - test.ok(results[taskName].length <= concurrency); - }); - test.done(); - }); -}; - -exports['auto petrify'] = function (test) { - var callOrder = []; - async.auto({ - task1: ['task2', function (callback) { - setTimeout(function () { - callOrder.push('task1'); - callback(); - }, 100); - }], - task2: function (callback) { - setTimeout(function () { - callOrder.push('task2'); - callback(); - }, 200); - }, - task3: ['task2', function (callback) { - callOrder.push('task3'); - callback(); - }], - task4: ['task1', 'task2', function (callback) { - callOrder.push('task4'); - callback(); - }] - }, - function (err) { - if (err) throw err; - test.same(callOrder, ['task2', 'task3', 'task1', 'task4']); - test.done(); - }); -}; - -exports['auto results'] = function(test){ - var callOrder = []; - async.auto({ - task1: ['task2', function(callback, results){ - test.same(results.task2, 'task2'); - setTimeout(function(){ - callOrder.push('task1'); - callback(null, 'task1a', 'task1b'); - }, 25); - }], - task2: function(callback){ - setTimeout(function(){ - callOrder.push('task2'); - callback(null, 'task2'); - }, 50); - }, - task3: ['task2', function(callback, results){ - test.same(results.task2, 'task2'); - callOrder.push('task3'); - callback(null); - }], - task4: ['task1', 'task2', function(callback, results){ - test.same(results.task1, ['task1a','task1b']); - test.same(results.task2, 'task2'); - callOrder.push('task4'); - callback(null, 'task4'); - }] - }, - function(err, results){ - test.same(callOrder, ['task2','task3','task1','task4']); - test.same(results, {task1: ['task1a','task1b'], task2: 'task2', task3: undefined, task4: 'task4'}); - test.done(); - }); -}; - -exports['auto empty object'] = function(test){ - async.auto({}, function(err){ - test.ok(err === null, err + " passed instead of 'null'"); - test.done(); - }); -}; - -exports['auto error'] = function(test){ - test.expect(1); - async.auto({ - task1: function(callback){ - callback('testerror'); - }, - task2: ['task1', function(callback){ - test.ok(false, 'task2 should not be called'); - callback(); - }], - task3: function(callback){ - callback('testerror2'); - } - }, - function(err){ - test.equals(err, 'testerror'); - }); - setTimeout(test.done, 100); -}; - -exports['auto no callback'] = function(test){ - async.auto({ - task1: function(callback){callback();}, - task2: ['task1', function(callback){callback(); test.done();}] - }); -}; - -exports['auto concurrency no callback'] = function(test){ - async.auto({ - task1: function(callback){callback();}, - task2: ['task1', function(callback){callback(); test.done();}] - }, 1); -}; - -exports['auto error should pass partial results'] = function(test) { - async.auto({ - task1: function(callback){ - callback(false, 'result1'); - }, - task2: ['task1', function(callback){ - callback('testerror', 'result2'); - }], - task3: ['task2', function(){ - test.ok(false, 'task3 should not be called'); - }] - }, - function(err, results){ - test.equals(err, 'testerror'); - test.equals(results.task1, 'result1'); - test.equals(results.task2, 'result2'); - test.done(); - }); -}; - -// Issue 24 on github: https://github.com/caolan/async/issues#issue/24 -// Issue 76 on github: https://github.com/caolan/async/issues#issue/76 -exports['auto removeListener has side effect on loop iterator'] = function(test) { - async.auto({ - task1: ['task3', function(/*callback*/) { test.done(); }], - task2: ['task3', function(/*callback*/) { /* by design: DON'T call callback */ }], - task3: function(callback) { callback(); } - }); -}; - -// Issue 410 on github: https://github.com/caolan/async/issues/410 -exports['auto calls callback multiple times'] = function(test) { - if (isBrowser()) { - // node only test - test.done(); - return; - } - var finalCallCount = 0; - var domain = require('domain').create(); - domain.on('error', function (e) { - // ignore test error - if (!e._test_error) { - return test.done(e); - } - }); - domain.run(function () { - async.auto({ - task1: function(callback) { callback(null); }, - task2: ['task1', function(callback) { callback(null); }] - }, - - // Error throwing final callback. This should only run once - function() { - finalCallCount++; - var e = new Error("An error"); - e._test_error = true; - throw e; - }); - }); - setTimeout(function () { - test.equal(finalCallCount, 1, - "Final auto callback should only be called once" - ); - test.done(); - }, 10); -}; - - -exports['auto calls callback multiple times with parallel functions'] = function(test) { - test.expect(1); - async.auto({ - task1: function(callback) { setTimeout(callback,0,"err"); }, - task2: function(callback) { setTimeout(callback,0,"err"); } - }, - // Error throwing final callback. This should only run once - function(err) { - test.equal(err, "err"); - test.done(); - }); -}; - - -// Issue 462 on github: https://github.com/caolan/async/issues/462 -exports['auto modifying results causes final callback to run early'] = function(test) { - async.auto({ - task1: function(callback, results){ - results.inserted = true; - callback(null, 'task1'); - }, - task2: function(callback){ - setTimeout(function(){ - callback(null, 'task2'); - }, 50); - }, - task3: function(callback){ - setTimeout(function(){ - callback(null, 'task3'); - }, 100); - } - }, - function(err, results){ - test.equal(results.inserted, true); - test.ok(results.task3, 'task3'); - test.done(); - }); -}; - -// Issue 263 on github: https://github.com/caolan/async/issues/263 -exports['auto prevent dead-locks due to inexistant dependencies'] = function(test) { - test.throws(function () { - async.auto({ - task1: ['noexist', function(callback){ - callback(null, 'task1'); - }] - }); - }, Error); - test.done(); -}; - -// Issue 263 on github: https://github.com/caolan/async/issues/263 -exports['auto prevent dead-locks due to cyclic dependencies'] = function(test) { - test.throws(function () { - async.auto({ - task1: ['task2', function(callback){ - callback(null, 'task1'); - }], - task2: ['task1', function(callback){ - callback(null, 'task2'); - }] - }); - }, Error); - test.done(); -}; - -// Issue 988 on github: https://github.com/caolan/async/issues/988 -exports['auto stops running tasks on error'] = function(test) { - async.auto({ - task1: function (callback) { - callback('error'); - }, - task2: function (callback) { - test.ok(false, 'test2 should not be called'); - callback(); - } - }, 1, function (error) { - test.equal(error, 'error', 'finishes with error'); - test.done(); - }); -}; - // Issue 306 on github: https://github.com/caolan/async/issues/306 exports['retry when attempt succeeds'] = function(test) { var failed = 3; |