monkey patches eventemitter (2) with .onceall function, see test for usage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var EventEmitter2 = require('eventemitter2').EventEmitter2, | |
EEPatcher = require('../../src/util/eepatcher')(EventEmitter2), | |
util = require('util'), | |
should = require('should'), | |
emitter = new EventEmitter2({ | |
wildcard: false | |
}); | |
describe('eepatcher', function() { | |
describe('onceall', function() { | |
it('should exist', function() { | |
emitter.onceall.should.exist; | |
emitter.onceall.should.be.a('function'); | |
}); | |
it('should throw without a callback', function() { | |
(function() { | |
emitter.onceall('eventone', 'eventtwo'); | |
}).should.throw(); | |
}); | |
it('should throw with only a callback', function() { | |
(function() { | |
emitter.onceall(function() {}); | |
}).should.throw(); | |
}); | |
it('should function with one event', function(done) { | |
emitter.onceall('eventone', function() { | |
done(); | |
}); | |
emitter.emit('eventone'); | |
}); | |
it('should function with two events', function(done) { | |
var e1fired = false, | |
e2fired = false; | |
emitter.onceall('eventone', 'eventtwo', function() { | |
e1fired.should.be.true; | |
e2fired.should.be.true; | |
done(); | |
}); | |
emitter.emit('eventone'); | |
e1fired = true; | |
emitter.emit('eventtwo'); | |
e2fired = true; | |
}); | |
it('should ignore invalid events', function(done) { | |
emitter.onceall('eventone', 500, 'eventtwo', function() { | |
done(); | |
}); | |
emitter.emit('eventone'); | |
emitter.emit('eventtwo'); | |
}); | |
it('should ignore duplicate events', function(done) { | |
emitter.onceall('deventone', 'deventone', 'deventtwo', 'deventthree', function() { | |
done(); | |
}); | |
emitter.emit('deventone'); | |
emitter.emit('deventtwo'); | |
emitter.emit('deventthree'); | |
}); | |
it('should give arguments sequentially', function(done) { | |
var arg1 = "arg1", | |
arg2 = 100, | |
arg3 = "arg3", | |
arg4 = 20, | |
arg5 = null; | |
emitter.onceall('seqev1', 'seqev2', 'seqev3', function(_arg1, _arg2, _arg3, _arg4, _arg5) { | |
_arg1.should.eql(arg1); | |
_arg2.should.eql(arg2); | |
_arg3.should.eql(arg3); | |
_arg4.should.eql(arg4); | |
should.not.exist(_arg5); | |
done(); | |
}); | |
emitter.emit('seqev3', arg4, arg5); | |
emitter.emit('seqev1', arg1); | |
emitter.emit('seqev2', arg2, arg3); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = function(EventEmitter) { | |
//original object must be passed | |
if (!EventEmitter) throw new Error("you must pass the EventEmitter object"); | |
/* | |
* Register for all given events and wait for them all to have emitted at least once. | |
* | |
* @param {String} Any amount of events to listen for. | |
* @param {Function} Callback to be called when all events emitted, callback arguments are passed in the same order as the events. | |
* | |
* Ignores non-string or duplicate arguments except for the last argument which should be a function. | |
*/ | |
EventEmitter.prototype.onceall = function() { | |
if (arguments.length < 2) throw new Error('you must pass at least one event and callback'); | |
var cb = arguments[arguments.length-1]; | |
if (typeof(cb) !== 'function') throw new Error('you must pass a callback'); | |
var emitter = this; | |
//keep track of events | |
var events = [], | |
eargs = {}, | |
evl = 0, | |
evc = 0; | |
for (var i = 0, il = arguments.length; i < il - 1; i++) { | |
if (typeof(arguments[i]) !== 'string' || eargs[arguments[i]]) continue; | |
registerEvent(arguments[i]); | |
} | |
function registerEvent(event) { | |
evl++; | |
events.push(event); | |
eargs[event] = true; | |
emitter.once(event, function() { | |
eargs[event] = Array.prototype.slice.call(arguments); | |
process.nextTick(function() { | |
if (evl === ++evc) cb.apply(emitter, getArgs()); | |
}); | |
}); | |
} | |
function getArgs() { | |
var args = []; | |
for (var i = 0; i < evl; i++) { | |
args = args.concat(eargs[events[i]]); | |
} | |
return args; | |
} | |
}; | |
//this is just an untested draft, don't pay attention to it yet | |
EventEmitter.prototype.onall = function() { | |
var evargs = arguments, | |
cb = evargs[evargs.length-1], | |
emitter = this; | |
if (typeof(cb) !== 'function') throw new Error('onall must be passed a callback as last argument'); | |
cb = function() { | |
cb.apply(emitter, arguments); | |
emitter.onceall(evargs); | |
}; | |
emitter.onceall(evargs); | |
}; | |
//allow chaining | |
return EventEmitter; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment