Update app and tooling
This commit is contained in:
parent
3046531bdd
commit
e620ec7349
4950 changed files with 2975120 additions and 10 deletions
25
node_modules/events-intercept/.npmignore
generated
vendored
Normal file
25
node_modules/events-intercept/.npmignore
generated
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directory
|
||||
# Deployed apps should consider commenting this line out:
|
||||
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
|
||||
node_modules
|
||||
6
node_modules/events-intercept/.travis.yml
generated
vendored
Normal file
6
node_modules/events-intercept/.travis.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
|
||||
after_script: npm run coveralls
|
||||
21
node_modules/events-intercept/LICENSE
generated
vendored
Normal file
21
node_modules/events-intercept/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Brandon Horst
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
116
node_modules/events-intercept/README.md
generated
vendored
Normal file
116
node_modules/events-intercept/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
#`events-intercept`
|
||||
|
||||
[](https://travis-ci.org/brandonhorst/events-intercept)
|
||||
[](https://coveralls.io/r/brandonhorst/events-intercept?branch=master)
|
||||
|
||||
The node [EventEmitter](http://nodejs.org/api/events.html) is very powerful. However, at times it could be valuable to intercept events before they reach their handlers, to modify the data, or emit other events. That's a job for `event-intercept`.
|
||||
|
||||
##Installation
|
||||
|
||||
```sh
|
||||
npm install events-intercept
|
||||
```
|
||||
|
||||
##Standalone Usage
|
||||
|
||||
The module contains a constructor, `EventEmitter`, which inherits from the standard node `events.EventEmitter`.
|
||||
|
||||
var EventEmitter = require('events-intercept').EventEmitter;
|
||||
var emitter = new EventEmitter();
|
||||
|
||||
In our application, we have an object that will emit a `data` event, and pass it a single argument.
|
||||
|
||||
emitter.emit('data', 'myData')
|
||||
|
||||
It is very easy to listen for this event and handle it
|
||||
|
||||
emitter.on('data', function(arg) {
|
||||
console.log(arg);
|
||||
}); //logs 'myData'
|
||||
|
||||
However, we want to intercept that event and modify the data. We can do that by setting an `interceptor` with `intercept(event, interceptor)`. It is passed all arguments that would be passed to the emitter, as well as a standard node callback. In this case, let's just add a prefix on to the data.
|
||||
|
||||
emitter.intercept('data', function(arg, done) {
|
||||
return done(null, 'intercepted ' + arg);
|
||||
});
|
||||
|
||||
This code will be executed before the handler, and the new argument will be passed on to the handler appropriately.
|
||||
|
||||
emitter.emit('data', 'some other data');
|
||||
//logs 'intercepted some other data'
|
||||
|
||||
If multiple interceptors are added to a single event, they will be called in the order that they are added, like [async.waterfall](https://github.com/caolan/async#waterfall).
|
||||
|
||||
Here's that sample code all together. Of course, `intercept` supports proper function chaining.
|
||||
|
||||
var eventsIntercept = require('events-intercept');
|
||||
var emitter = new eventsIntercept.EventEmitter();
|
||||
|
||||
emitter
|
||||
.on('data', function(arg) {
|
||||
console.log(arg);
|
||||
}).intercept('data', function(arg, done) {
|
||||
return done(null, 'intercepted ' + arg);
|
||||
}).emit('data', 'myData');
|
||||
//logs 'intercepted myData'
|
||||
|
||||
Please see `test/intercept.js` for more complete samples.
|
||||
|
||||
##Calling Separate Events
|
||||
|
||||
There may be times when you want to intercept one event and call another. Luckily, all `intercept` handlers are called with the `EventEmitter` as the `this` context, so you can `emit` events yourself.
|
||||
|
||||
emitter.intercept('data', function(done) {
|
||||
this
|
||||
.emit('otherData')
|
||||
.emit('thirdData');
|
||||
return done(null);
|
||||
});
|
||||
//emits 'data', 'otherData', and 'thirdData'
|
||||
|
||||
Remember, `emit`ting an event that you are `intercept`ing will cause a loop, so be careful.
|
||||
|
||||
In fact, an `intercept`or do not need to call the callback at all, which means that the event that was `intercept`ed will never be called at all.
|
||||
|
||||
|
||||
emitter.intercept('data', function(done) {
|
||||
this
|
||||
.emit('otherData')
|
||||
.emit('thirdData');
|
||||
});
|
||||
//emits 'otherData' and 'thirdData' but not 'data'
|
||||
|
||||
##Utilities
|
||||
|
||||
`events-intercept` supports all of the useful utilities that the standard `EventEmitter` supports:
|
||||
|
||||
* `interceptors(type)` returns an array of all interceptors (functions) for the given type.
|
||||
* `removeInterceptor(type, interceptor)` removes an interceptor of a given type. You must pass in the interceptor function.
|
||||
* `removeAllInterceptors(type)` removes all interceptors for a given type.
|
||||
* `removeAllInterceptors()` removes all interceptors. Will remove the `removeInterceptor` event last, so they will all get triggered.
|
||||
* the EventEmitter will throw a warning if more than 10 interceptors are added to a single event, as this could represent a memory leak. `setMaxInterceptors(n)` allows you to change that. Set it to 0 for no limit.
|
||||
|
||||
All of these are demonstrated in the tests.
|
||||
|
||||
##Patching
|
||||
|
||||
Of course, many EventEmitters that you have the pleasure of using will not have the foresight to use `event-intercept`. Thankfully, Javascript is awesome, it's possible to monkey patch the interception capabilities onto an existing object. Just call
|
||||
|
||||
var events = require('events');
|
||||
var eventsIntercept = require('events-intercept');
|
||||
|
||||
var emitter = new events.EventEmitter();
|
||||
|
||||
eventsIntercept.patch(emitter)
|
||||
|
||||
emitter
|
||||
.on('data', function(arg) {
|
||||
console.log(arg);
|
||||
}).intercept('data', function(arg, done) {
|
||||
return done(null, 'intercepted ' + arg);
|
||||
}).emit('data', 'myData');
|
||||
//logs 'intercepted myData'
|
||||
|
||||
Now, you should be able to call `intercept` on the standard `EventEmitter`.
|
||||
|
||||
This is also shown in `test/intercept.js`.
|
||||
228
node_modules/events-intercept/lib/events-intercept.js
generated
vendored
Normal file
228
node_modules/events-intercept/lib/events-intercept.js
generated
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
(function () {
|
||||
|
||||
var events = require('events');
|
||||
var util = require('util');
|
||||
|
||||
function intercept(type, interceptor) {
|
||||
var m;
|
||||
|
||||
if (typeof interceptor !== 'function') {
|
||||
throw new TypeError('interceptor must be a function');
|
||||
}
|
||||
|
||||
this.emit('newInterceptor', type, interceptor);
|
||||
|
||||
if (!this._interceptors[type]) {
|
||||
this._interceptors[type] = [interceptor];
|
||||
} else {
|
||||
this._interceptors[type].push(interceptor);
|
||||
}
|
||||
|
||||
// Check for listener leak
|
||||
if (!this._interceptors[type].warned) {
|
||||
if (typeof this._maxInterceptors !== 'undefined') {
|
||||
m = this._maxInterceptors;
|
||||
} else {
|
||||
m = EventEmitter.defaultMaxInterceptors;
|
||||
}
|
||||
|
||||
if (m && m > 0 && this._interceptors[type].length > m) {
|
||||
this._interceptors[type].warned = true;
|
||||
console.error('(node) warning: possible events-intercept EventEmitter memory ' +
|
||||
'leak detected. %d interceptors added. ' +
|
||||
'Use emitter.setMaxInterceptors(n) to increase limit.',
|
||||
this._interceptors[type].length);
|
||||
console.trace();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
function emitFactory(superCall) {
|
||||
return function (type) {
|
||||
var completed,
|
||||
interceptor,
|
||||
_this = this;
|
||||
|
||||
function next(err) {
|
||||
var trueArgs;
|
||||
if (err) {
|
||||
_this.emit('error', err);
|
||||
} else if (completed === interceptor.length) {
|
||||
return superCall.apply(_this, [type].concat(Array.prototype.slice.call(arguments).slice(1)));
|
||||
} else {
|
||||
trueArgs = Array.prototype.slice.call(arguments).slice(1).concat([next]);
|
||||
completed += 1;
|
||||
return interceptor[completed - 1].apply(_this, trueArgs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_this._interceptors) {
|
||||
_this._interceptors = {};
|
||||
}
|
||||
|
||||
interceptor = _this._interceptors[type];
|
||||
|
||||
if (!interceptor) {
|
||||
|
||||
//Just pass through
|
||||
return superCall.apply(_this, arguments);
|
||||
|
||||
} else {
|
||||
|
||||
completed = 0;
|
||||
return next.apply(_this, [null].concat(Array.prototype.slice.call(arguments).slice(1)));
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function interceptors(type) {
|
||||
var ret;
|
||||
|
||||
if (!this._interceptors || !this._interceptors[type]) {
|
||||
ret = [];
|
||||
} else {
|
||||
ret = this._interceptors[type].slice();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function removeInterceptor(type, interceptor) {
|
||||
var list, position, length, i;
|
||||
|
||||
if (typeof interceptor !== 'function') {
|
||||
throw new TypeError('interceptor must be a function');
|
||||
}
|
||||
|
||||
if (!this._interceptors || !this._interceptors[type]) {
|
||||
return this;
|
||||
}
|
||||
|
||||
list = this._interceptors[type];
|
||||
length = list.length;
|
||||
position = -1;
|
||||
|
||||
for (i = length - 1; i >= 0; i--) {
|
||||
if (list[i] === interceptor) {
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (position < 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (length === 1) {
|
||||
delete this._interceptors[type];
|
||||
} else {
|
||||
list.splice(position, 1);
|
||||
}
|
||||
|
||||
this.emit('removeInterceptor', type, interceptor);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
function listenersFactory(superCall) {
|
||||
return function (type) {
|
||||
var superListeners = superCall.call(this, type);
|
||||
var fakeFunctionIndex;
|
||||
var tempSuperListeners = superListeners.slice();
|
||||
if (type === 'newListener' || type === 'removeListener') {
|
||||
fakeFunctionIndex = superListeners.indexOf(fakeFunction);
|
||||
if (fakeFunctionIndex !== -1) {
|
||||
tempSuperListeners.splice(fakeFunctionIndex, 1);
|
||||
}
|
||||
return tempSuperListeners;
|
||||
}
|
||||
return superListeners;
|
||||
};
|
||||
}
|
||||
|
||||
function fakeFunction() {}
|
||||
|
||||
function fixListeners(emitter) {
|
||||
emitter.on('newListener', fakeFunction);
|
||||
emitter.on('removeListener', fakeFunction);
|
||||
}
|
||||
|
||||
function setMaxInterceptors(n) {
|
||||
if (typeof n !== 'number' || n < 0 || isNaN(n)) {
|
||||
throw new TypeError('n must be a positive number');
|
||||
}
|
||||
this._maxInterceptors = n;
|
||||
return this;
|
||||
}
|
||||
|
||||
function removeAllInterceptors(type) {
|
||||
var key, theseInterceptors, length, i;
|
||||
|
||||
if (!this._interceptors || Object.getOwnPropertyNames(this._interceptors).length === 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (arguments.length === 0) {
|
||||
|
||||
for (key in this._interceptors) {
|
||||
if (this._interceptors.hasOwnProperty(key) && key !== 'removeInterceptor') {
|
||||
this.removeAllInterceptors(key);
|
||||
}
|
||||
}
|
||||
this.removeAllInterceptors('removeInterceptor');
|
||||
this._interceptors = {};
|
||||
|
||||
} else if (this._interceptors[type]) {
|
||||
theseInterceptors = this._interceptors[type];
|
||||
length = theseInterceptors.length;
|
||||
|
||||
// LIFO order
|
||||
for (i = length - 1; i >= 0; i--) {
|
||||
this.removeInterceptor(type, theseInterceptors[i]);
|
||||
}
|
||||
|
||||
delete this._interceptors[type];
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
function EventEmitter() {
|
||||
events.EventEmitter.call(this);
|
||||
fixListeners(this);
|
||||
}
|
||||
|
||||
util.inherits(EventEmitter, events.EventEmitter);
|
||||
|
||||
EventEmitter.prototype.intercept = intercept;
|
||||
EventEmitter.prototype.emit = emitFactory(EventEmitter.super_.prototype.emit);
|
||||
EventEmitter.prototype.interceptors = interceptors;
|
||||
EventEmitter.prototype.removeInterceptor = removeInterceptor;
|
||||
EventEmitter.prototype.removeAllInterceptors = removeAllInterceptors;
|
||||
EventEmitter.prototype.setMaxInterceptors = setMaxInterceptors;
|
||||
EventEmitter.prototype.listeners = listenersFactory(EventEmitter.super_.prototype.listeners);
|
||||
EventEmitter.defaultMaxInterceptors = 10;
|
||||
|
||||
function monkeyPatch(emitter) {
|
||||
var oldEmit = emitter.emit;
|
||||
var oldListeners = emitter.listeners;
|
||||
|
||||
emitter.emit = emitFactory(oldEmit);
|
||||
emitter.intercept = intercept;
|
||||
emitter.interceptors = interceptors;
|
||||
emitter.removeInterceptor = removeInterceptor;
|
||||
emitter.removeAllInterceptors = removeAllInterceptors;
|
||||
emitter.setMaxInterceptors = setMaxInterceptors;
|
||||
emitter.listeners = listenersFactory(oldListeners);
|
||||
fixListeners(emitter);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
EventEmitter: EventEmitter,
|
||||
patch: monkeyPatch
|
||||
};
|
||||
|
||||
})();
|
||||
40
node_modules/events-intercept/package.json
generated
vendored
Normal file
40
node_modules/events-intercept/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "events-intercept",
|
||||
"version": "2.0.0",
|
||||
"description": "event interceptors - like middleware for EventEmitter",
|
||||
"main": "lib/events-intercept.js",
|
||||
"scripts": {
|
||||
"test": "mocha test",
|
||||
"posttest": "istanbul cover _mocha -- -R spec",
|
||||
"coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/brandonhorst/events-intercept.git"
|
||||
},
|
||||
"keywords": [
|
||||
"event",
|
||||
"events",
|
||||
"emit",
|
||||
"intercept",
|
||||
"tap",
|
||||
"hook",
|
||||
"report",
|
||||
"mutate",
|
||||
"EventEmitter"
|
||||
],
|
||||
"author": "@brandonhorst",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/brandonhorst/events-intercept/issues"
|
||||
},
|
||||
"homepage": "https://github.com/brandonhorst/events-intercept",
|
||||
"devDependencies": {
|
||||
"chai": "^1.10.0",
|
||||
"coveralls": "^2.11.2",
|
||||
"istanbul": "^0.3.5",
|
||||
"mocha": "^2.1.0",
|
||||
"sinon": "^1.12.2",
|
||||
"sinon-chai": "^2.6.0"
|
||||
}
|
||||
}
|
||||
87
node_modules/events-intercept/test/emit_return.js
generated
vendored
Normal file
87
node_modules/events-intercept/test/emit_return.js
generated
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
var chai = require('chai'),
|
||||
assert = chai.assert.equal,
|
||||
eventsIntercept = require('../lib/events-intercept'),
|
||||
events = require('events');
|
||||
|
||||
describe('patched event emitters', function () {
|
||||
describe('with no intercepts', function () {
|
||||
it('returns true if an event had handlers', function () {
|
||||
var ee = new events.EventEmitter();
|
||||
eventsIntercept.patch(ee);
|
||||
|
||||
ee.on('foo', function () {});
|
||||
|
||||
assert(ee.emit('foo'), true, "emit('foo') is true");
|
||||
});
|
||||
|
||||
it('returns false if an event had no handlers', function () {
|
||||
var ee = new events.EventEmitter();
|
||||
eventsIntercept.patch(ee);
|
||||
ee.on('foo', function () {});
|
||||
|
||||
assert(ee.emit('bar'), false, "emit('bar') is false");
|
||||
});
|
||||
});
|
||||
|
||||
describe('with the event intercepted', function () {
|
||||
it('returns true if an event had handlers', function () {
|
||||
var ee = new events.EventEmitter();
|
||||
eventsIntercept.patch(ee);
|
||||
|
||||
var intercepted = false;
|
||||
var handled = false;
|
||||
|
||||
ee.on('foo', function () { handled = true; });
|
||||
ee.intercept('foo', function (next) { intercepted = true; return next(); });
|
||||
|
||||
assert(ee.emit('foo'), true, "emit('foo') returns true");
|
||||
assert(intercepted, true, "interceptor was invoked");
|
||||
assert(handled, true, "handler was invoked");
|
||||
});
|
||||
|
||||
it('returns false if an event had no handlers', function () {
|
||||
var ee = new events.EventEmitter();
|
||||
eventsIntercept.patch(ee);
|
||||
|
||||
var intercepted = false;
|
||||
|
||||
ee.intercept('bar', function (next) { intercepted = true; return next(); });
|
||||
|
||||
assert(ee.emit('bar'), false, "emit('bar') returns false");
|
||||
assert(intercepted, true, "interceptor was called");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('events-intercept event emitters', function () {
|
||||
it('returns true if an event had handlers', function () {
|
||||
var ee = new eventsIntercept.EventEmitter();
|
||||
ee.on('foo', function () {});
|
||||
|
||||
assert(ee.emit('foo'), true, "emit('foo') is true");
|
||||
});
|
||||
|
||||
it('returns false if an event had no handlers', function () {
|
||||
var ee = new eventsIntercept.EventEmitter();
|
||||
eventsIntercept.patch(ee);
|
||||
ee.on('foo', function () {});
|
||||
|
||||
assert(ee.emit('bar'), false, "emit('bar') is false");
|
||||
});
|
||||
|
||||
describe('with the event intercepted', function () {
|
||||
it('returns true if an event had handlers', function () {
|
||||
var ee = new eventsIntercept.EventEmitter();
|
||||
|
||||
var intercepted = false;
|
||||
var handled = false;
|
||||
|
||||
ee.on('foo', function () { handled = true; });
|
||||
ee.intercept('foo', function (next) { intercepted = true; return next(); });
|
||||
|
||||
assert(ee.emit('foo'), true, "emit('foo') returns true");
|
||||
assert(intercepted, true, "interceptor was invoked");
|
||||
assert(handled, true, "handler was invoked");
|
||||
});
|
||||
});
|
||||
});
|
||||
485
node_modules/events-intercept/test/intercept.js
generated
vendored
Normal file
485
node_modules/events-intercept/test/intercept.js
generated
vendored
Normal file
|
|
@ -0,0 +1,485 @@
|
|||
var chai = require('chai'),
|
||||
expect = chai.expect,
|
||||
sinon = require('sinon'),
|
||||
eventsIntercept = require('../lib/events-intercept'),
|
||||
events = require('events'),
|
||||
emitterFactories;
|
||||
|
||||
chai.use(require('sinon-chai'));
|
||||
chai.config.includeStack = true;
|
||||
|
||||
emitterFactories = {
|
||||
"events-intercept EventEmitter": function() {return new eventsIntercept.EventEmitter()},
|
||||
"patched classic EventEmitter": function() {
|
||||
var classicEmitter = new events.EventEmitter();
|
||||
eventsIntercept.patch(classicEmitter);
|
||||
return classicEmitter;
|
||||
}
|
||||
}
|
||||
|
||||
for (description in emitterFactories) {
|
||||
|
||||
var emitterFactory = emitterFactories[description];
|
||||
|
||||
(function(emitterFactory) {
|
||||
|
||||
describe(description, function() {
|
||||
it('intercepts an event with a single interceptor', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
handler,
|
||||
interceptor;
|
||||
|
||||
handler = function(arg) {
|
||||
expect(interceptor).to.have.been.called.once;
|
||||
expect(arg).to.equal('newValue');
|
||||
done();
|
||||
};
|
||||
|
||||
interceptor = sinon.spy(function(arg, done) {
|
||||
expect(arg).to.equal('value');
|
||||
done(null, 'newValue');
|
||||
});
|
||||
|
||||
|
||||
emitter
|
||||
.intercept('test', interceptor)
|
||||
.on('test', handler)
|
||||
.emit('test', 'value');
|
||||
});
|
||||
|
||||
it('intercepts an event with a multiple interceptors', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
handler,
|
||||
interceptor1,
|
||||
interceptor2,
|
||||
interceptor3;
|
||||
|
||||
handler = function(arg) {
|
||||
expect(interceptor1).to.have.been.called.once;
|
||||
expect(interceptor2).to.have.been.called.once;
|
||||
expect(interceptor3).to.have.been.called.once;
|
||||
expect(arg).to.equal('finalValue');
|
||||
done();
|
||||
};
|
||||
|
||||
interceptor1 = sinon.spy(function(arg, done) {
|
||||
expect(arg).to.equal('value');
|
||||
done(null, 'secondValue', 'anotherValue');
|
||||
});
|
||||
|
||||
interceptor2 = sinon.spy(function(arg, arg2, done) {
|
||||
expect(arg).to.equal('secondValue');
|
||||
expect(arg2).to.equal('anotherValue');
|
||||
done(null, 'thirdValue');
|
||||
});
|
||||
|
||||
interceptor3 = sinon.spy(function(arg, done) {
|
||||
expect(arg).to.equal('thirdValue');
|
||||
done(null, 'finalValue');
|
||||
});
|
||||
|
||||
|
||||
emitter
|
||||
.on('test', handler)
|
||||
.intercept('test', interceptor1)
|
||||
.intercept('test', interceptor2)
|
||||
.intercept('test', interceptor3)
|
||||
.emit('test', 'value');
|
||||
});
|
||||
|
||||
it('warns once for 11+ interceptors (by default)', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
handler,
|
||||
interceptors = [],
|
||||
i;
|
||||
|
||||
for (i=0; i < 12; i++) {
|
||||
interceptors[i] = sinon.spy(function(done) {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
handler = function(arg) {
|
||||
for (i=0; i < 12; i++) {
|
||||
expect(interceptors[i]).to.have.been.called.once;
|
||||
}
|
||||
expect(console.error).to.have.been.called.once;
|
||||
expect(console.trace).to.have.been.called.once;
|
||||
console.error.restore();
|
||||
console.trace.restore();
|
||||
done()
|
||||
}
|
||||
|
||||
sinon.stub(console, "error");
|
||||
sinon.stub(console, "trace");
|
||||
|
||||
emitter
|
||||
.on('test', handler);
|
||||
for (i=0; i < 12; i++) {
|
||||
emitter.intercept('test', interceptors[i]);
|
||||
}
|
||||
emitter.emit('test');
|
||||
});
|
||||
|
||||
it('allows for setting the maxInterceptors', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
handler,
|
||||
interceptors = [],
|
||||
i;
|
||||
|
||||
for (i=0; i < 6; i++) {
|
||||
interceptors[i] = sinon.spy(function(done) {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
handler = function(arg) {
|
||||
for (i=0; i < 6; i++) {
|
||||
expect(interceptors[i]).to.have.been.called.once;
|
||||
}
|
||||
expect(console.error).to.have.been.called.once;
|
||||
expect(console.trace).to.have.been.called.once;
|
||||
console.error.restore();
|
||||
console.trace.restore();
|
||||
done()
|
||||
}
|
||||
|
||||
sinon.stub(console, "error");
|
||||
sinon.stub(console, "trace");
|
||||
|
||||
emitter
|
||||
.setMaxInterceptors(5)
|
||||
.on('test', handler);
|
||||
for (i=0; i < 6; i++) {
|
||||
emitter.intercept('test', interceptors[i]);
|
||||
}
|
||||
emitter.emit('test');
|
||||
});
|
||||
|
||||
it('throws for invalid maxInterceptors', function() {
|
||||
var emitter = emitterFactory();
|
||||
|
||||
expect(function() {
|
||||
emitter.setMaxInterceptors('not a number');
|
||||
}).to.throw(Error);
|
||||
});
|
||||
|
||||
it('triggers an error when an interceptor passes one', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
handler = sinon.spy(),
|
||||
interceptor,
|
||||
errorHandler;
|
||||
|
||||
interceptor = sinon.spy(function(arg, done) {
|
||||
expect(arg).to.equal('value')
|
||||
done(new Error('test error'));
|
||||
});
|
||||
|
||||
errorHandler = function(err) {
|
||||
expect(interceptor).to.have.been.called.once;
|
||||
expect(handler).to.not.have.been.called;
|
||||
expect(err.message).to.equal('test error');
|
||||
done();
|
||||
};
|
||||
|
||||
|
||||
emitter
|
||||
.on('test', handler)
|
||||
.intercept('test', interceptor)
|
||||
.on('error', errorHandler)
|
||||
.emit('test', 'value');
|
||||
});
|
||||
|
||||
it('allows interceptors to trigger other events', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
handler = sinon.spy(),
|
||||
interceptor,
|
||||
errorHandler;
|
||||
|
||||
interceptor = sinon.spy(function(arg, done) {
|
||||
expect(arg).to.equal('value')
|
||||
this.emit('newTest', 'newValue')
|
||||
});
|
||||
|
||||
newHandler = (function(arg) {
|
||||
expect(arg).to.equal('newValue');
|
||||
expect(interceptor).to.have.been.called.once;
|
||||
expect(handler).to.not.have.been.called;
|
||||
done();
|
||||
});
|
||||
|
||||
emitter
|
||||
.on('test', handler)
|
||||
.on('newTest', newHandler)
|
||||
.intercept('test', interceptor)
|
||||
.emit('test', 'value');
|
||||
});
|
||||
|
||||
// it('can monkey patch standard EventEmitters', function(done) {
|
||||
// var emitter = new events.EventEmitter(),
|
||||
// handler,
|
||||
// interceptor;
|
||||
|
||||
// handler = function(arg) {
|
||||
// expect(interceptor).to.have.been.called.once;
|
||||
// expect(arg).to.equal('newValue');
|
||||
// done();
|
||||
// };
|
||||
|
||||
// interceptor = sinon.spy(function(arg, done) {
|
||||
// expect(arg).to.equal('value');
|
||||
// done(null, 'newValue');
|
||||
// });
|
||||
|
||||
// eventsIntercept.patch(emitter);
|
||||
|
||||
// emitter
|
||||
// .on('test', handler)
|
||||
// .intercept('test', interceptor)
|
||||
// .emit('test', 'value');
|
||||
// });
|
||||
|
||||
it('behaves as before for events without interceptors', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
handler;
|
||||
|
||||
handler = function(arg) {
|
||||
expect(arg).to.equal('value');
|
||||
done();
|
||||
};
|
||||
|
||||
emitter
|
||||
.on('test', handler)
|
||||
.emit('test', 'value');
|
||||
});
|
||||
|
||||
it('throws for interceptors that are not functions', function() {
|
||||
var emitter = emitterFactory(),
|
||||
interceptCall;
|
||||
|
||||
interceptCall = function() {
|
||||
emitter.intercept('test', 'not a function');
|
||||
};
|
||||
|
||||
expect(interceptCall).to.throw(Error);
|
||||
});
|
||||
|
||||
it('emits newInterceptor for new interceptors', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
interceptor = function() {},
|
||||
newInterceptorCall;
|
||||
|
||||
newInterceptorCall = function(event, _interceptor) {
|
||||
expect(event).to.equal('test');
|
||||
expect(_interceptor).to.equal(interceptor);
|
||||
done()
|
||||
}
|
||||
|
||||
emitter
|
||||
.on('newInterceptor', newInterceptorCall)
|
||||
.intercept('test', interceptor);
|
||||
});
|
||||
|
||||
it('lists all interceptors', function() {
|
||||
var emitter = emitterFactory(),
|
||||
interceptor1 = function() {},
|
||||
interceptor2 = function() {};
|
||||
|
||||
expect(emitter.interceptors('test'), '0').to.deep.equal([]);
|
||||
|
||||
emitter.intercept('test', interceptor1);
|
||||
expect(emitter.interceptors('test'), '1').to.deep.equal([interceptor1]);
|
||||
|
||||
emitter.intercept('test', interceptor2);
|
||||
expect(emitter.interceptors('test'), '2').to.deep.equal([interceptor1, interceptor2]);
|
||||
});
|
||||
|
||||
it('removes an interceptor', function() {
|
||||
var emitter = emitterFactory(),
|
||||
interceptor1 = function() {},
|
||||
interceptor2 = function() {},
|
||||
notAnInterceptor = function() {};
|
||||
|
||||
emitter
|
||||
.intercept('test', interceptor1)
|
||||
.intercept('test', interceptor2);
|
||||
expect(emitter.interceptors('test'), '2').to.deep.equal([interceptor1, interceptor2]);
|
||||
|
||||
emitter.removeInterceptor('test', interceptor1);
|
||||
expect(emitter.interceptors('test'), '1').to.deep.equal([interceptor2]);
|
||||
|
||||
emitter.removeInterceptor('test', notAnInterceptor);
|
||||
expect(emitter.interceptors('test'), '0').to.deep.equal([interceptor2]);
|
||||
|
||||
emitter.removeInterceptor('test', interceptor2);
|
||||
expect(emitter.interceptors('test'), '0').to.deep.equal([]);
|
||||
});
|
||||
|
||||
it('removes all interceptors', function() {
|
||||
var emitter = emitterFactory(),
|
||||
interceptor1 = function() {},
|
||||
interceptor2 = function() {},
|
||||
removeHandler = sinon.spy()
|
||||
removeInterceptor = sinon.spy();
|
||||
|
||||
emitter
|
||||
.intercept('removeInterceptor', removeInterceptor)
|
||||
.on('removeInterceptor', removeHandler)
|
||||
.intercept('test', interceptor1)
|
||||
.intercept('test', interceptor2)
|
||||
.removeAllInterceptors()
|
||||
.removeAllInterceptors();
|
||||
|
||||
expect(removeHandler).to.have.been.called.twice;
|
||||
expect(removeInterceptor).to.have.been.called.once;
|
||||
expect(emitter.interceptors('test')).to.deep.equal([]);
|
||||
|
||||
});
|
||||
|
||||
it('removes specific interceptors', function() {
|
||||
var emitter = emitterFactory(),
|
||||
interceptor1 = function() {},
|
||||
interceptor2 = function() {},
|
||||
removeHandler = sinon.spy();
|
||||
|
||||
emitter
|
||||
.on('removeInterceptor', removeHandler)
|
||||
.intercept('test', interceptor1)
|
||||
.intercept('anotherTest', interceptor2)
|
||||
.removeAllInterceptors('test')
|
||||
.removeAllInterceptors('notAnEvent');
|
||||
|
||||
expect(removeHandler).to.have.been.called.once;
|
||||
expect(emitter.interceptors('anotherTest')).to.deep.equal([interceptor2]);
|
||||
|
||||
});
|
||||
|
||||
it('throws for removing interceptors that are not functions', function() {
|
||||
var emitter = emitterFactory(),
|
||||
interceptCall;
|
||||
|
||||
interceptCall = function() {
|
||||
emitter.removeInterceptor('test', 'not a function');
|
||||
};
|
||||
|
||||
expect(interceptCall).to.throw(Error);
|
||||
});
|
||||
|
||||
it('emits removeInterceptor for removed interceptors', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
interceptor = function() {},
|
||||
removeInterceptorCall;
|
||||
|
||||
removeInterceptorCall = function(event, _interceptor) {
|
||||
expect(event).to.equal('test');
|
||||
expect(_interceptor).to.equal(interceptor);
|
||||
done()
|
||||
}
|
||||
|
||||
emitter
|
||||
.on('removeInterceptor', removeInterceptorCall)
|
||||
.intercept('test', interceptor)
|
||||
.removeInterceptor('test', interceptor);
|
||||
});
|
||||
|
||||
it("doesn't do anything for removeInterceptor with no interceptor", function() {
|
||||
var emitter = emitterFactory(),
|
||||
interceptor = function() {},
|
||||
removeInterceptorCall = sinon.spy();
|
||||
|
||||
emitter
|
||||
.on('removeInterceptor', removeInterceptorCall)
|
||||
.removeInterceptor('test', interceptor);
|
||||
|
||||
expect(removeInterceptorCall).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('calls an interceptor even if there is no handler', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
interceptor;
|
||||
|
||||
interceptor = function(arg, interceptorDone) {
|
||||
expect(arg).to.equal('value');
|
||||
interceptorDone();
|
||||
done();
|
||||
}
|
||||
|
||||
emitter
|
||||
.intercept('test', interceptor)
|
||||
.emit('test', 'value')
|
||||
});
|
||||
|
||||
it('emits newListener and removeListener even if there are no handlers', function() {
|
||||
var emitter = emitterFactory(),
|
||||
newListenerInterceptor,
|
||||
removeListenerInterceptor,
|
||||
handler = sinon.spy();
|
||||
|
||||
newListenerInterceptor = sinon.spy(function(event, interceptor, done) {
|
||||
expect(event).to.equal('test');
|
||||
expect(interceptor).to.equal(handler);
|
||||
done()
|
||||
});
|
||||
|
||||
removeListenerInterceptor = sinon.spy(function(event, interceptor, done) {
|
||||
expect(event).to.equal('test');
|
||||
expect(interceptor).to.equal(handler);
|
||||
done()
|
||||
});
|
||||
|
||||
emitter
|
||||
.intercept('newListener', newListenerInterceptor)
|
||||
.intercept('removeListener', removeListenerInterceptor)
|
||||
.on('test', handler)
|
||||
.removeListener('test', handler);
|
||||
|
||||
expect(emitter.listeners('newListener')).to.be.empty;
|
||||
expect(emitter.listeners('removeListener')).to.be.empty;
|
||||
expect(handler).to.not.have.been.called;
|
||||
expect(newListenerInterceptor).to.have.been.called.once;
|
||||
expect(removeListenerInterceptor).to.have.been.called.once;
|
||||
})
|
||||
|
||||
it('emits newListener and removeListener if there are handlers', function(done) {
|
||||
var emitter = emitterFactory(),
|
||||
newListenerInterceptor,
|
||||
removeListenerInterceptor,
|
||||
newListenerHandler = sinon.spy(),
|
||||
removeListenerHandler = sinon.spy(),
|
||||
handler = sinon.spy();
|
||||
|
||||
newListenerInterceptor = function(event, interceptor, done) {
|
||||
expect(event).to.equal('test');
|
||||
expect(interceptor).to.equal(handler);
|
||||
done()
|
||||
}
|
||||
|
||||
removeListenerInterceptor = function(event, interceptor, done) {
|
||||
expect(event).to.equal('test');
|
||||
expect(interceptor).to.equal(handler);
|
||||
done()
|
||||
}
|
||||
|
||||
emitter
|
||||
.on('removeListener', removeListenerHandler)
|
||||
.on('newListener', newListenerHandler)
|
||||
.intercept('newListener', newListenerInterceptor)
|
||||
.intercept('removeListener', removeListenerInterceptor)
|
||||
.on('test', handler)
|
||||
.removeListener('test', handler);
|
||||
|
||||
expect(handler).to.not.have.been.called;
|
||||
expect(emitter.listeners('newListener')).to.deep.equal([newListenerHandler]);
|
||||
expect(emitter.listeners('removeListener')).to.deep.equal([removeListenerHandler]);
|
||||
expect(emitter.listeners('test')).to.deep.equal([]);
|
||||
expect(newListenerHandler).to.have.been.called.once;
|
||||
expect(removeListenerHandler).to.have.been.called.once;
|
||||
|
||||
done()
|
||||
|
||||
|
||||
})
|
||||
|
||||
});
|
||||
})(emitterFactory);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue