189 lines
6.6 KiB
TypeScript
189 lines
6.6 KiB
TypeScript
|
/**
|
||
|
* @license
|
||
|
* Copyright Google Inc. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by an MIT-style license that can be
|
||
|
* found in the LICENSE file at https://angular.io/license
|
||
|
*/
|
||
|
|
||
|
import {EventEmitter} from 'events';
|
||
|
|
||
|
describe('nodejs EventEmitter', () => {
|
||
|
let zone: Zone, zoneA: Zone, zoneB: Zone, emitter: EventEmitter, expectZoneACount: number,
|
||
|
zoneResults: string[];
|
||
|
beforeEach(() => {
|
||
|
zone = Zone.current;
|
||
|
zoneA = zone.fork({name: 'A'});
|
||
|
zoneB = zone.fork({name: 'B'});
|
||
|
|
||
|
emitter = new EventEmitter();
|
||
|
expectZoneACount = 0;
|
||
|
|
||
|
zoneResults = [];
|
||
|
});
|
||
|
|
||
|
function expectZoneA(value: string) {
|
||
|
expectZoneACount++;
|
||
|
expect(Zone.current.name).toBe('A');
|
||
|
expect(value).toBe('test value');
|
||
|
}
|
||
|
|
||
|
function listenerA() { zoneResults.push('A'); }
|
||
|
|
||
|
function listenerB() { zoneResults.push('B'); }
|
||
|
|
||
|
function shouldNotRun() { fail('this listener should not run'); }
|
||
|
|
||
|
it('should register listeners in the current zone', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('test', expectZoneA);
|
||
|
emitter.addListener('test', expectZoneA);
|
||
|
});
|
||
|
zoneB.run(() => emitter.emit('test', 'test value'));
|
||
|
expect(expectZoneACount).toBe(2);
|
||
|
});
|
||
|
it('allows chaining methods', () => {
|
||
|
zoneA.run(() => {
|
||
|
expect(emitter.on('test', expectZoneA)).toBe(emitter);
|
||
|
expect(emitter.addListener('test', expectZoneA)).toBe(emitter);
|
||
|
});
|
||
|
});
|
||
|
it('should remove listeners properly', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('test', shouldNotRun);
|
||
|
emitter.on('test2', shouldNotRun);
|
||
|
emitter.removeListener('test', shouldNotRun);
|
||
|
});
|
||
|
zoneB.run(() => {
|
||
|
emitter.removeListener('test2', shouldNotRun);
|
||
|
emitter.emit('test', 'test value');
|
||
|
emitter.emit('test2', 'test value');
|
||
|
});
|
||
|
});
|
||
|
it('remove listener should return event emitter', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('test', shouldNotRun);
|
||
|
expect(emitter.removeListener('test', shouldNotRun)).toEqual(emitter);
|
||
|
emitter.emit('test', 'test value');
|
||
|
});
|
||
|
});
|
||
|
it('should return all listeners for an event', () => {
|
||
|
zoneA.run(() => { emitter.on('test', expectZoneA); });
|
||
|
zoneB.run(() => { emitter.on('test', shouldNotRun); });
|
||
|
expect(emitter.listeners('test')).toEqual([expectZoneA, shouldNotRun]);
|
||
|
});
|
||
|
it('should return empty array when an event has no listeners',
|
||
|
() => { zoneA.run(() => { expect(emitter.listeners('test')).toEqual([]); }); });
|
||
|
it('should prepend listener by order', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('test', listenerA);
|
||
|
emitter.on('test', listenerB);
|
||
|
expect(emitter.listeners('test')).toEqual([listenerA, listenerB]);
|
||
|
emitter.emit('test');
|
||
|
expect(zoneResults).toEqual(['A', 'B']);
|
||
|
zoneResults = [];
|
||
|
|
||
|
emitter.removeAllListeners('test');
|
||
|
|
||
|
emitter.on('test', listenerA);
|
||
|
emitter.prependListener('test', listenerB);
|
||
|
expect(emitter.listeners('test')).toEqual([listenerB, listenerA]);
|
||
|
emitter.emit('test');
|
||
|
expect(zoneResults).toEqual(['B', 'A']);
|
||
|
});
|
||
|
});
|
||
|
it('should remove All listeners properly', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('test', expectZoneA);
|
||
|
emitter.on('test', expectZoneA);
|
||
|
emitter.removeAllListeners('test');
|
||
|
expect(emitter.listeners('test').length).toEqual(0);
|
||
|
});
|
||
|
});
|
||
|
it('remove All listeners should return event emitter', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('test', expectZoneA);
|
||
|
emitter.on('test', expectZoneA);
|
||
|
expect(emitter.removeAllListeners('test')).toEqual(emitter);
|
||
|
expect(emitter.listeners('test').length).toEqual(0);
|
||
|
});
|
||
|
});
|
||
|
it('should remove All listeners properly even without a type parameter', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('test', shouldNotRun);
|
||
|
emitter.on('test1', shouldNotRun);
|
||
|
emitter.removeAllListeners();
|
||
|
expect(emitter.listeners('test').length).toEqual(0);
|
||
|
expect(emitter.listeners('test1').length).toEqual(0);
|
||
|
});
|
||
|
});
|
||
|
it('should remove once listener after emit', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.once('test', expectZoneA);
|
||
|
emitter.emit('test', 'test value');
|
||
|
expect(emitter.listeners('test').length).toEqual(0);
|
||
|
});
|
||
|
});
|
||
|
it('should remove once listener properly before listener triggered', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.once('test', shouldNotRun);
|
||
|
emitter.removeListener('test', shouldNotRun);
|
||
|
emitter.emit('test');
|
||
|
});
|
||
|
});
|
||
|
it('should trigger removeListener when remove listener', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('removeListener', function(type: string, handler: any) {
|
||
|
zoneResults.push('remove' + type);
|
||
|
});
|
||
|
emitter.on(
|
||
|
'newListener', function(type: string, handler: any) { zoneResults.push('new' + type); });
|
||
|
emitter.on('test', shouldNotRun);
|
||
|
emitter.removeListener('test', shouldNotRun);
|
||
|
expect(zoneResults).toEqual(['newtest', 'removetest']);
|
||
|
});
|
||
|
});
|
||
|
it('should trigger removeListener when remove all listeners with eventname ', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('removeListener', function(type: string, handler: any) {
|
||
|
zoneResults.push('remove' + type);
|
||
|
});
|
||
|
emitter.on('test', shouldNotRun);
|
||
|
emitter.on('test1', expectZoneA);
|
||
|
emitter.removeAllListeners('test');
|
||
|
expect(zoneResults).toEqual(['removetest']);
|
||
|
expect(emitter.listeners('removeListener').length).toBe(1);
|
||
|
});
|
||
|
});
|
||
|
it('should trigger removeListener when remove all listeners without eventname', () => {
|
||
|
zoneA.run(() => {
|
||
|
emitter.on('removeListener', function(type: string, handler: any) {
|
||
|
zoneResults.push('remove' + type);
|
||
|
});
|
||
|
emitter.on('test', shouldNotRun);
|
||
|
emitter.on('test1', shouldNotRun);
|
||
|
emitter.removeAllListeners();
|
||
|
expect(zoneResults).toEqual(['removetest', 'removetest1']);
|
||
|
expect(emitter.listeners('test').length).toBe(0);
|
||
|
expect(emitter.listeners('test1').length).toBe(0);
|
||
|
expect(emitter.listeners('removeListener').length).toBe(0);
|
||
|
});
|
||
|
});
|
||
|
it('should not enter endless loop when register uncaughtException to process', () => {
|
||
|
require('domain');
|
||
|
zoneA.run(() => { process.on('uncaughtException', function() {}); });
|
||
|
});
|
||
|
it('should be able to addEventListener with symbol eventName', () => {
|
||
|
zoneA.run(() => {
|
||
|
const testSymbol = Symbol('test');
|
||
|
const test1Symbol = Symbol('test1');
|
||
|
emitter.on(testSymbol, expectZoneA);
|
||
|
emitter.on(test1Symbol, shouldNotRun);
|
||
|
emitter.removeListener(test1Symbol, shouldNotRun);
|
||
|
expect(emitter.listeners(testSymbol).length).toBe(1);
|
||
|
expect(emitter.listeners(test1Symbol).length).toBe(0);
|
||
|
emitter.emit(testSymbol, 'test value');
|
||
|
});
|
||
|
});
|
||
|
});
|