From 63df4873a0b910c55dc9b8fede3bbf738b277de9 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Sat, 4 Apr 2015 14:57:26 +1100 Subject: [PATCH] Better callback misuse detection --- EventEmitterEx.js | 5 ++++- test/EventEmitterEx.test.js | 14 +++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/EventEmitterEx.js b/EventEmitterEx.js index d8f3838..4d8ccbb 100644 --- a/EventEmitterEx.js +++ b/EventEmitterEx.js @@ -138,13 +138,16 @@ } function callback (position, err/* arguments */) { + assert(! Array.isArray(result[position]), + 'Callback called more than once by function at position ' + position + ' (0-based)'); + if (err) { firstError = firstError || err; + result[position] = []; } else { result[position] = slice(arguments, 2); } len--; - assert(len >= 0, 'Callback called more than once for each mapAsync() function!'); if (! len) { if (firstError) { eex.emit('error', firstError); diff --git a/test/EventEmitterEx.test.js b/test/EventEmitterEx.test.js index 6af8a25..0abe79b 100644 --- a/test/EventEmitterEx.test.js +++ b/test/EventEmitterEx.test.js @@ -354,7 +354,19 @@ cb(null); expect(function () { cb(null); - }).to.throw(Error, 'Callback called more than once for each mapAsync() function!'); + }).to.throw(Error, 'Callback called more than once by function at position 0 (0-based)'); + done(); + }); + mapped.on('error', done); + emitter.emit('end'); + }); + + it('should throw if callback called too many times (with misbehaving callback)', function (done) { + var mapped = emitter.mapAsync(function () {/* bad function, does not call cb() */}, function (cb) { + cb(null); + expect(function () { + cb(null); + }).to.throw(Error, 'Callback called more than once by function at position 1 (0-based)'); done(); }); mapped.on('error', done);