angular-docs-cn/packages/zone.js/test/node/events.spec.ts

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');
});
});
});