/// import { assertEquals } from "jsr:@std/assert"; import { startServer } from "./deno.ts"; const hostname = "0.0.0.0"; const port = 8042; const href = `ws://${hostname}:${port}`; function connect(url: string): Promise<[WebSocket, string[]]> { return new Promise((resolve, reject) => { const messages: string[] = []; const socket = new WebSocket(url); socket.onopen = () => resolve([socket, messages]); socket.onerror = (error) => reject(error); socket.onmessage = ({ data }) => { messages.push(data); }; }); } function close(socket: WebSocket): Promise { return new Promise((resolve) => { if (socket.readyState === WebSocket.CLOSED) { return resolve(); } socket.onclose = () => resolve(); socket.close(); }); } function setup( fn: (ctx: Deno.TestContext) => Promise, ): (ctx: Deno.TestContext) => Promise { return async (ctx) => { const shutdown = startServer(hostname, port); try { await fn(ctx); } finally { await shutdown(); } }; } function flush(): Promise { return new Promise((resolve) => setTimeout(resolve, 0)); } Deno.test( "Welcome all clients on connect.", setup(async () => { const [s1, m1] = await connect(href); const [s2, m2] = await connect(href); await flush(); assertEquals(m1, ["Welcome 1, type /join ."]); assertEquals(m2, ["Welcome 2, type /join ."]); await close(s2); await close(s1); }), ); Deno.test( "Messages all clients in a room on joining.", setup(async () => { const [s1, m1] = await connect(href); const [s2, m2] = await connect(href); await flush(); m1.length = 0; m2.length = 0; s1.send("/join meh"); s2.send("/join meh"); await flush(); assertEquals(m1, ["1 has joined!", "2 has joined!"]); assertEquals(m2, ["2 has joined!"]); await close(s2); await close(s1); }), ); Deno.test( "Messages remaining members if one left the room.", setup(async () => { const [s1, m1] = await connect(href); const [s2, m2] = await connect(href); s1.send("/join meh"); s2.send("/join meh"); await flush(); m1.length = 0; m2.length = 0; await close(s2); await flush(); assertEquals(m1, ["2 has left!"]); assertEquals(m2, []); await close(s1); }), );