Public: anyone can read this; the crew can change it.

forked from trevato/cs

The page's end of a room is pinned before anything moves it: src/client/session.ts gets the test file its docstring already claims #345

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`src/client/session.test.ts` is new: 24 tests over `createSession` driven by a socket of plain objects and an injected clock — no browser, no timer, no port. The snapshots in it are real ones, written by `src/rooms/wire.ts` out of a second `World` that stands in for the room's own, so what is pinned is the module rather than a hand-made fixture; every `f32` in the fixture is a number the wire keep…

shipped production is serving it deploy ae07c2d

opened this

src/client/session.test.ts is new: 24 tests over createSession driven by a socket of plain objects and an injected clock — no browser, no timer, no port. The snapshots in it are real ones, written by src/rooms/wire.ts out of a second World that stands in for the room's own, so what is pinned is the module rather than a hand-made fixture; every f32 in the fixture is a number the wire keeps exactly, so positions are compared with toEqual and not a tolerance.

Each boundary is tested both ways. A hello seats you on the server's seat, makes that body world.me, marks it not a bot (with a roster that does not mention the seat, so only that line can have done it) and forgets the previous match's effects, grenades and clouds; a roster renames the bodies it names, sets bot, counts only the people it has bodies for, and leaves an unmentioned seat alone; a snapshot moves the bodies, writes the round, and leaves your own aim alone while taking your position and velocity from got.own. Against that: a wrong first byte, a truncated frame, a frame before the hello, data that is neither string nor bytes, a string that is not JSON, JSON that is not a Down, an unknown k, and a malformed hello/roster/log each change nothing and throw nothing — checked by comparing a snapshot of the whole world before and after. The four sentences are proved on a clock the test moves (behind is now - landed; 500 ms is still PLAYING, 501 is BEHIND), the feed and messages are capped at eight with the newest eight kept, press sends nothing until the socket is open and then exactly INPUT_BYTES with a tick that increments once a call and a buy on only the frame it was asked on, and after close() the same frames that moved the world a moment earlier reach nothing — which is what close() actually closing the socket buys.

Two things I did beyond the letter of the issue, both worth a look. The world fixture is the game's own createWorld(DE_FORGE, SHORT, …), as in bots.test.ts, hud.test.ts and the rest, rather than something added to src/client/stage.test-helper.ts: that helper is the stub page and holds no world, and giving it one would give the module a second concept. And the false interpolation claim the issue asks to correct is not in session.ts but in SNAPSHOT_HZ's comment in src/rooms/room.ts, which credited session.ts with hiding 62 ms of interpolation it does not do; I fixed that sentence there and corrected session.ts's own header, which said "two sentences" for four and now says plainly that nothing between two snapshots is smoothed. I left src/client/main.ts alone entirely — the point of the issue is that this module is testable by itself.

bun run test (typecheck plus 1371 tests) passes, and the server still boots and answers / with 200.

🤖 Generated with Claude Code

Closes #319

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs