import assert from "node:assert"; import { describe, it } from "node:test"; import { EventBus } from "./index"; describe("EventBus plugin", () => { it("publishes subscribed dom event", () => { const bus = new EventBus(); const el = document.createElement("button"); let calls = 0; bus.add("click", { el, fn: () => { calls += 1; }, }); bus.subscribe("click", el); el.dispatchEvent(new window.Event("click", { bubbles: true })); assert.equal(calls, 1); }); it("initializes with empty store", () => { const bus = new EventBus(); assert.ok(bus.store instanceof Map); assert.equal(bus.store.size, 0); }); it("adds event to store", () => { const bus = new EventBus(); const el = document.createElement("div"); const fn = () => null; bus.add("testEvent", { el, fn }); assert.ok(bus.isEventExist("testEvent")); }); it("does not add event without element", () => { const bus = new EventBus(); const fn = () => null; bus.add("testEvent", { fn }); assert.ok(!bus.isEventExist("testEvent")); }); it("does not add event without function", () => { const bus = new EventBus(); const el = document.createElement("div"); bus.add("testEvent", { el }); assert.ok(!bus.isEventExist("testEvent")); }); it("prevents duplicate callbacks for same element", () => { const bus = new EventBus(); const el = document.createElement("div"); const fn = () => null; bus.add("testEvent", { el, fn }); bus.add("testEvent", { el, fn }); const eventData = bus.getMapByEventName("testEvent"); const elData = eventData?.get(el); assert.equal(elData?.callbacks.length, 1); }); it("allows multiple different callbacks for same element", () => { const bus = new EventBus(); const el = document.createElement("div"); const fn1 = () => 1; const fn2 = () => 2; bus.add("testEvent", { el, fn: fn1 }); bus.add("testEvent", { el, fn: fn2 }); const eventData = bus.getMapByEventName("testEvent"); const elData = eventData?.get(el); assert.equal(elData?.callbacks.length, 2); }); it("publishes event without subscription", () => { const bus = new EventBus(); const el = document.createElement("div"); let calls = 0; bus.add("testEvent", { el, fn: () => { calls += 1; }, }); bus.publish("testEvent"); assert.equal(calls, 1); }); it("unsubscribes from event", () => { const bus = new EventBus(); const el = document.createElement("button"); let calls = 0; bus.add("click", { el, fn: () => { calls += 1; }, }); bus.subscribe("click", el); bus.unsubscribe("click", el); el.dispatchEvent(new window.Event("click", { bubbles: true })); assert.equal(calls, 0); }); it("clears event from store", () => { const bus = new EventBus(); const el = document.createElement("div"); const fn = () => null; bus.add("testEvent", { el, fn }); bus.clear("testEvent"); assert.ok(!bus.isEventExist("testEvent")); }); it("clears all events when called without parameters", () => { const bus = new EventBus(); const el1 = document.createElement("div"); const el2 = document.createElement("div"); bus.add("event1", { el: el1, fn: () => null }); bus.add("event2", { el: el2, fn: () => null }); bus.clear(); assert.equal(bus.store.size, 0); }); it("fills store from listeners object", () => { const bus = new EventBus(); const el = document.createElement("div"); let calls = 0; bus.fill(el, { click: () => { calls += 1; }, }); bus.publish("click"); assert.equal(calls, 1); }); it("handles once option correctly", () => { const bus = new EventBus(); const el = document.createElement("div"); let calls = 0; bus.add("testEvent", { el, fn: () => { calls += 1; }, options: { once: true }, }); bus.publish("testEvent"); bus.publish("testEvent"); assert.equal(calls, 1); }); it("does not clear other listeners when once is set for one element", () => { const bus = new EventBus(); const onceEl = document.createElement("div"); const persistentEl = document.createElement("div"); let onceCalls = 0; let persistentCalls = 0; bus.add("mixedEvent", { el: onceEl, fn: () => { onceCalls += 1; }, options: { once: true }, }); bus.add("mixedEvent", { el: persistentEl, fn: () => { persistentCalls += 1; }, }); bus.publish("mixedEvent"); bus.publish("mixedEvent"); assert.equal(onceCalls, 1); assert.equal(persistentCalls, 2); }); it("unsubscribes capture listeners correctly", () => { const bus = new EventBus(); const el = document.createElement("button"); let calls = 0; bus.add("click", { el, fn: () => { calls += 1; }, options: { capture: true }, }); bus.subscribe("click", el); bus.unsubscribe("click", el); el.dispatchEvent(new window.Event("click", { bubbles: true })); assert.equal(calls, 0); }); it("subscribes to all events when called without eventName", () => { const bus = new EventBus(); const el = document.createElement("button"); let calls = 0; bus.add("click", { el, fn: () => { calls += 1; }, }); bus.add("focus", { el, fn: () => { calls += 1; }, }); bus.subscribe("", el); el.dispatchEvent(new window.Event("click", { bubbles: true })); el.dispatchEvent(new window.Event("focus", { bubbles: true })); assert.equal(calls, 2); }); it("clears specific callback from element", () => { const bus = new EventBus(); const el = document.createElement("div"); let calls1 = 0; let calls2 = 0; const fn1 = () => { calls1 += 1; }; const fn2 = () => { calls2 += 1; }; bus.add("testEvent", { el, fn: fn1 }); bus.add("testEvent", { el, fn: fn2 }); bus.clear("testEvent", el, fn1); bus.publish("testEvent"); assert.equal(calls1, 0); assert.equal(calls2, 1); }); it("keeps remaining dom callbacks active after clearing one callback", () => { const bus = new EventBus(); const el = document.createElement("button"); let calls1 = 0; let calls2 = 0; const fn1 = () => { calls1 += 1; }; const fn2 = () => { calls2 += 1; }; bus.add("click", { el, fn: fn1 }); bus.add("click", { el, fn: fn2 }); bus.subscribe("click", el); bus.clear("click", el, fn1); el.dispatchEvent(new window.Event("click", { bubbles: true })); assert.equal(calls1, 0); assert.equal(calls2, 1); }); it("handles bubbling dom events using subscribed currentTarget", () => { const bus = new EventBus(); const parent = document.createElement("div"); const child = document.createElement("button"); parent.appendChild(child); let calls = 0; bus.add("click", { el: parent, fn: () => { calls += 1; }, }); bus.subscribe("click", parent); child.dispatchEvent(new window.Event("click", { bubbles: true })); assert.equal(calls, 1); }); });