- Replace socket.io relay with Colyseus 0.15 authoritative server - GameRoom with GameState schema (players, units, resources) - Pure TS services: CombatResolver, EconomyService, PathfindingService, UnitManager - POST /api/create-room → 4-char invite code - React/MUI LobbyScreen: Create (shows code + START GAME) / Join by code - ColyseusClient: joinOrCreate/join by room type = invite code - Nginx: static assets direct, all else proxied to Colyseus (WS upgrade) - Content-hashed JS bundles for Cloudflare cache-busting - 1-player lobbies: START GAME button bypasses 2-player wait
43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
import { generateCode } from "../src/generateCode";
|
|
|
|
describe("generateCode", () => {
|
|
it("should return a string of the requested length", () => {
|
|
const code = generateCode(4);
|
|
expect(code).toHaveLength(4);
|
|
expect(typeof code).toBe("string");
|
|
});
|
|
|
|
it("should return a string for length 6", () => {
|
|
const code = generateCode(6);
|
|
expect(code).toHaveLength(6);
|
|
});
|
|
|
|
it("should only contain uppercase alphanumeric characters", () => {
|
|
// Test 50 codes to ensure consistency
|
|
for (let i = 0; i < 50; i++) {
|
|
const code = generateCode(4);
|
|
expect(code).toMatch(/^[A-Z0-9]+$/);
|
|
}
|
|
});
|
|
|
|
it("should not contain ambiguous characters (0, O, 1, I, L)", () => {
|
|
const ambiguous = new Set(["0", "O", "1", "I", "L"]);
|
|
// Test 100 codes to catch any ambiguous chars
|
|
for (let i = 0; i < 100; i++) {
|
|
const code = generateCode(4);
|
|
for (const ch of code) {
|
|
expect(ambiguous.has(ch)).toBe(false);
|
|
}
|
|
}
|
|
});
|
|
|
|
it("should generate different codes on successive calls", () => {
|
|
const codes = new Set<string>();
|
|
for (let i = 0; i < 20; i++) {
|
|
codes.add(generateCode(4));
|
|
}
|
|
// With enough calls, we should get different codes
|
|
expect(codes.size).toBeGreaterThan(1);
|
|
});
|
|
});
|