UNPKG

@difizen/mana-common

Version:

183 lines (169 loc) 4.72 kB
import assert from 'assert'; import type { Disposable } from '.'; import { noop } from '.'; import { Deferred } from '.'; import { Emitter, Event } from './'; describe('event', () => { describe('Event', () => { it('#event map transformer', (done) => { const emitterNumber = new Emitter<number>(); const eventString = Event.map(emitterNumber.event, (e) => e.toString()); eventString((e) => { assert(typeof e === 'string'); done(); }); emitterNumber.fire(1); }); }); it('#event basic', (done) => { let test = false; const emitter = new Emitter<void>(); emitter.event(() => { test = true; assert(test); done(); }); emitter.fire(); }); it('#listener dispose', (done) => { let test = true; const emitter = new Emitter<void>(); const disposable = emitter.event(() => { test = false; }); emitter.event(() => { assert(test); done(); }); disposable.dispose(); disposable.dispose(); emitter.fire(); }); it('#emitter dispose', async () => { let test = true; const emitter = new Emitter<void>(); emitter.event(() => { test = false; }); emitter.event(() => { test = false; }); emitter.dispose(); emitter.fire(); const doneDeferred = new Deferred<void>(); setTimeout(() => { assert(test); doneDeferred.resolve(); }, 100); await doneDeferred.promise; }); it('#emitter option', async () => { let firstListenerAdded = false; let lastListenerRemoved = false; const emitter = new Emitter<void>({ onFirstListenerAdd: () => { firstListenerAdded = true; }, onLastListenerRemove: () => { lastListenerRemoved = true; }, }); const disposable = emitter.event(noop); disposable.dispose(); const doneDeferred = new Deferred<void>(); setTimeout(() => { assert(firstListenerAdded); assert(lastListenerRemoved); doneDeferred.resolve(); }, 50); await doneDeferred.promise; }); it('#event option', async () => { let test = true; const context = {}; const disposables: Disposable[] = []; const emitter = new Emitter<void>(); disposables.push(emitter.event(() => (test = true), context)); disposables.push(emitter.event(() => (test = true), context)); disposables.forEach((toDispose) => toDispose.dispose()); const doneDeferred = new Deferred<void>(); setTimeout(() => { assert(test); doneDeferred.resolve(); }, 50); await doneDeferred.promise; }); it('#emitter sequence listeners', async () => { const emitter = new Emitter<void>(); emitter.event(() => true); let sequenceTimes1 = 0; await emitter.sequence((listener) => { sequenceTimes1 += 1; return !!listener(); }); assert(sequenceTimes1 === 1); // all listener sequenceTimes1 = 0; emitter.event(() => true); emitter.event(() => false); emitter.event(() => true); await emitter.sequence((listener) => { sequenceTimes1 += 1; return !!listener(); }); assert(sequenceTimes1 === 3); // stop at index 2 }); it('#emitter dispose without callbacks', () => { const emitter = new Emitter<void>(); const disposable = emitter.event(() => true); try { (emitter as any)._callbacks._callbacks = undefined; disposable.dispose(); assert(true); } catch (ex) { assert(false); } }); it('#listener add remove with error context', () => { const emitter = new Emitter<void>(); const disposable = emitter.event(() => true, {}); try { (emitter as any)._callbacks._contexts = [{}]; disposable.dispose(); } catch (ex: any) { assert( ex.message === 'When adding a listener with a context, you should remove it with the same context', ); } }); it('#emitter sequence listeners without callbacks', async () => { const emitter = new Emitter<void>(); emitter.event(() => true); let sequenceTimes1 = 0; (emitter as any)._callbacks._callbacks = undefined; await emitter.sequence((listener) => { sequenceTimes1 += 1; return !!listener(); }); assert(sequenceTimes1 === 0); // all listener }); it('#error listener', (done) => { console.error = noop; let times = 0; const emitter = new Emitter<void>(); emitter.event(() => { times += 1; throw new Error('error listener'); }); emitter.event(() => { times += 1; }); try { emitter.fire(); assert(times === 2); // all listener done(); } catch (e) { // } }); });