Skip to content

Commit b99f03f

Browse files
authored
fix(events): bind emitters with for..in. (#3059)
Fixes #3057
1 parent ab3c0e3 commit b99f03f

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

lib/events.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ function bufferEvents (emitter, eventsToBuffer) {
3333

3434
class KarmaEventEmitter extends EventEmitter {
3535
bind (object) {
36-
Object.keys(object).forEach((method) => {
36+
for (const method in object) {
3737
if (method.startsWith('on') && helper.isFunction(object[method])) {
3838
this.on(helper.camelToSnake(method.substr(2)), function () {
39+
// We do not use an arrow function here, to supply the caller as this.
3940
object[method].apply(object, Array.from(arguments).concat(this))
4041
})
4142
}
42-
})
43+
}
4344
}
4445

4546
emitAsync (name) {

test/unit/events.spec.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,48 @@ describe('events', () => {
2020
var object = null
2121

2222
beforeEach(() => {
23-
object = sinon.stub({
23+
// Note: es6 class instances have non-enumerable prototype properties.
24+
function FB () {};
25+
FB.prototype = {
26+
onPrototypeBar () {}
27+
}
28+
object = new FB()
29+
Object.assign(object, {
2430
onFoo: () => {},
2531
onFooBar: () => {},
26-
foo: () => {},
27-
bar: () => {}
32+
foo: () => {}
2833
})
34+
2935
emitter.bind(object)
3036
})
3137

3238
it('should register all "on" methods to events', () => {
39+
sinon.spy(object, 'onFoo')
3340
emitter.emit('foo')
3441
expect(object.onFoo).to.have.been.called
3542

43+
sinon.spy(object, 'onFooBar')
3644
emitter.emit('foo_bar')
3745
expect(object.onFooBar).to.have.been.called
3846

47+
sinon.spy(object, 'onPrototypeBar')
48+
emitter.emit('prototype_bar')
49+
expect(object.onPrototypeBar).to.have.been.called
50+
51+
sinon.spy(object, 'foo')
3952
expect(object.foo).not.to.have.been.called
40-
expect(object.bar).not.to.have.been.called
4153
})
4254

4355
it('should bind methods to the owner object', () => {
56+
sinon.spy(object, 'foo')
57+
sinon.spy(object, 'onFoo')
58+
sinon.spy(object, 'onFooBar')
4459
emitter.emit('foo')
4560
emitter.emit('foo_bar')
4661

4762
expect(object.onFoo).to.have.always.been.calledOn(object)
4863
expect(object.onFooBar).to.have.always.been.calledOn(object)
4964
expect(object.foo).not.to.have.been.called
50-
expect(object.bar).not.to.have.been.called
5165
})
5266
})
5367

0 commit comments

Comments
 (0)