79 lines
4.4 KiB
TypeScript
79 lines
4.4 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { TERRITORIES } from '../game/board';
|
|
import {
|
|
finishMovementPromises, movementClaimText, movementEventAllowed, movementMatches,
|
|
parseMovementClaim, settleMovementEvent, validMovementClaim, type MovementPromise,
|
|
} from '../game/movement-promises';
|
|
|
|
const destination = TERRITORIES.find(row => row.sectors.length >= 2)!;
|
|
assert.ok(destination);
|
|
const [first, second] = destination.sectors;
|
|
const promise = (sector: number | undefined, answer: boolean, minimum = 2): MovementPromise => ({
|
|
territory: destination.id, minimum, ...(sector === undefined ? {} : { sector }),
|
|
event: 'promise', turn: 1, player: 'owner', asker: 'asker', answer,
|
|
});
|
|
const movement = (sector: number | undefined, amount = 2) => ({
|
|
territory: destination.id, amount, ...(sector === undefined ? {} : { sector }),
|
|
});
|
|
|
|
void test('movement claim accepts one actual printed sector and preserves original territory-only data', () => {
|
|
const claim = { territory: destination.id, minimum: 2, sector: first };
|
|
assert.deepEqual(parseMovementClaim(claim), claim);
|
|
assert.match(movementClaimText(claim), new RegExp(`sector ${first}`));
|
|
assert.deepEqual(parseMovementClaim({ territory: destination.id, minimum: 2 }),
|
|
{ territory: destination.id, minimum: 2 });
|
|
assert.equal(JSON.stringify(parseMovementClaim({ territory: destination.id, minimum: 2 })),
|
|
JSON.stringify({ territory: destination.id, minimum: 2 }));
|
|
assert.deepEqual(parseMovementClaim({ ...claim, turn: 1, player: 'owner' }), claim);
|
|
for (const invalid of [undefined, null, -1, 1.1, '1', Math.max(...destination.sectors) + 100]) {
|
|
assert.equal(validMovementClaim({ ...claim, sector: invalid }), false);
|
|
assert.throws(() => parseMovementClaim({ ...claim, sector: invalid }));
|
|
}
|
|
});
|
|
|
|
void test('sector match requires the actual movement destination, not a missing or different sector', () => {
|
|
const exact = promise(first, true), generic = promise(undefined, true);
|
|
assert.equal(movementMatches(exact, movement(first)), true);
|
|
assert.equal(movementMatches(exact, movement(second)), false);
|
|
assert.equal(movementMatches(exact, movement(undefined)), false);
|
|
assert.equal(movementMatches(exact, movement(first, 1)), false);
|
|
assert.equal(movementMatches(exact, movement(first, 21)), false);
|
|
assert.equal(movementMatches(exact, null), false);
|
|
assert.equal(movementMatches(generic, movement(first)), true);
|
|
assert.equal(movementMatches(generic, movement(second)), true);
|
|
assert.equal(movementMatches(generic, movement(undefined)), true);
|
|
});
|
|
|
|
void test('Yes remains live through other sectors and smaller groups; one actual group fulfills it', () => {
|
|
const original = [promise(first, true, 3)];
|
|
const other = settleMovementEvent(original, 'owner', 1, movement(second, 4));
|
|
assert.equal(other[0].fulfilled, undefined);
|
|
const small = settleMovementEvent(other, 'owner', 1, movement(first, 2));
|
|
assert.equal(small[0].fulfilled, undefined);
|
|
assert.throws(() => finishMovementPromises(small, 'owner', 1));
|
|
const matching = settleMovementEvent(small, 'owner', 1, movement(first, 3));
|
|
assert.equal(matching[0].fulfilled, true);
|
|
assert.equal(original[0].fulfilled, undefined);
|
|
assert.equal(finishMovementPromises(matching, 'owner', 1)[0].fulfilled, true);
|
|
});
|
|
|
|
void test('No blocks only its exact sector and retains the restriction across other movements', () => {
|
|
const original = [promise(first, false)];
|
|
assert.equal(movementEventAllowed(original, movement(first)), false);
|
|
assert.throws(() => settleMovementEvent(original, 'owner', 1, movement(first)));
|
|
const allowed = settleMovementEvent(original, 'owner', 1, movement(second));
|
|
assert.equal(allowed[0].fulfilled, undefined);
|
|
assert.equal(movementEventAllowed(allowed, movement(first)), false);
|
|
assert.equal(finishMovementPromises(allowed, 'owner', 1)[0].fulfilled, true);
|
|
});
|
|
|
|
void test('distinct exact-sector Yes claims can be fulfilled by two distinct physical moves', () => {
|
|
const rows = [promise(first, true), { ...promise(second, true), event: 'second-promise' }];
|
|
const firstMove = settleMovementEvent(rows, 'owner', 1, movement(first));
|
|
assert.equal(firstMove[0].fulfilled, true); assert.equal(firstMove[1].fulfilled, undefined);
|
|
assert.throws(() => finishMovementPromises(firstMove, 'owner', 1));
|
|
const secondMove = settleMovementEvent(firstMove, 'owner', 1, movement(second));
|
|
assert.ok(secondMove.every(row => row.fulfilled));
|
|
});
|