UNPKG

event-emitters

Version:
122 lines 4.84 kB
import { EventEmitter } from './EventEmitter'; describe('EventEmitter', () => { /* eslint-disable @typescript-eslint/explicit-function-return-type */ let emitter = new EventEmitter(); beforeEach(() => { emitter = new EventEmitter(); }); it('updates subscribed listener with statuses as they change', () => { let current; emitter.subscribe((newVal) => { current = newVal; }); expect(current).toEqual(undefined); const secondVal = 2; emitter.emit(secondVal); expect(current).toEqual(secondVal); }); it('supports multiple listeners', () => { let current1; let current2; emitter.subscribe((newVal) => { current1 = newVal; }); emitter.subscribe((newVal) => { current2 = newVal; }); expect(current1).toEqual(undefined); expect(current2).toEqual(undefined); const secondVal = 2; emitter.emit(secondVal); expect(current1).toEqual(secondVal); expect(current2).toEqual(secondVal); }); it('stops updating a listener after `unsubscribe` is called', () => { let current1; let current2; const secondListener = (newVal) => { current2 = newVal; }; emitter.subscribe((newVal) => { current1 = newVal; }); emitter.subscribe(secondListener); expect(current1).toEqual(undefined); expect(current2).toEqual(undefined); const secondVal = 2; emitter.emit(secondVal); expect(current1).toEqual(secondVal); expect(current2).toEqual(secondVal); emitter.unsubscribe(secondListener); const thirdVal = 3; emitter.emit(thirdVal); expect(current1).toEqual(thirdVal); expect(current2).toEqual(secondVal); }); it('throws an error when trying to subscribe the same listener twice', () => { // eslint-disable-next-line @typescript-eslint/no-empty-function const listener = () => { }; emitter.subscribe(listener); expect(() => { emitter.subscribe(listener); }).toThrow(); }); it('throws an error when trying to unsubscribe a listener that is not listening', () => { // eslint-disable-next-line @typescript-eslint/no-empty-function const listener1 = () => { }; // eslint-disable-next-line @typescript-eslint/no-empty-function const listener2 = () => { }; emitter.subscribe(listener1); expect(() => { emitter.unsubscribe(listener2); }).toThrow(); }); describe('async iterator', () => { it('can be iterated over in order using "for await" loop', async () => { const allVals = []; async function iterate(iterator) { for await (const val of iterator) { allVals.push(val); if (val === 3) break; } } const promise = iterate(emitter); emitter.emit(1); emitter.emit(2); emitter.emit(3); expect(emitter.hasListeners()).toEqual(true); await expect(promise).resolves.not.toThrow(); expect(allVals).toEqual([1, 2, 3]); // ensure that the iterator's return() method was called expect(emitter.hasListeners()).toEqual(false); }); it('queues calls to next() such that emissions are delivered in sequence via emitted queue', async () => { const iterator = emitter.asyncIterator(); // by calling emit() before next() the emitted items are queued via iterator.emitted emitter.emit(1); emitter.emit(2); emitter.emit(3); const vals = await Promise.all([iterator.next(), iterator.next(), iterator.next()]); expect(vals).toEqual([ { done: false, value: 1 }, { done: false, value: 2 }, { done: false, value: 3 }, ]); }); it('queues calls to next such that emissions are delivered in sequence via pending listener queue', async () => { const iterator = emitter.asyncIterator(); // by calling next() before emit() the pending listeners are queued via iterator.pendingListens const promises = [iterator.next(), iterator.next(), iterator.next()]; emitter.emit(1); emitter.emit(2); emitter.emit(3); expect(await Promise.all(promises)).toEqual([ { done: false, value: 1 }, { done: false, value: 2 }, { done: false, value: 3 }, ]); }); }); }); //# sourceMappingURL=EventEmitter.spec.js.map