///
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 open",
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(
// "removes a client from broadcast after it disconnects",
// setup(async () => {
// const [s1, m1] = await connect(href);
// const [s2, m2] = await connect(href);
// const [s3, m3] = await connect(href);
// await flush();
// m1.length = 0;
// m2.length = 0;
// m3.length = 0;
// await close(s3);
// assertEquals(m1, ["3 has left!"]);
// assertEquals(m2, ["3 has left!"]);
// assertEquals(m3, []);
// await close(s2);
// await close(s1);
// }),
// );