46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { broadcast, subscribe } from './sse';
|
|
|
|
// ISS-129 (v0.57.0): the fan-out registry behind /api/events — plain Set semantics, so no DB or
|
|
// server needed. Subscribers leak across tests in this file (module-level state), which is fine:
|
|
// each test only asserts on its own arrays.
|
|
|
|
describe('lib/sse', () => {
|
|
it('delivers broadcasts to subscribers and stops after unsubscribe', () => {
|
|
const a: string[] = [];
|
|
const b: string[] = [];
|
|
const unsubA = subscribe((t) => a.push(t));
|
|
const unsubB = subscribe((t) => b.push(t));
|
|
|
|
broadcast('x');
|
|
expect(a).toEqual(['x']);
|
|
expect(b).toEqual(['x']);
|
|
|
|
unsubA();
|
|
broadcast('y');
|
|
expect(a).toEqual(['x']); // unsubscribed — no more events
|
|
expect(b).toEqual(['x', 'y']);
|
|
unsubB();
|
|
});
|
|
|
|
it('a throwing subscriber does not break the others', () => {
|
|
const got: string[] = [];
|
|
subscribe(() => {
|
|
throw new Error('boom');
|
|
});
|
|
const unsub = subscribe((t) => got.push(t));
|
|
broadcast('z');
|
|
expect(got).toEqual(['z']);
|
|
unsub();
|
|
});
|
|
|
|
it('unsubscribe is idempotent', () => {
|
|
const got: string[] = [];
|
|
const unsub = subscribe((t) => got.push(t));
|
|
unsub();
|
|
unsub(); // second call must not throw
|
|
broadcast('w');
|
|
expect(got).toEqual([]);
|
|
});
|
|
});
|