75 lines
4.0 KiB
TypeScript
75 lines
4.0 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
chooseDiscoveryStorm,
|
|
discoveryStormSaphoModes,
|
|
discoveryStormSignature,
|
|
finishDiscoveryStorm,
|
|
reorderDiscoveryStorm,
|
|
validateDiscoveryStorm,
|
|
} from '../game/discovery-storm';
|
|
import {createTestingStationContestFixture} from './fixture-testing-station-contest';
|
|
|
|
// Real revealed station, original storm source and both occupants. The helper
|
|
// tests ordering only; physical Sapho ownership and disposal belong to engine.
|
|
const source = () => createTestingStationContestFixture().game;
|
|
|
|
void test('legacy station signature stays unchanged and offers only meaningful two-seat moves', () => {
|
|
const game = source(), frame = game.ecologicalStorm!;
|
|
const [first, second] = frame.queue!.order;
|
|
assert.equal(frame.signature, JSON.stringify([frame.event, frame.turn, frame.owner,
|
|
frame.token, frame.from, frame.base, frame.delta, frame.stage,
|
|
frame.queue!.order, frame.queue!.choices]));
|
|
assert.deepEqual(discoveryStormSaphoModes(game, frame, first), ['last']);
|
|
assert.deepEqual(discoveryStormSaphoModes(game, frame, second), ['first']);
|
|
assert.deepEqual(discoveryStormSaphoModes(game, frame, 'nonoccupant'), []);
|
|
});
|
|
|
|
for (const mode of ['first', 'last'] as const) void test(
|
|
`Sapho ${mode} binds a fresh station event and preserves both cumulative choices`, () => {
|
|
const game = source(), original = structuredClone(game.ecologicalStorm!);
|
|
const holder = original.queue!.order[mode === 'first' ? 1 : 0];
|
|
const frame = reorderDiscoveryStorm(game, original,
|
|
{holder, event: original.event, mode, nextEvent: 'sapho-fresh-event'});
|
|
assert.deepEqual(original, game.ecologicalStorm);
|
|
assert.deepEqual(frame.queue!.order, [...original.queue!.order].reverse());
|
|
assert.equal(frame.owner, frame.queue!.order[0]);
|
|
assert.deepEqual(frame.sapho, {event: original.event, nextEvent: 'sapho-fresh-event',
|
|
originalOrder: original.queue!.order, holder, mode});
|
|
assert.deepEqual(discoveryStormSaphoModes(game, frame, holder), []);
|
|
assert.throws(() => chooseDiscoveryStorm(game, frame, frame.owner, original.event, 0));
|
|
let next = chooseDiscoveryStorm(game, frame, frame.owner, frame.event, 0);
|
|
assert.equal(next.event, 'sapho-fresh-event:1');
|
|
validateDiscoveryStorm(game, next);
|
|
next = chooseDiscoveryStorm(game, next, next.owner, next.event, 0);
|
|
assert.equal(next.stage, 'traversal');
|
|
validateDiscoveryStorm(game, next);
|
|
next = finishDiscoveryStorm(next);
|
|
validateDiscoveryStorm(game, next);
|
|
assert.deepEqual(next.sapho, frame.sapho);
|
|
assert.deepEqual(next.queue!.choices.map(choice => choice.owner), frame.queue!.order);
|
|
},
|
|
);
|
|
|
|
void test('stale, ineffective, replayed and tampered station reorder requests fail closed', () => {
|
|
const game = source(), frame = game.ecologicalStorm!;
|
|
const [first, second] = frame.queue!.order, before = structuredClone(frame);
|
|
for (const input of [
|
|
{holder: first, event: 'stale', mode: 'last' as const, nextEvent: 'fresh'},
|
|
{holder: first, event: frame.event, mode: 'first' as const, nextEvent: 'fresh'},
|
|
{holder: second, event: frame.event, mode: 'first' as const, nextEvent: frame.event},
|
|
{holder: 'other', event: frame.event, mode: 'last' as const, nextEvent: 'fresh'},
|
|
]) assert.throws(() => reorderDiscoveryStorm(game, frame, input));
|
|
assert.deepEqual(frame, before);
|
|
const reordered = reorderDiscoveryStorm(game, frame,
|
|
{holder: first, event: frame.event, mode: 'last', nextEvent: 'fresh'});
|
|
assert.throws(() => reorderDiscoveryStorm(game, reordered,
|
|
{holder: second, event: 'fresh', mode: 'last', nextEvent: 'again'}));
|
|
const changed = structuredClone(reordered);
|
|
changed.sapho!.originalOrder.reverse();
|
|
changed.signature = discoveryStormSignature(changed);
|
|
assert.throws(() => validateDiscoveryStorm(game, changed));
|
|
const afterFirst = chooseDiscoveryStorm(game, frame, first, frame.event, 0);
|
|
assert.deepEqual(discoveryStormSaphoModes(game, afterFirst, second), []);
|
|
});
|