Repository: caolan/async (js)
Issue: eachOfLimit with limit < 1 should error
Currently instantly resolves. I think this should be a case we throw an error in.

Pull request description: limits of less than 1 are now an error
Closes #1249

Patch:
diff --git a/lib/internal/eachOfLimit.js b/lib/internal/eachOfLimit.js
index ae153b1..2928366 100644
--- a/lib/internal/eachOfLimit.js
+++ b/lib/internal/eachOfLimit.js
@@ -9,7 +9,10 @@ import breakLoop from './breakLoop';
 export default function _eachOfLimit(limit) {
     return function (obj, iteratee, callback) {
         callback = once(callback || noop);
-        if (limit <= 0 || !obj) {
+        if (limit <= 0) {
+            throw new RangeError('concurrency limit cannot be less than 1')
+        }
+        if (!obj) {
             return callback(null);
         }
         var nextElem = iterator(obj);
diff --git a/lib/internal/queue.js b/lib/internal/queue.js
index 575497b..a421d2e 100644
--- a/lib/internal/queue.js
+++ b/lib/internal/queue.js
@@ -9,7 +9,7 @@ export default function queue(worker, concurrency, payload) {
         concurrency = 1;
     }
     else if(concurrency === 0) {
-        throw new Error('Concurrency must not be zero');
+        throw new RangeError('Concurrency must not be zero');
     }
 
     var _worker = wrapAsync(worker);


Test patch:
diff --git a/test/concat.js b/test/concat.js
index f6b73b3..75f8db7 100644
--- a/test/concat.js
+++ b/test/concat.js
@@ -293,15 +293,15 @@ describe('concat', function() {
             });
         });
 
-        it('zero limit', function(done) {
-            async.concatLimit([3, 2, 2, 1], 0, function(val, next) {
-                assert(false, 'iteratee should not be called');
-                next();
-            }, function(err, result) {
-                expect(err).to.eql(null);
-                expect(result).to.be.an('array').that.is.empty;
-                done();
-            });
+        it('zero limit', function() {
+            expect(() => {
+                async.concatLimit([3, 2, 2, 1], 0, function(val, next) {
+                    assert(false, 'iteratee should not be called');
+                    next();
+                }, function() {
+                    assert(false, 'callback should not be called');
+                });
+            }).to.throw(/limit/)
         });
 
         it('does not continue replenishing after error', function(done) {
diff --git a/test/each.js b/test/each.js
index 014e9df..ba5f3c4 100644
--- a/test/each.js
+++ b/test/each.js
@@ -199,15 +199,15 @@ describe("each", function() {
         });
     });
 
-    it('eachLimit zero limit', function(done) {
-        async.eachLimit([0,1,2,3,4,5], 0, function(x, callback){
-            assert(false, 'iteratee should not be called');
-            callback();
-        }, function(err){
-            if (err) throw err;
-            assert(true, 'should call callback');
-        });
-        setTimeout(done, 25);
+    it('eachLimit zero limit', function() {
+        expect(() => {
+            async.eachLimit([0,1,2,3,4,5], 0, function(x, callback){
+                assert(false, 'iteratee should not be called');
+                callback();
+            }, function(){
+                assert(false, 'should not call callback');
+            });
+        }).to.throw(/limit/)
     });
 
     it('eachLimit error', function(done) {
diff --git a/test/eachOf.js b/test/eachOf.js
index 7d80990..1701d3e 100644
--- a/test/eachOf.js
+++ b/test/eachOf.js
@@ -299,15 +299,15 @@ describe("eachOf", function() {
         });
     });
 
-    it('forEachOfLimit zero limit', function(done) {
-        async.forEachOfLimit({ a: 1, b: 2 }, 0, function(x, callback){
-            assert(false, 'iteratee should not be called');
-            callback();
-        }, function(err){
-            if (err) throw err;
-            assert(true, 'should call callback');
-        });
-        setTimeout(done, 25);
+    it('forEachOfLimit zero limit', function() {
+        expect(() => {
+            async.forEachOfLimit({ a: 1, b: 2 }, 0, function(x, callback){
+                assert(false, 'iteratee should not be called');
+                callback();
+            }, function(){
+                assert(true, 'should call callback');
+            });
+        }).to.throw(/concurrency limit/)
     });
 
     it('forEachOfLimit no limit', function(done) {
diff --git a/test/groupBy.js b/test/groupBy.js
index d20f385..796d353 100644
--- a/test/groupBy.js
+++ b/test/groupBy.js
@@ -247,15 +247,15 @@ describe('groupBy', function() {
             });
         });
 
-        it('zero limit', function(done) {
-            async.groupByLimit([3, 2, 2, 1], 0, function(val, next) {
-                assert(false, 'iteratee should not be called');
-                next();
-            }, function(err, result) {
-                expect(err).to.eql(null);
-                expect(result).to.eql({});
-                done();
-            });
+        it('zero limit', function() {
+            expect(() => {
+                async.groupByLimit([3, 2, 2, 1], 0, function(val, next) {
+                    assert(false, 'iteratee should not be called');
+                    next();
+                }, function() {
+                    assert(false, 'should not be called');
+                });
+            }).to.throw(/concurrency limit/)
         });
 
         it('does not continue replenishing after error', function(done) {
diff --git a/test/map.js b/test/map.js
index c7f5030..eb0c3ea 100644
--- a/test/map.js
+++ b/test/map.js
@@ -224,15 +224,15 @@ describe("map", function() {
         });
     });
 
-    it('mapLimit zero limit', function(done) {
-        async.mapLimit([0, 1, 2, 3, 4, 5], 0, function(x, callback) {
-            assert(false, 'iteratee should not be called');
-            callback();
-        }, function(err, results) {
-            expect(results).to.eql([]);
-            assert(true, 'should call callback');
-        });
-        setTimeout(done, 25);
+    it('mapLimit zero limit', function() {
+        expect(() => {
+            async.mapLimit([0, 1, 2, 3, 4, 5], 0, function(x, callback) {
+                assert(false, 'iteratee should not be called');
+                callback();
+            }, function() {
+                assert(false, 'should not be called');
+            });
+        }).to.throw(/concurrency limit/)
     });
 
     it('mapLimit error', function(done) {