ef832b823d
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 1m10s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m39s
In offline mode the lobby now shows only the device-local games and its New-vs-AI entry creates one through the in-browser engine — the visible payoff of the offline mode. - LocalSource.list() reconstructs a lobby GameView per stored local game by replay, exposed through the lazy gamesource proxy; unit-tested via an in-memory store. - Lobby.load() branches on offlineMode: lists local games and skips every gateway call (no online games/invitations/incoming); the Stats tab is disabled offline. - NewGame offline: find() creates a device-local vs_ai game via LocalSource.create using the profile's advertised dict version + a local seed; the friends flow and the random-opponent option are hidden, and the variant picker / Start are enabled offline (were gated on connection). - id.ts: newLocalGameId + randomSeed (tested). Docs: ARCHITECTURE + FUNCTIONAL(+ru) offline-mode section. Deferred to fast-follow: the Settings Friends/Profile/Feedback affordance gating, the flip-to-offline readiness wait, the offline mock e2e (needs mock-dawg support), and the local-hint UI. The offline flow is verified on the test contour — the mock e2e cannot enter offline mode (the toggle is gated to an installed PWA).
25 lines
750 B
TypeScript
25 lines
750 B
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { LOCAL_ID_PREFIX, isLocalGameId, newLocalGameId, randomSeed } from './id';
|
|
|
|
describe('local game id helpers', () => {
|
|
it('recognises local ids by prefix', () => {
|
|
expect(isLocalGameId(LOCAL_ID_PREFIX + 'x')).toBe(true);
|
|
expect(isLocalGameId('deadbeef')).toBe(false);
|
|
});
|
|
|
|
it('mints unique local ids', () => {
|
|
const a = newLocalGameId();
|
|
const b = newLocalGameId();
|
|
expect(isLocalGameId(a)).toBe(true);
|
|
expect(a).not.toBe(b);
|
|
});
|
|
|
|
it('produces a bigint seed in the 32-bit range', () => {
|
|
for (let i = 0; i < 50; i++) {
|
|
const s = randomSeed();
|
|
expect(typeof s).toBe('bigint');
|
|
expect(s >= 0n && s <= 0xffffffffn).toBe(true);
|
|
}
|
|
});
|
|
});
|