2019-05-31 11:56:07 -04:00
|
|
|
/**
|
|
|
|
* @license
|
2020-05-19 15:08:49 -04:00
|
|
|
* Copyright Google LLC All Rights Reserved.
|
2019-05-31 11:56:07 -04:00
|
|
|
*
|
|
|
|
* 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');
|
|
|
|
}
|
|
|
|
|
2020-04-13 19:40:21 -04:00
|
|
|
function listenerA() {
|
|
|
|
zoneResults.push('A');
|
|
|
|
}
|
2019-05-31 11:56:07 -04:00
|
|
|
|
2020-04-13 19:40:21 -04:00
|
|
|
function listenerB() {
|
|
|
|
zoneResults.push('B');
|
|
|
|
}
|
2019-05-31 11:56:07 -04:00
|
|
|
|
2020-04-13 19:40:21 -04:00
|
|
|
function shouldNotRun() {
|
|
|
|
fail('this listener should not run');
|
|
|
|
}
|
2019-05-31 11:56:07 -04:00
|
|
|
|
|
|
|
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', () => {
|
2020-04-13 19:40:21 -04:00
|
|
|
zoneA.run(() => {
|
|
|
|
emitter.on('test', expectZoneA);
|
|
|
|
});
|
|
|
|
zoneB.run(() => {
|
|
|
|
emitter.on('test', shouldNotRun);
|
|
|
|
});
|
2019-05-31 11:56:07 -04:00
|
|
|
expect(emitter.listeners('test')).toEqual([expectZoneA, shouldNotRun]);
|
|
|
|
});
|
2020-04-13 19:40:21 -04:00
|
|
|
it('should return empty array when an event has no listeners', () => {
|
|
|
|
zoneA.run(() => {
|
|
|
|
expect(emitter.listeners('test')).toEqual([]);
|
|
|
|
});
|
|
|
|
});
|
2019-05-31 11:56:07 -04:00
|
|
|
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);
|
|
|
|
});
|
2020-04-13 19:40:21 -04:00
|
|
|
emitter.on('newListener', function(type: string, handler: any) {
|
|
|
|
zoneResults.push('new' + type);
|
|
|
|
});
|
2019-05-31 11:56:07 -04:00
|
|
|
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');
|
2020-04-13 19:40:21 -04:00
|
|
|
zoneA.run(() => {
|
|
|
|
process.on('uncaughtException', function() {});
|
|
|
|
});
|
2019-05-31 11:56:07 -04:00
|
|
|
});
|
|
|
|
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');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|