Files
Dune/tests/sapho-self-last-order.test.ts

91 lines
4.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict';
import test from 'node:test';
import {
reorderSaphoMovementOrder, saphoMovementOrderEvent, SaphoMovementOrderError,
type SaphoMovementOrderContext,
} from '../game/sapho-movement-order';
function context(): SaphoMovementOrderContext {
return {
queue: {
event: 'movement:3', eligible: ['done', 'active', 'later', 'last'],
remaining: ['active', 'later', 'last'], completed: ['done'],
current: 'active', currentStarted: true, protectedLast: null,
},
started: ['done', 'active'], guild: null, allowStartedLast: true,
};
}
function request(input: SaphoMovementOrderContext, player = 'active', mode: 'first' | 'last' = 'last') {
return reorderSaphoMovementOrder(input, { event: saphoMovementOrderEvent(input), player, mode });
}
function reject(input: SaphoMovementOrderContext, player = 'active', mode: 'first' | 'last' = 'last', event?: string) {
const before = structuredClone(input);
assert.throws(() => reorderSaphoMovementOrder(input, {
event: event ?? saphoMovementOrderEvent(input), player, mode,
}), SaphoMovementOrderError);
assert.deepEqual(input, before);
}
void test('a Basic started actor suspends the same opportunity at a protected last position', () => {
const input = context(), before = structuredClone(input), event = saphoMovementOrderEvent(input);
const result = request(input);
assert.equal(result.event, event);
assert.equal(result.afterCurrent, null);
assert.equal(result.suspended, 'active');
assert.deepEqual(result.next, {
event: 'movement:3', eligible: ['done', 'active', 'later', 'last'],
remaining: ['later', 'last', 'active'], completed: ['done'],
current: 'later', currentStarted: false, protectedLast: 'active',
});
assert.deepEqual(input, before);
assert.notEqual(result.next.eligible, input.queue.eligible);
assert.notEqual(result.next.completed, input.queue.completed);
assert.notEqual(result.next.remaining, input.queue.remaining);
});
void test('started self-last needs explicit Basic admission and cannot create a first or duplicate turn', () => {
const input = context();
reject({ ...input, allowStartedLast: undefined });
reject({ ...input, allowStartedLast: false });
reject(input, 'active', 'first');
reject(input, 'done');
const alone = context();
alone.queue = { ...alone.queue, eligible: ['done', 'active'], remaining: ['active'], completed: ['done'] };
reject(alone);
const advanced = context();
advanced.guild = { player: 'last', granted: false, locked: false };
assert.equal(request(advanced).next.protectedLast, 'active');
const proposed = request(input);
const already = { ...input, queue: proposed.next, started: ['done', 'active'] };
const resumed = request(already, 'active', 'first');
assert.equal(resumed.next.current, 'active');
assert.equal(resumed.next.currentStarted, true);
assert.equal(resumed.next.protectedLast, null);
});
void test('a started actor is bound to its current phase, actor and whole remaining tail', () => {
const input = context(), event = saphoMovementOrderEvent(input);
assert.notEqual(event, input.queue.event);
const changed = context();
changed.queue = { ...changed.queue, remaining: ['active', 'last', 'later'] };
reject(changed, 'active', 'last', event);
const nextPhase = context(); nextPhase.queue = { ...nextPhase.queue, event: 'movement:4' };
reject(nextPhase, 'active', 'last', event);
const changedActor = context();
changedActor.queue = { ...changedActor.queue, remaining: ['later', 'active', 'last'], current: 'later' };
changedActor.started = ['done', 'later'];
reject(changedActor, 'later', 'last', event);
const invalid = context(); invalid.started = ['active', 'later'];
assert.throws(() => saphoMovementOrderEvent(invalid), SaphoMovementOrderError);
});
void test('explicit admission does not change another player’s existing queued-turn reorder', () => {
const input = context(), before = structuredClone(input);
const result = request(input, 'last', 'first');
assert.equal(result.afterCurrent, 'active');
assert.equal(result.suspended, undefined);
assert.deepEqual(result.next.remaining, ['active', 'last', 'later']);
assert.equal(result.next.currentStarted, true);
assert.deepEqual(input, before);
});