///
import { assertEquals } from "jsr:@std/assert";
const url = "ws://0.0.0.0:6969";
function connect(): Promise {
return new Promise((resolve, reject) => {
const socket = new WebSocket(url);
socket.onopen = () => resolve(socket);
socket.onerror = (e) => reject(e);
});
}
function nextMessage(socket: WebSocket): Promise {
return new Promise((resolve, reject) => {
const onMessage = (e: MessageEvent) => {
socket.removeEventListener("message", onMessage);
try {
resolve(JSON.parse(e.data));
} catch {
resolve(e.data);
}
};
socket.addEventListener("message", onMessage);
socket.addEventListener("error", reject, { once: true });
});
}
function closeAndWait(socket: WebSocket): Promise {
return new Promise((resolve) => {
if (socket.readyState === WebSocket.CLOSED) return resolve();
socket.onclose = () => resolve();
socket.close();
});
}
Deno.test("broadcasts a message from one client to another", async () => {
const a = await connect(); // 1
const b = await connect(); // 2
const received = await nextMessage(b);
assertEquals(received, "2 has joined!");
await closeAndWait(a);
await closeAndWait(b);
});
Deno.test("removes a client from broadcast after it disconnects", async () => {
// test are executed in a row so the ID will just increment
const a = await connect(); // 3
const b = await connect(); // 4
await closeAndWait(b);
const msg = await nextMessage(a);
assertEquals(msg, "4 has left!");
await closeAndWait(a);
});