forked from Lilly-Protocol/agentlily-runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathissue-229-runtime-event-bus-off.test.ts
More file actions
83 lines (63 loc) · 2.68 KB
/
Copy pathissue-229-runtime-event-bus-off.test.ts
File metadata and controls
83 lines (63 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { describe, it, expect, vi } from "vitest";
import { RuntimeEventBus } from "../../src/events/runtime-events.js";
describe("RuntimeEventBus public off() method (Issue #229)", () => {
it("removes only the specified listener and decreases listenerCount by one", () => {
const bus = new RuntimeEventBus();
const fn1 = vi.fn();
const fn2 = vi.fn();
bus.on("runtime.started", fn1);
bus.on("runtime.started", fn2);
expect(bus.listenerCount("runtime.started")).toBe(2);
const removed = bus.off("runtime.started", fn1);
expect(removed).toBe(true);
expect(bus.listenerCount("runtime.started")).toBe(1);
bus.emit({
name: "runtime.started",
payload: { runtimeId: "rt-1", occurredAt: "2026-09-01T00:00:00Z" }
});
// fn1 must NOT be called; fn2 MUST be called
expect(fn1).not.toHaveBeenCalled();
expect(fn2).toHaveBeenCalledTimes(1);
});
it("allows calling the unsubscribe function returned by on() without throwing", () => {
const bus = new RuntimeEventBus();
const fn = vi.fn();
const unsubscribe = bus.on("runtime.started", fn);
expect(bus.listenerCount("runtime.started")).toBe(1);
expect(() => unsubscribe()).not.toThrow();
expect(bus.listenerCount("runtime.started")).toBe(0);
bus.emit({
name: "runtime.started",
payload: { runtimeId: "rt-1", occurredAt: "2026-09-01T00:00:00Z" }
});
expect(fn).not.toHaveBeenCalled();
});
it("returns false when attempting to remove an unregistered listener or from an empty event", () => {
const bus = new RuntimeEventBus();
const fn1 = vi.fn();
const fn2 = vi.fn();
// 1. Event has no listeners at all
expect(bus.off("runtime.started", fn1)).toBe(false);
// 2. Event has other listeners, but not fn2
bus.on("runtime.started", fn1);
expect(bus.off("runtime.started", fn2)).toBe(false);
// 3. Second call with the same listener after removal returns false
expect(bus.off("runtime.started", fn1)).toBe(true);
expect(bus.off("runtime.started", fn1)).toBe(false);
});
it("maintains strict event isolation when unregistering listeners across different event names", () => {
const bus = new RuntimeEventBus();
const startHandler = vi.fn();
const stopHandler = vi.fn();
bus.on("runtime.started", startHandler);
bus.on("runtime.stopped", stopHandler);
bus.off("runtime.started", startHandler);
expect(bus.listenerCount("runtime.started")).toBe(0);
expect(bus.listenerCount("runtime.stopped")).toBe(1);
bus.emit({
name: "runtime.stopped",
payload: { runtimeId: "rt-2", occurredAt: "2026-09-01T00:00:00Z" }
});
expect(stopHandler).toHaveBeenCalledTimes(1);
});
});