diff options
author | Hubert Argasinski <argasinski.hubert@gmail.com> | 2018-11-27 17:04:13 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-27 17:04:13 -0600 |
commit | bf67791e75d329a39f71f81e055091ad76088f81 (patch) | |
tree | f193e6714efe4a61b87c01a5c8ac64802b67b6f2 | |
parent | a5a9f13ee024e58a3bd074f9c4e0130f0499d27b (diff) | |
download | async-bf67791e75d329a39f71f81e055091ad76088f81.tar.gz |
Fixes #1582 (#1597)
* ensure err is passed on for cancelable methods
* fix test descriptions
-rw-r--r-- | lib/concatLimit.js | 2 | ||||
-rw-r--r-- | lib/groupByLimit.js | 2 | ||||
-rw-r--r-- | lib/internal/createTester.js | 2 | ||||
-rw-r--r-- | lib/internal/filter.js | 2 | ||||
-rw-r--r-- | lib/mapValuesLimit.js | 2 | ||||
-rw-r--r-- | lib/sortBy.js | 2 | ||||
-rw-r--r-- | lib/tryEach.js | 2 | ||||
-rw-r--r-- | test/applyEach.js | 53 | ||||
-rw-r--r-- | test/autoInject.js | 26 | ||||
-rw-r--r-- | test/compose.js | 25 | ||||
-rw-r--r-- | test/concat.js | 58 | ||||
-rw-r--r-- | test/detect.js | 58 | ||||
-rw-r--r-- | test/each.js | 58 | ||||
-rw-r--r-- | test/every.js | 55 | ||||
-rw-r--r-- | test/filter.js | 116 | ||||
-rw-r--r-- | test/groupBy.js | 58 | ||||
-rw-r--r-- | test/map.js | 55 | ||||
-rw-r--r-- | test/mapValues.js | 79 | ||||
-rw-r--r-- | test/parallel.js | 21 | ||||
-rw-r--r-- | test/reduce.js | 30 | ||||
-rw-r--r-- | test/retryable.js | 16 | ||||
-rw-r--r-- | test/seq.js | 25 | ||||
-rw-r--r-- | test/series.js | 16 | ||||
-rw-r--r-- | test/some.js | 58 | ||||
-rw-r--r-- | test/sortBy.js | 18 | ||||
-rw-r--r-- | test/times.js | 58 | ||||
-rw-r--r-- | test/transform.js | 16 | ||||
-rw-r--r-- | test/tryEach.js | 20 |
28 files changed, 917 insertions, 16 deletions
diff --git a/lib/concatLimit.js b/lib/concatLimit.js index 34c35df..bb74b35 100644 --- a/lib/concatLimit.js +++ b/lib/concatLimit.js @@ -26,7 +26,7 @@ function concatLimit(coll, limit, iteratee, callback) { return mapLimit(coll, limit, (val, iterCb) => { _iteratee(val, (err, ...args) => { if (err) return iterCb(err); - return iterCb(null, args); + return iterCb(err, args); }); }, (err, mapResults) => { var result = []; diff --git a/lib/groupByLimit.js b/lib/groupByLimit.js index 24d5c40..6a0d7ac 100644 --- a/lib/groupByLimit.js +++ b/lib/groupByLimit.js @@ -27,7 +27,7 @@ function groupByLimit(coll, limit, iteratee, callback) { return mapLimit(coll, limit, (val, iterCb) => { _iteratee(val, (err, key) => { if (err) return iterCb(err); - return iterCb(null, {key, val}); + return iterCb(err, {key, val}); }); }, (err, mapResults) => { var result = {}; diff --git a/lib/internal/createTester.js b/lib/internal/createTester.js index 5858702..2c2745e 100644 --- a/lib/internal/createTester.js +++ b/lib/internal/createTester.js @@ -8,7 +8,7 @@ export default function _createTester(check, getResult) { const iteratee = wrapAsync(_iteratee) eachfn(arr, (value, _, callback) => { iteratee(value, (err, result) => { - if (err) return callback(err) + if (err || err === false) return callback(err); if (check(result) && !testResult) { testPassed = true; diff --git a/lib/internal/filter.js b/lib/internal/filter.js index 15d7ae3..936dac6 100644 --- a/lib/internal/filter.js +++ b/lib/internal/filter.js @@ -27,7 +27,7 @@ function filterGeneric(eachfn, coll, iteratee, callback) { if (v) { results.push({index, value: x}); } - iterCb(); + iterCb(err); }); }, err => { if (err) return callback(err); diff --git a/lib/mapValuesLimit.js b/lib/mapValuesLimit.js index af56f25..f34943d 100644 --- a/lib/mapValuesLimit.js +++ b/lib/mapValuesLimit.js @@ -33,7 +33,7 @@ function mapValuesLimit(obj, limit, iteratee, callback) { _iteratee(val, key, (err, result) => { if (err) return next(err); newObj[key] = result; - next(); + next(err); }); }, err => callback(err, newObj)); } diff --git a/lib/sortBy.js b/lib/sortBy.js index ec724b6..4477677 100644 --- a/lib/sortBy.js +++ b/lib/sortBy.js @@ -55,7 +55,7 @@ function sortBy (coll, iteratee, callback) { return map(coll, (x, iterCb) => { _iteratee(x, (err, criteria) => { if (err) return iterCb(err); - iterCb(null, {value: x, criteria}); + iterCb(err, {value: x, criteria}); }); }, (err, results) => { if (err) return callback(err); diff --git a/lib/tryEach.js b/lib/tryEach.js index 6677c9d..c968cb7 100644 --- a/lib/tryEach.js +++ b/lib/tryEach.js @@ -45,6 +45,8 @@ function tryEach(tasks, callback) { var result; return eachSeries(tasks, (task, taskCb) => { wrapAsync(task)((err, ...args) => { + if (err === false) return taskCb(err); + if (args.length < 2) { [result] = args; } else { diff --git a/test/applyEach.js b/test/applyEach.js index ee70305..4a67ee4 100644 --- a/test/applyEach.js +++ b/test/applyEach.js @@ -35,6 +35,32 @@ describe('applyEach', () => { }); }); + it('applyEach canceled', (done) => { + var call_order = []; + function one(_, cb) { + call_order.push('one'); + cb(null, 1); + } + + function two(_, cb) { + call_order.push('two'); + cb(false); + } + + function three(/*, cb */) { + throw new Error('third task - should not get here'); + } + + async.applyEach({one, two, three}, 5, () => { + throw new Error('final callback - should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql(['one', 'two']); + done(); + }, 25); + }); + it('applyEachSeries', (done) => { var call_order = []; function one(val, cb) { @@ -66,6 +92,33 @@ describe('applyEach', () => { }); }); + it('applyEachSeries canceled', (done) => { + var call_order = []; + function one(_, cb) { + async.setImmediate(() => { + call_order.push('one'); + cb(null, 1); + }); + } + function two(_, cb) { + async.setImmediate(() => { + call_order.push('two'); + cb(false); + }); + } + function three(/*, cb */) { + throw new Error('third task - should not get here'); + } + async.applyEachSeries([one, two, three], 5, () => { + throw new Error('final callback - should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql(['one', 'two']); + done(); + }, 25); + }); + it('applyEach partial application', (done) => { var call_order = []; var one = function (val, cb) { diff --git a/test/autoInject.js b/test/autoInject.js index bb3270b..224783f 100644 --- a/test/autoInject.js +++ b/test/autoInject.js @@ -122,4 +122,30 @@ describe('autoInject', () => { done(); }); }); + + it('should be cancelable', (done) => { + var call_order = []; + + async.autoInject({ + task1 (cb) { + call_order.push('task1'); + cb(null, 1); + }, + task2 (task3, cb) { + call_order.push('task2'); + cb(null, 2); + }, + task3 (cb) { + call_order.push('task3'); + cb(false); + }, + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql(['task1', 'task3']); + done(); + }, 25); + }); }); diff --git a/test/compose.js b/test/compose.js index 39892c0..2eb3b6c 100644 --- a/test/compose.js +++ b/test/compose.js @@ -83,4 +83,29 @@ describe('compose', () => { done(); }); }); + + it('should be cancelable', (done) => { + var call_order = []; + + var add2 = function (n, cb) { + call_order.push('add2'); + cb(null, n + 2); + }; + var mul3 = function (n, cb) { + call_order.push('mul3'); + cb(false, n * 3); + }; + var add1 = function () { + throw new Error('add1 - should not get here'); + }; + var add2mul3add1 = async.compose(add1, mul3, add2); + add2mul3add1(3, () => { + throw new Error('final callback - should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql(['add2', 'mul3']); + done(); + }, 25); + }); }); diff --git a/test/concat.js b/test/concat.js index cc97374..e42344b 100644 --- a/test/concat.js +++ b/test/concat.js @@ -36,6 +36,24 @@ describe('concat', function() { }); }); + it('canceled', (done) => { + var callOrder = []; + async.concat([1, 3, 2], (val, next) => { + callOrder.push(val); + if (val === 3) { + return next(false, [val, val + 1]); + } + next(null, [val, val + 1]); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 3]); + done(); + }, 25); + }); + it('original untouched', (done) => { var arr = ['foo', 'bar', 'baz']; async.concat(arr, (val, next) => { @@ -240,6 +258,26 @@ describe('concat', function() { }); }); + it('canceled', (done) => { + var callOrder = []; + async.concatLimit([1, 2, 3, 4, 5], 2, (val, next) => { + callOrder.push(val); + async.setImmediate(() => { + if (val === 3) { + return next(false, val); + } + next(null, val) + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 2, 3, 4]); + done(); + }, 50); + }); + it('handles objects', (done) => { async.concatLimit({'foo': 1, 'bar': 2, 'baz': 3}, 2, (val, next) => { next(null, val+1); @@ -373,6 +411,26 @@ describe('concat', function() { }); }); + it('canceled', (done) => { + var callOrder = []; + async.concatSeries([1, 2, 3], (val, next) => { + callOrder.push(val); + async.setImmediate(() => { + if (val === 2) { + return next(false, val); + } + next(null, val) + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 2]); + done(); + }, 50); + }); + it('handles objects', (done) => { async.concatSeries({'foo': 1, 'bar': 2, 'baz': 3}, (val, next) => { return next(null, [val, val+1]); diff --git a/test/detect.js b/test/detect.js index f6a5416..3351d9e 100644 --- a/test/detect.js +++ b/test/detect.js @@ -47,6 +47,24 @@ describe("detect", () => { }); }); + it('detect canceled', (done) => { + var call_order = []; + async.detect({'a': 3, 'b': 2, 'c': 1}, (x, callback) => { + call_order.push(x); + if (x === 2) { + return callback(false); + } + callback(null); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3, 2]); + done(); + }, 25); + }); + it('detectSeries', function(done){ var call_order = []; async.detectSeries([3,2,1], detectIteratee.bind(this, call_order), (err, result) => { @@ -98,6 +116,26 @@ describe("detect", () => { }); }); + it('detectSeries canceled', (done) => { + var call_order = []; + async.detectSeries([3, 2, 1], (x, callback) => { + async.setImmediate(() => { + call_order.push(x); + if (x === 2) { + return callback(false); + } + callback(null); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3, 2]); + done(); + }, 50); + }); + it('detectLimit', function(done){ var call_order = []; async.detectLimit([3, 2, 1], 2, detectIteratee.bind(this, call_order), (err, result) => { @@ -135,6 +173,26 @@ describe("detect", () => { }); }); + it('detectLimit canceled', (done) => { + var call_order = []; + async.detectLimit([3, 3, 2, 2, 1], 2, (x, callback) => { + async.setImmediate(() => { + call_order.push(x); + if (x === 2) { + return callback(false); + } + callback(null); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3, 3, 2, 2]); + done(); + }, 50); + }); + it('detectSeries doesn\'t cause stack overflow (#1293)', (done) => { var arr = _.range(10000); let calls = 0; diff --git a/test/each.js b/test/each.js index d05457b..eb12842 100644 --- a/test/each.js +++ b/test/each.js @@ -74,6 +74,24 @@ describe("each", () => { setTimeout(done, 50); }); + it('each canceled', (done) => { + var call_order = []; + async.each([1, 2, 3], (x, callback) => { + call_order.push(x); + if (x === 2) { + return callback(false); + } + callback(null); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1, 2, 3]); + done(); + }, 25); + }); + it('each no callback', function(done) { async.each([1], eachNoCallbackIteratee.bind(this, done)); }); @@ -148,6 +166,26 @@ describe("each", () => { setTimeout(done, 50); }); + it('eachSeries canceled', (done) => { + var call_order = []; + async.eachSeries([1, 2, 3], (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false); + } + callback(null); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1, 2]); + done(); + }, 50); + }); + it('eachSeries no callback', function(done) { async.eachSeries([1], eachNoCallbackIteratee.bind(this, done)); }); @@ -226,6 +264,26 @@ describe("each", () => { setTimeout(done, 25); }); + it('eachLimit canceled', (done) => { + var call_order = []; + async.eachLimit([1, 1, 2, 2, 3], 2, (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false); + } + callback(null); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1, 1, 2, 2]); + done(); + }, 50); + }); + it('eachLimit no callback', function(done) { async.eachLimit([1], 1, eachNoCallbackIteratee.bind(this, done)); }); diff --git a/test/every.js b/test/every.js index 629246c..00038b9 100644 --- a/test/every.js +++ b/test/every.js @@ -84,6 +84,23 @@ describe("every", () => { }); }); + it('canceled', (done) => { + var call_order = []; + async.every([1,2,3], (x, callback) => { + call_order.push(x); + if (x === 2) { + return callback(false, true); + } + callback(null, true); + }, () => { + throw new Error('should not get here'); + }); + setTimeout(() => { + expect(call_order).to.eql([1,2,3]); + done(); + }, 25); + }); + it('everySeries doesn\'t cause stack overflow (#1293)', (done) => { var arr = _.range(10000); let calls = 0; @@ -97,6 +114,25 @@ describe("every", () => { }); }); + it('everySeries canceled', (done) => { + var call_order = []; + async.everySeries([1,2,3], (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false, true); + } + callback(null, true); + }); + }, () => { + throw new Error('should not get here'); + }); + setTimeout(() => { + expect(call_order).to.eql([1, 2]); + done(); + }, 50); + }); + it('everyLimit doesn\'t cause stack overflow (#1293)', (done) => { var arr = _.range(10000); let calls = 0; @@ -110,6 +146,25 @@ describe("every", () => { }); }); + it('everyLimit canceled', (done) => { + var call_order = []; + async.everyLimit([1,1,2,2,3], 2, (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false, true); + } + callback(null, true); + }); + }, () => { + throw new Error('final callback - should not get here'); + }); + setTimeout(() => { + expect(call_order).to.eql([1,1,2,2]); + done(); + }, 50); + }); + it('all alias', () => { expect(async.all).to.equal(async.every); }); diff --git a/test/filter.js b/test/filter.js index c636aa1..5f666e9 100644 --- a/test/filter.js +++ b/test/filter.js @@ -92,6 +92,24 @@ describe("filter", () => { }); }); + it('filter canceled', (done) => { + var call_order = []; + async.filter([3,1,2], (x, callback) => { + call_order.push(x); + if (x === 1) { + return callback(false, true); + } + callback(null, true); + } , () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3,1,2]); + done(); + }, 25); + }); + it('filterSeries', (done) => { async.filterSeries([3,1,2], filterIteratee, (err, results) => { expect(err).to.equal(null); @@ -100,6 +118,26 @@ describe("filter", () => { }); }); + it('filterSeries canceled', (done) => { + var call_order = []; + async.filterSeries([3,1,2], (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 1) { + return callback(false, true); + } + callback(null, true); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3,1]); + done(); + }, 50); + }); + it('select alias', () => { expect(async.select).to.equal(async.filter); }); @@ -118,6 +156,26 @@ describe("filter", () => { }); }); + it('filterLimit canceled', (done) => { + var call_order = []; + async.filterLimit([1,1,2,2,3], 2, (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false, true); + } + callback(null, true); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1,1,2,2]); + done(); + }, 50); + }); + }); describe("reject", () => { @@ -152,6 +210,24 @@ describe("reject", () => { }); }); + it('reject canceled', (done) => { + var call_order = []; + async.filter([3,1,2], (x, callback) => { + call_order.push(x); + if (x === 2) { + return callback(false, false); + } + callback(null, false); + } , () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3,1,2]); + done(); + }, 25); + }); + it('rejectSeries', (done) => { async.rejectSeries([3,1,2], filterIteratee, (err, results) => { expect(err).to.equal(null); @@ -160,6 +236,26 @@ describe("reject", () => { }); }); + it('rejectSeries canceled', (done) => { + var call_order = []; + async.rejectSeries([3,1,2], (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 1) { + return callback(false, false); + } + callback(null, false); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3,1]); + done(); + }, 50); + }); + it('rejectLimit', (done) => { testLimit([5, 4, 3, 2, 1], async.rejectLimit, 2, (v, next) => { next(null, v % 2); @@ -170,6 +266,26 @@ describe("reject", () => { }); }); + it('rejectLimit canceled', (done) => { + var call_order = []; + async.filterLimit([1,1,2,2,3], 2, (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false, false); + } + callback(null, false); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1,1,2,2]); + done(); + }, 50); + }); + it('filter fails', (done) => { async.filter({a: 1, b: 2, c: 3}, (item, callback) => { if (item === 3) { diff --git a/test/groupBy.js b/test/groupBy.js index 0fcf53b..b00484c 100644 --- a/test/groupBy.js +++ b/test/groupBy.js @@ -36,6 +36,24 @@ describe('groupBy', function() { }); }); + it('canceled', (done) => { + var callOrder = []; + async.groupBy([1, 3, 2], (val, next) => { + callOrder.push(val); + if (val === 3) { + return next(false, val+1); + } + next(null, val+1); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 3]); + done(); + }, 25); + }); + it('original untouched', (done) => { var obj = {a: 'b', b: 'c', c: 'd'}; async.groupBy(obj, (val, next) => { @@ -205,6 +223,26 @@ describe('groupBy', function() { }); }); + it('canceled', (done) => { + var callOrder = []; + async.groupByLimit([1, 1, 2, 2, 3], 2, (val, next) => { + callOrder.push(val); + async.setImmediate(() => { + if (val === 2) { + return next(false, val+1); + } + next(null, val+1); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 1, 2, 2]); + done(); + }, 50); + }); + it('handles empty object', (done) => { async.groupByLimit({}, 2, (val, next) => { assert(false, 'iteratee should not be called'); @@ -319,6 +357,26 @@ describe('groupBy', function() { }); }); + it('canceled', (done) => { + var callOrder = []; + async.groupBySeries([1, 2, 3], (val, next) => { + callOrder.push(val); + async.setImmediate(() => { + if (val === 2) { + return next(false, val+1); + } + next(null, val+1); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 2]); + done(); + }, 50); + }); + it('handles arrays', (done) => { async.groupBySeries(['a', 'a', 'b'], (val, next) => { next(null, val); diff --git a/test/map.js b/test/map.js index 484e654..b6bf6e2 100644 --- a/test/map.js +++ b/test/map.js @@ -103,6 +103,23 @@ describe("map", () => { setTimeout(done, 50); }); + it('map canceled', (done) => { + var call_order = []; + async.map([1, 2, 3], (x, callback) => { + call_order.push(x); + if (x === 2) { + return callback(false, x * 2); + } + callback(null, x * 2); + }, () => { + throw new Error('should not get here'); + }); + setTimeout(() => { + expect(call_order).to.eql([1, 2, 3]); + done(); + }, 25); + }); + it('map undefined array', (done) => { async.map(undefined, (x, callback) => { callback(); @@ -149,6 +166,25 @@ describe("map", () => { setTimeout(done, 50); }); + it('mapSeries canceled', (done) => { + var call_order = []; + async.mapSeries([1, 2, 3], (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false, x * 2); + } + callback(null, x * 2); + }); + }, () => { + throw new Error('should not get here'); + }); + setTimeout(() => { + expect(call_order).to.eql([1, 2]); + done(); + }, 50); + }); + it('mapSeries undefined array', (done) => { async.mapSeries(undefined, (x, callback) => { callback(); @@ -251,6 +287,25 @@ describe("map", () => { setTimeout(done, 25); }); + it('mapLimit canceled', (done) => { + var call_order = []; + async.mapLimit([1, 2, 3, 4, 5], 2, (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 3) { + return callback(false, x * 2); + } + callback(null, x * 2); + }); + }, () => { + throw new Error('should not get here'); + }); + setTimeout(() => { + expect(call_order).to.eql([1, 2, 3, 4]); + done(); + }, 50); + }); + it('mapLimit does not continue replenishing after error', (done) => { var started = 0; var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; diff --git a/test/mapValues.js b/test/mapValues.js index 9f49840..3264337 100644 --- a/test/mapValues.js +++ b/test/mapValues.js @@ -2,7 +2,7 @@ var async = require('../lib'); var {expect} = require('chai'); describe('mapValues', () => { - var obj = {a: 1, b: 2, c: 3}; + var obj = {a: 1, b: 2, c: 3, d: 4}; context('mapValuesLimit', () => { it('basics', (done) => { @@ -10,7 +10,8 @@ describe('mapValues', () => { var concurrency = { a: 2, b: 2, - c: 1 + c: 2, + d: 1 }; async.mapValuesLimit(obj, 2, (val, key, next) => { running++; @@ -22,7 +23,7 @@ describe('mapValues', () => { }, (err, result) => { expect(running).to.equal(0); expect(err).to.eql(null); - expect(result).to.eql({a: 'a1', b: 'b2', c: 'c3'}); + expect(result).to.eql({a: 'a1', b: 'b2', c: 'c3', d: 'd4'}); done(); }); }); @@ -39,15 +40,36 @@ describe('mapValues', () => { done(); }); }); + + it('canceled', (done) => { + var callOrder = []; + async.mapValuesLimit(obj, 2, (val, key, next) => { + callOrder.push(val, key); + async.setImmediate(() => { + if (key === 'b') { + return next(false); + } + next(null, val); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 'a', 2, 'b', 3, 'c']); + done(); + }, 50); + }); }); context('mapValues', () => { it('basics', (done) => { var running = 0; var concurrency = { - a: 3, - b: 2, - c: 1 + a: 4, + b: 3, + c: 2, + d: 1 }; async.mapValues(obj, (val, key, next) => { running++; @@ -59,10 +81,28 @@ describe('mapValues', () => { }, (err, result) => { expect(running).to.equal(0); expect(err).to.eql(null); - expect(result).to.eql({a: 'a1', b: 'b2', c: 'c3'}); + expect(result).to.eql({a: 'a1', b: 'b2', c: 'c3', d: 'd4'}); done(); }); }); + + it('canceled', (done) => { + var callOrder = []; + async.mapValues(obj, (val, key, next) => { + callOrder.push(val, key); + if (key === 'b') { + return next(false, val); + } + next(null, val); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 'a', 2, 'b']); + done(); + }, 25); + }); }); context('mapValuesSeries', () => { @@ -71,7 +111,8 @@ describe('mapValues', () => { var concurrency = { a: 1, b: 1, - c: 1 + c: 1, + d: 1 }; async.mapValuesSeries(obj, (val, key, next) => { running++; @@ -83,9 +124,29 @@ describe('mapValues', () => { }, (err, result) => { expect(running).to.equal(0); expect(err).to.eql(null); - expect(result).to.eql({a: 'a1', b: 'b2', c: 'c3'}); + expect(result).to.eql({a: 'a1', b: 'b2', c: 'c3', d: 'd4'}); done(); }); }); + + it('canceled', (done) => { + var callOrder = []; + async.mapValuesSeries(obj, (val, key, next) => { + callOrder.push(val, key); + async.setImmediate(() => { + if (key === 'b') { + return next(false, val); + } + next(null, val); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(callOrder).to.eql([1, 'a', 2, 'b']); + done(); + }, 50); + }); }); }); diff --git a/test/parallel.js b/test/parallel.js index d53a8c6..ad1f44e 100644 --- a/test/parallel.js +++ b/test/parallel.js @@ -58,6 +58,27 @@ describe('parallel', () => { setTimeout(done, 100); }); + it('parallel canceled', (done) => { + var call_order = []; + async.parallel([ + function(callback) { + call_order.push('one'); + callback(false); + }, + function(callback){ + call_order.push('two'); + callback(null); + } + ], () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql(['one', 'two']); + done(); + }, 25); + }); + it('parallel no callback', (done) => { async.parallel([ function(callback){callback();}, diff --git a/test/reduce.js b/test/reduce.js index 1184b52..6f0c82c 100644 --- a/test/reduce.js +++ b/test/reduce.js @@ -35,6 +35,21 @@ describe('reduce', () => { setTimeout(done, 50); }); + it('reduce canceled', (done) => { + var call_order = []; + async.reduce([1,2,3], 0, (a, x, callback) => { + call_order.push(x); + callback(x === 2 ? false : null, a + x) + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1, 2]); + done(); + }, 25); + }); + it('inject alias', (done) => { expect(async.inject).to.equal(async.reduce); done(); @@ -59,6 +74,21 @@ describe('reduce', () => { }); }); + it('reduceRight canceled', (done) => { + var call_order = []; + async.reduceRight([1,2,3], 0, (a, x, callback) => { + call_order.push(x); + callback(x === 2 ? false : null, a + x) + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3, 2]); + done(); + }, 25); + }); + it('foldr alias', (done) => { expect(async.foldr).to.equal(async.reduceRight); done(); diff --git a/test/retryable.js b/test/retryable.js index e18afdc..0107e53 100644 --- a/test/retryable.js +++ b/test/retryable.js @@ -81,4 +81,20 @@ describe('retryable', () => { done(); }); }); + + it('should be cancelable', (done) => { + var calls = 0; + var retryableTask = async.retryable(3, (_, cb) => { + calls++; + cb(calls > 1 ? false : 'fail'); + }); + retryableTask('foo', () => { + throw new Error('should not get here'); + }) + + setTimeout(() => { + expect(calls).to.equal(2); + done(); + }, 25); + }); }); diff --git a/test/seq.js b/test/seq.js index cbb7634..09d8bee 100644 --- a/test/seq.js +++ b/test/seq.js @@ -62,6 +62,31 @@ describe('seq', () => { }); }); + it('seq canceled', (done) => { + var call_order = []; + + var add2 = function (n, cb) { + call_order.push('add2'); + cb(null, n + 2); + }; + var mul3 = function (n, cb) { + call_order.push('mul3'); + cb(false, n * 3); + }; + var add1 = function () { + throw new Error('add1 - should not get here'); + }; + var add2mul3add1 = async.seq(add2, mul3, add1); + add2mul3add1(3, () => { + throw new Error('final callback - should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql(['add2', 'mul3']); + done(); + }, 25); + }); + it('seq binding', (done) => { var testcontext = {name: 'foo'}; diff --git a/test/series.js b/test/series.js index a7c7d93..2b24c6f 100644 --- a/test/series.js +++ b/test/series.js @@ -92,6 +92,22 @@ describe('series', () => { setTimeout(done, 100); }); + it('canceled', (done) => { + async.series([ + function(callback) { + callback(false, 1); + }, + function(callback) { + assert(false, 'second function should not be called'); + callback('error2', 2); + } + ], () => { + assert(false, 'final callback should not be called'); + }); + + setTimeout(done, 25); + }); + it('error with reflect', (done) => { async.series([ async.reflect((callback) => { diff --git a/test/some.js b/test/some.js index 676797a..b5ca29d 100644 --- a/test/some.js +++ b/test/some.js @@ -50,6 +50,24 @@ describe("some", () => { }); }); + it('some canceled', (done) => { + var call_order = []; + async.some([3,1,2], (x, callback) => { + call_order.push(x); + if (x === 1) { + return callback(false); + } + callback(); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([3, 1, 2]); + done(); + }, 25); + }); + it('some no callback', (done) => { var calls = []; @@ -84,6 +102,46 @@ describe("some", () => { }); }); + it('someLimit canceled', (done) => { + var call_order = []; + async.someLimit([1,1,2,2,3], 2, (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false); + } + callback(); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1, 1, 2, 2,]); + done(); + }, 50); + }); + + it('someSeries canceled', (done) => { + var call_order = []; + async.someSeries([1, 2, 3], (x, callback) => { + call_order.push(x); + async.setImmediate(() => { + if (x === 2) { + return callback(false); + } + callback(); + }); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1, 2]); + done(); + }, 50); + }); + it('someLimit short-circuit', (done) => { var calls = 0; async.someLimit([3,1,2], 1, (x, callback) => { diff --git a/test/sortBy.js b/test/sortBy.js index 8f4afe3..28dbad6 100644 --- a/test/sortBy.js +++ b/test/sortBy.js @@ -33,4 +33,22 @@ describe('sortBy', () => { done(); }); }); + + it('sortBy canceled', (done) => { + var call_order = []; + async.sortBy([{a:1},{a:15},{a:6}], (x, callback) => { + call_order.push(x.a); + if (x.a === 15) { + return callback(false, x.a); + } + callback(null, x.a); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1, 15, 6]); + done(); + }, 25); + }); }); diff --git a/test/times.js b/test/times.js index f1c7f0a..f6371de 100644 --- a/test/times.js +++ b/test/times.js @@ -48,6 +48,24 @@ describe('times', () => { setTimeout(done, 50); }); + it('times canceled', (done) => { + var call_order = []; + async.times(5, (n, callback) => { + call_order.push(n); + if (n === 2) { + return callback(false, n); + } + callback(null, n); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([0,1,2]); + done(); + }, 25); + }); + it('timesSeries', (done) => { var call_order = []; async.timesSeries(5, (n, callback) => { @@ -71,6 +89,26 @@ describe('times', () => { setTimeout(done, 50); }); + it('timesSeries canceled', (done) => { + var call_order = []; + async.timesSeries(5, (n, callback) => { + call_order.push(n); + async.setImmediate(() => { + if (n === 2) { + return callback(false, n); + } + callback(null, n); + }) + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([0,1,2]); + done(); + }, 25); + }); + it('timesLimit', (done) => { var limit = 2; var running = 0; @@ -87,4 +125,24 @@ describe('times', () => { done(); }); }); + + it('timesLimit canceled', (done) => { + var call_order = []; + async.timesLimit(5, 2, (n, callback) => { + call_order.push(n); + async.setImmediate(() => { + if (n === 2) { + return callback(false, n); + } + callback(null, n); + }) + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([0,1,2,3]); + done(); + }, 25); + }); }); diff --git a/test/transform.js b/test/transform.js index 7a1c2e7..84781f4 100644 --- a/test/transform.js +++ b/test/transform.js @@ -52,6 +52,22 @@ describe('transform', () => { }); }); + it('transform canceled', (done) => { + var call_order = []; + async.transform([1,2,3], (a, v, k, callback) => { + call_order.push(v); + a.push(v + 1); + callback(v === 2 ? false : null); + }, () => { + throw new Error('should not get here'); + }); + + setTimeout(() => { + expect(call_order).to.eql([1, 2, 3]); + done(); + }, 25); + }); + it('transform with two arguments', (done) => { try { async.transform([1, 2, 3], (a, v, k, callback) => { diff --git a/test/tryEach.js b/test/tryEach.js index 6cc257e..7af25b5 100644 --- a/test/tryEach.js +++ b/test/tryEach.js @@ -82,5 +82,23 @@ describe('tryEach', () => { done(); }); }); -}); + it('canceled', (done) => { + var call_order = []; + async.tryEach([ + function(callback) { + call_order.push('task1'); + callback(false); + }, + function() { + assert.fail('task2 should not been called'); + } + ], () => { + assert.fail('should not been called'); + }); + setTimeout(() => { + expect(call_order).to.eql(['task1']); + done(); + }, 25); + }); +}); |