73 lines
3.5 KiB
TypeScript
73 lines
3.5 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
reorderSaphoMovementOrder, saphoMovementOrderEvent, SaphoMovementOrderError,
|
|
type SaphoMovementOrderContext,
|
|
} from '../game/sapho-movement-order';
|
|
|
|
function context(currentStarted = false): SaphoMovementOrderContext {
|
|
return {
|
|
queue: {
|
|
event: 'movement:3', eligible: ['done', 'current', 'later', 'holder'],
|
|
remaining: ['current', 'later', 'holder'], completed: ['done'],
|
|
current: 'current', currentStarted, protectedLast: 'holder',
|
|
},
|
|
started: currentStarted ? ['done', 'current', 'holder'] : ['done', 'holder'],
|
|
guild: null,
|
|
};
|
|
}
|
|
function change(input: SaphoMovementOrderContext, player = 'holder', mode: 'first' | 'last' = 'first') {
|
|
return reorderSaphoMovementOrder(input, { event: saphoMovementOrderEvent(input), player, mode });
|
|
}
|
|
|
|
void test('suspended holder resumes its existing started turn when First becomes current', () => {
|
|
const input = context(), before = structuredClone(input), result = change(input);
|
|
assert.deepEqual(result.next.remaining, ['holder', 'current', 'later']);
|
|
assert.deepEqual(result.next.completed, ['done']);
|
|
assert.equal(result.next.current, 'holder');
|
|
assert.equal(result.next.currentStarted, true);
|
|
assert.equal(result.next.protectedLast, null);
|
|
assert.equal(result.afterCurrent, null);
|
|
assert.equal(result.suspended, undefined);
|
|
assert.deepEqual(input, before);
|
|
});
|
|
|
|
void test('another started actor finishes before the suspended holder resumes', () => {
|
|
const input = context(true), before = structuredClone(input), result = change(input);
|
|
assert.deepEqual(result.next.remaining, ['current', 'holder', 'later']);
|
|
assert.deepEqual(result.next.completed, ['done']);
|
|
assert.equal(result.next.current, 'current');
|
|
assert.equal(result.next.currentStarted, true);
|
|
assert.equal(result.next.protectedLast, null);
|
|
assert.equal(result.afterCurrent, 'current');
|
|
assert.deepEqual(input, before);
|
|
});
|
|
|
|
void test('only the same holder can replace its protected suspended Last', () => {
|
|
const input = context(), before = structuredClone(input);
|
|
assert.throws(() => change(input, 'later', 'first'), SaphoMovementOrderError);
|
|
assert.throws(() => change(input, 'later', 'last'), SaphoMovementOrderError);
|
|
assert.throws(() => change(input, 'holder', 'last'), SaphoMovementOrderError);
|
|
assert.throws(() => reorderSaphoMovementOrder(input,
|
|
{ event: 'movement:4', player: 'holder', mode: 'first' }), SaphoMovementOrderError);
|
|
assert.deepEqual(input, before);
|
|
});
|
|
|
|
void test('unrelated started tails and inconsistent current start are rejected', () => {
|
|
const unrelated = context(); unrelated.started = ['done', 'later', 'holder'];
|
|
assert.throws(() => saphoMovementOrderEvent(unrelated), SaphoMovementOrderError);
|
|
const noProtection = context(); noProtection.queue = { ...noProtection.queue, protectedLast: null };
|
|
assert.throws(() => saphoMovementOrderEvent(noProtection), SaphoMovementOrderError);
|
|
const badCurrent = context(); badCurrent.started = ['current', 'holder'];
|
|
assert.throws(() => saphoMovementOrderEvent(badCurrent), SaphoMovementOrderError);
|
|
});
|
|
|
|
void test('a granted current Guild turn cannot be displaced by suspended First', () => {
|
|
const granted = context();
|
|
granted.guild = { player: 'current', granted: true, locked: false };
|
|
assert.throws(() => change(granted), SaphoMovementOrderError);
|
|
const currentStarted = context(true);
|
|
currentStarted.guild = { player: 'current', granted: true, locked: false };
|
|
assert.equal(change(currentStarted).afterCurrent, 'current');
|
|
});
|