From 09ef8bb8c72b887d2240360f1eb44adeb6c4aca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 24 Jan 2019 10:24:59 +0100 Subject: [PATCH] add bus class --- web/static/src/ts/core/bus.ts | 32 ++++++++++++++++++++++++++++++++ web/static/tests/bus_test.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 web/static/src/ts/core/bus.ts create mode 100644 web/static/tests/bus_test.ts diff --git a/web/static/src/ts/core/bus.ts b/web/static/src/ts/core/bus.ts new file mode 100644 index 00000000..5f016bb7 --- /dev/null +++ b/web/static/src/ts/core/bus.ts @@ -0,0 +1,32 @@ +type Callback = (...args: any[]) => void; + +interface Subscription { + owner: any; + callback: Callback; +} + +export default class Bus { + private subscriptions: { [eventType: string]: Subscription[] } = {}; + + on(eventType: string, owner: any, callback: Callback) { + if (!this.subscriptions[eventType]) { + this.subscriptions[eventType] = []; + } + this.subscriptions[eventType].push({ + owner, + callback + }); + } + off(eventType: string, owner: any) { + const subs = this.subscriptions[eventType]; + if (subs) { + this.subscriptions[eventType] = subs.filter(s => s.owner !== owner); + } + } + trigger(eventType: string, ...args: any[]) { + const subs = this.subscriptions[eventType] || []; + for (let sub of subs) { + sub.callback(...args); + } + } +} diff --git a/web/static/tests/bus_test.ts b/web/static/tests/bus_test.ts new file mode 100644 index 00000000..3ae90343 --- /dev/null +++ b/web/static/tests/bus_test.ts @@ -0,0 +1,29 @@ +import Bus from "../src/ts/core/bus"; + +describe("event bus behaviour", () => { + test("can subscribe and be notified", () => { + const bus = new Bus(); + let notified = false; + bus.on("event", {}, () => (notified = true)); + expect(notified).toBe(false); + bus.trigger("event"); + expect(notified).toBe(true); + }); + + test("can unsubscribe", () => { + const bus = new Bus(); + let notified = false; + let owner = {}; + bus.on("event", owner, () => (notified = true)); + bus.off("event", owner); + bus.trigger("event"); + expect(notified).toBe(false); + }); + + test("arguments are properly propagated", () => { + expect.assertions(1); + const bus = new Bus(); + bus.on("event", {}, (arg: any) => expect(arg).toBe("hello world")); + bus.trigger("event", "hello world"); + }); +});