From 3e5dead07ff6582497e7023efc6d1e6cdc1465d7 Mon Sep 17 00:00:00 2001 From: Schluffe Date: Fri, 11 Sep 2026 23:36:23 +0200 Subject: [PATCH] test the web sockets --- deno.lock | 33 ++++++++++++++++++++++++ server/client.test.ts | 59 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 deno.lock create mode 100644 server/client.test.ts diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..7b2008d --- /dev/null +++ b/deno.lock @@ -0,0 +1,33 @@ +{ + "version": "5", + "specifiers": { + "jsr:@std/assert@*": "1.0.19", + "jsr:@std/internal@^1.0.12": "1.0.14" + }, + "jsr": { + "@std/assert@1.0.19": { + "integrity": "eaada96ee120cb980bc47e040f82814d786fe8162ecc53c91d8df60b8755991e", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/internal@1.0.14": { + "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7" + } + }, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:@biomejs/biome@2.5.12", + "npm:@types/bun@1.4.0", + "npm:jsdom@^30.0.1", + "npm:lz-string@1.5.0", + "npm:solid-js@1.9.15", + "npm:typescript@7.0.2", + "npm:vite-plugin-solid@2.11.14", + "npm:vite@8.2.2", + "npm:vitest@5" + ] + } + } +} diff --git a/server/client.test.ts b/server/client.test.ts new file mode 100644 index 0000000..1a972c6 --- /dev/null +++ b/server/client.test.ts @@ -0,0 +1,59 @@ +/// +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); +});