feat(session): add explicit leave and immediate slot release
This commit is contained in:
@@ -103,6 +103,29 @@ test("latency correlation is bounded and only completes matching authoritative v
|
||||
assert.equal(tracker.pointerSnapshot().length, player.LATENCY_SAMPLE_LIMIT);
|
||||
});
|
||||
|
||||
test("connection quality uses one correlated heartbeat and bounded local smoothing", () => {
|
||||
let clock = 0;
|
||||
const quality = new player.ConnectionQuality(() => clock);
|
||||
assert.equal(quality.begin("heartbeat-1"), true);
|
||||
assert.equal(quality.begin("heartbeat-2"), false);
|
||||
clock = 85;
|
||||
assert.equal(quality.acknowledge("wrong", 2), false);
|
||||
assert.equal(quality.acknowledge("heartbeat-1", 2), true);
|
||||
assert.deepEqual(quality.latest, {totalMs: 85, communicationMs: 83, handlingMs: 2, received: 85});
|
||||
for (let index = 0; index < player.QUALITY_SAMPLE_LIMIT + 2; index++) {
|
||||
clock += 10;
|
||||
assert.equal(quality.begin(`heartbeat-${index + 2}`), true);
|
||||
clock += 20;
|
||||
assert.equal(quality.acknowledge(`heartbeat-${index + 2}`, 1), true);
|
||||
}
|
||||
assert.equal(quality.samples.length, player.QUALITY_SAMPLE_LIMIT);
|
||||
assert.equal(quality.acknowledge("heartbeat-99", 1001), false);
|
||||
clock += player.HEARTBEAT_STALE_MS + 1;
|
||||
assert.equal(quality.status(), "stale");
|
||||
quality.reset();
|
||||
assert.equal(quality.status(), "unknown");
|
||||
});
|
||||
|
||||
test("player map cells enlarge small projections without exceeding a readable bound", () => {
|
||||
const sevenBySeven = player.playerCellSize(396, 730, 7, 7);
|
||||
const fourByFour = player.playerCellSize(396, 730, 4, 4);
|
||||
@@ -338,8 +361,9 @@ test("refresh contract restores only the token and waits for server projection",
|
||||
assert.equal("position" in restore.payload, false);
|
||||
assert.equal("inventory" in restore.payload, false);
|
||||
const script = fs.readFileSync(path.join(project, "web/player.js"), "utf8");
|
||||
assert.equal((script.match(/localStorage\.setItem/g) || []).length, 1);
|
||||
assert.equal((script.match(/localStorage\.setItem/g) || []).length, 2);
|
||||
assert.match(script, /localStorage\.setItem\(TOKEN_KEY, message\.payload\.token\)/);
|
||||
assert.match(script, /localStorage\.setItem\(NAME_KEY, byId\("player-name"\)\.value\.slice\(0, 32\)\)/);
|
||||
});
|
||||
|
||||
test("player assets are local, Russian, accessible, and responsive", () => {
|
||||
@@ -392,6 +416,19 @@ test("one compact settings popover replaces standalone secondary controls", () =
|
||||
assert.match(script, /button\.textContent = reduced \? "Движение: выкл" : "Движение: вкл"/);
|
||||
});
|
||||
|
||||
test("connection quality stays compact and exposes an honest response split", () => {
|
||||
const html = fs.readFileSync(path.join(project, "web/index.html"), "utf8");
|
||||
const css = fs.readFileSync(path.join(project, "web/player.css"), "utf8");
|
||||
const script = fs.readFileSync(path.join(project, "web/player.js"), "utf8");
|
||||
assert.match(html, /id="quality"[^>]*aria-label="Отклик неизвестен"/);
|
||||
assert.match(html, /id="quality-details"/);
|
||||
assert.match(css, /\.quality-pill \{[^}]*min-width: 48px/);
|
||||
assert.match(script, /send\("heartbeat", \{\}, null\)/);
|
||||
assert.match(script, /communicationMs: Math\.max\(0, smoothedMs - handlingMs\)/);
|
||||
assert.match(script, /message\.payload\.command === "heartbeat"/);
|
||||
assert.match(script, /documentObject\.hidden/);
|
||||
});
|
||||
|
||||
test("reference-derived SVG gameplay symbols preserve local yellow and blue ownership", () => {
|
||||
const icons = fs.readFileSync(path.join(project, "web/icons.svg"), "utf8");
|
||||
const script = fs.readFileSync(path.join(project, "web/player.js"), "utf8");
|
||||
|
||||
Reference in New Issue
Block a user