import { describe, expect, test, jest } from "@jest/globals"; type IListeners = { name: string, callback: (...args:any[]) => void } class EventEmitter { protected Listeners:IListeners[] = []; public addEventListener(eventName: string, callback: (...args:any[]) => void) { this.Listeners.push({ callback, name: eventName }); } public trigger(eventName: string, data?: any) { this.Listeners.forEach(event => { if (event.name===eventName) { event.callback(data); } }); } public removeEventListener(eventName: string, callback: () => any) { this.Listeners = this.Listeners.filter(event => event.name!==eventName); } } describe("Event emitter", () => { const emitter = new EventEmitter(); const callback = jest.fn(); test("adds a listener", () => { emitter.addEventListener("click", callback); expect(callback.mock.calls.length).toBe(0); }); test("emits an event", () => { let sentEvent = { x: 123, y: 42, }; emitter.trigger("click", sentEvent); expect(callback.mock.calls[0][0]).toBe(sentEvent); }); test("removes the listener", () => { emitter.trigger("click"); expect(callback.mock.calls.length).toBe(2); emitter.removeEventListener("click", callback); emitter.trigger("click"); expect(callback.mock.calls.length).toBe(2); }); });