feat(sdk): add isolated single-game sessions
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { test } from 'node:test';
|
||||
import type {
|
||||
GameEntry,
|
||||
GameHost,
|
||||
GameModule,
|
||||
PlatformGameSnapshot,
|
||||
} from '../../YouleNexus/assets/framework/sdk/contracts/index.ts';
|
||||
import {
|
||||
assertGameContract,
|
||||
type GameContractHost,
|
||||
} from '../../YouleNexus/assets/framework/sdk/testing/game-contract-harness.ts';
|
||||
|
||||
test('assertGameContract runs the reusable isolated session conformance suite', () => {
|
||||
let invalidations = 0;
|
||||
let nextModuleId = 0;
|
||||
const entry: GameEntry = {
|
||||
key: 'fixture',
|
||||
gameId: 41,
|
||||
route: 'fixture-route',
|
||||
resolveSeatCount: (roomtype) => {
|
||||
const seats = roomtype[0];
|
||||
if (seats === 2 || seats === 4 || seats === 10) return seats;
|
||||
return 4;
|
||||
},
|
||||
createModule: () => makeModule(++nextModuleId),
|
||||
};
|
||||
|
||||
assert.doesNotThrow(() => assertGameContract(entry, makeConformanceHost(() => { invalidations++; })));
|
||||
assert.equal(invalidations, 2);
|
||||
assert.ok(nextModuleId >= 2);
|
||||
});
|
||||
|
||||
function makeModule(id: number): GameModule {
|
||||
let host: GameHost | undefined;
|
||||
let restored: unknown;
|
||||
let eventCount = 0;
|
||||
let messageCycle: number | undefined;
|
||||
return {
|
||||
attach(value) { host = value; },
|
||||
handlePlatformEvent(event) {
|
||||
eventCount++;
|
||||
if (event.type === 'room.entered') {
|
||||
assert.equal(event.roomtype[0], 4);
|
||||
}
|
||||
},
|
||||
handleGameMessage(message) {
|
||||
assert.equal(message.rpc, 'conformance.message');
|
||||
const data = message.data as { cycle: number };
|
||||
assert.equal(typeof data.cycle, 'number');
|
||||
messageCycle = data.cycle;
|
||||
},
|
||||
restore(deskinfo) { restored = deskinfo; },
|
||||
dispose() {
|
||||
assert.ok(host);
|
||||
assert.equal(eventCount, 1);
|
||||
assert.deepEqual(restored, deskinfoFor(messageCycle!));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function deskinfoFor(cycle: number): { readonly cycle: number } {
|
||||
return { cycle };
|
||||
}
|
||||
|
||||
function makeConformanceHost(onInvalidate: () => void): () => GameContractHost {
|
||||
return () => {
|
||||
const snapshot: PlatformGameSnapshot = {
|
||||
connection: { phase: 'connected' },
|
||||
self: { playerId: 1, seat: 0 },
|
||||
room: { roomcode: 'fixture', roomtype: [], stage: 0, needprepare: 0, infinite: 0 },
|
||||
seats: [],
|
||||
};
|
||||
return {
|
||||
host: {
|
||||
seat: { toView: (seat) => seat, toServer: (seat) => seat },
|
||||
getSnapshot: () => snapshot,
|
||||
subscribe: () => () => {},
|
||||
sendGameMessage: () => {},
|
||||
execute: () => {},
|
||||
},
|
||||
invalidate: onInvalidate,
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user