forked from xtermjs/xterm.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request xtermjs#432 from Tyriar/335_TS_EventEmitter
Convert EventEmitter to TypeScript and add tests
- Loading branch information
Showing
3 changed files
with
154 additions
and
64 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { assert } from 'chai'; | ||
import { EventEmitter } from './EventEmitter'; | ||
|
||
describe('EventEmitter', () => { | ||
let eventEmitter: EventEmitter; | ||
|
||
beforeEach(() => { | ||
eventEmitter = new EventEmitter(); | ||
}); | ||
|
||
describe('once', () => { | ||
it('should trigger the listener only once', () => { | ||
let count = 0; | ||
const listener = () => count++; | ||
eventEmitter.once('test', listener); | ||
eventEmitter.emit('test'); | ||
assert.equal(count, 1); | ||
eventEmitter.emit('test'); | ||
assert.equal(count, 1); | ||
}); | ||
}); | ||
|
||
describe('emit', () => { | ||
it('should emit events to listeners', () => { | ||
let count1 = 0; | ||
let count2 = 0; | ||
const listener1 = () => count1++; | ||
const listener2 = () => count2++; | ||
eventEmitter.on('test', listener1); | ||
eventEmitter.on('test', listener2); | ||
eventEmitter.emit('test'); | ||
assert.equal(count1, 1); | ||
assert.equal(count2, 1); | ||
eventEmitter.emit('test'); | ||
assert.equal(count1, 2); | ||
assert.equal(count2, 2); | ||
}); | ||
|
||
it('should manage multiple listener types', () => { | ||
let count1 = 0; | ||
let count2 = 0; | ||
const listener1 = () => count1++; | ||
const listener2 = () => count2++; | ||
eventEmitter.on('test', listener1); | ||
eventEmitter.on('foo', listener2); | ||
eventEmitter.emit('test'); | ||
assert.equal(count1, 1); | ||
assert.equal(count2, 0); | ||
eventEmitter.emit('foo'); | ||
assert.equal(count1, 1); | ||
assert.equal(count2, 1); | ||
}); | ||
}); | ||
|
||
describe('listeners', () => { | ||
it('should return listeners for the type requested', () => { | ||
assert.equal(eventEmitter.listeners('test').length, 0); | ||
const listener = () => {}; | ||
eventEmitter.on('test', listener); | ||
assert.deepEqual(eventEmitter.listeners('test'), [listener]); | ||
}); | ||
}); | ||
|
||
describe('off', () => { | ||
it('should remove the specific listener', () => { | ||
const listener1 = () => {}; | ||
const listener2 = () => {}; | ||
eventEmitter.on('foo', listener1); | ||
eventEmitter.on('foo', listener2); | ||
assert.equal(eventEmitter.listeners('foo').length, 2); | ||
eventEmitter.off('foo', listener1); | ||
assert.deepEqual(eventEmitter.listeners('foo'), [listener2]); | ||
}); | ||
}); | ||
|
||
describe('removeAllListeners', () => { | ||
it('should clear all listeners', () => { | ||
eventEmitter.on('foo', () => {}); | ||
assert.equal(eventEmitter.listeners('foo').length, 1); | ||
eventEmitter.removeAllListeners('foo'); | ||
assert.equal(eventEmitter.listeners('foo').length, 0); | ||
}); | ||
}); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
* @license MIT | ||
*/ | ||
|
||
interface ListenerType { | ||
(): void; | ||
listener?: () => void; | ||
}; | ||
|
||
export class EventEmitter { | ||
private _events: {[type: string]: ListenerType[]}; | ||
|
||
constructor() { | ||
this._events = {}; | ||
} | ||
|
||
public on(type, listener): void { | ||
this._events[type] = this._events[type] || []; | ||
this._events[type].push(listener); | ||
} | ||
|
||
public off(type, listener): void { | ||
if (!this._events[type]) { | ||
return; | ||
} | ||
|
||
let obj = this._events[type]; | ||
let i = obj.length; | ||
|
||
while (i--) { | ||
if (obj[i] === listener || obj[i].listener === listener) { | ||
obj.splice(i, 1); | ||
return; | ||
} | ||
} | ||
} | ||
|
||
public removeAllListeners(type): void { | ||
if (this._events[type]) { | ||
delete this._events[type]; | ||
} | ||
} | ||
|
||
public once(type, listener): any { | ||
function on() { | ||
let args = Array.prototype.slice.call(arguments); | ||
this.off(type, on); | ||
return listener.apply(this, args); | ||
} | ||
(<any>on).listener = listener; | ||
return this.on(type, on); | ||
} | ||
|
||
public emit(type): void { | ||
if (!this._events[type]) { | ||
return; | ||
} | ||
|
||
let args = Array.prototype.slice.call(arguments, 1); | ||
let obj = this._events[type]; | ||
|
||
for (let i = 0; i < obj.length; i++) { | ||
obj[i].apply(this, args); | ||
} | ||
} | ||
|
||
public listeners(type): ListenerType[] { | ||
return this._events[type] || []; | ||
} | ||
} |