57 lines
3.3 KiB
TypeScript
57 lines
3.3 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { viewGame, type Action, type Game } from '../game/engine';
|
|
import {
|
|
actTruthTurnAction as act, advanceTruthTurnAction as advance, bindTruthTurnAction as bind,
|
|
createTruthTurnActionFixture as fixture, finishTruthTurnAction as finish,
|
|
settleTruthTurnAction as settle, truthTurnActionClean as clean,
|
|
truthTurnActionInventory as inventory, truthTurnActionPlayer as player,
|
|
truthTurnActionPromise as promise, truthTurnActionShip as ship,
|
|
} from './fixture-truth-turn-action';
|
|
|
|
function reject(game: Game, actor: string, action: Action) {
|
|
const before = structuredClone(game);
|
|
assert.throws(() => act(game, actor, action));
|
|
assert.deepEqual(game, before, 'Rejected actions preserve both original receipts.');
|
|
}
|
|
|
|
/** Real Basic three-seat game, actual dealt Truthtrance and native movement
|
|
* window. This schedules the later public obligation first; it then asks and
|
|
* fulfills a distinct genuine whole-turn Truthtrance shipment in turn one. */
|
|
void test('a completed earlier whole-turn Truthtrance receipt preserves a scheduled future travel deal through rollover', () => {
|
|
const f = fixture(), dueTurn = f.game.turn + 1, originalCards = inventory(f.game);
|
|
let game = act(f.game, f.asker, {type:'dealOffer', target:f.target, terms:'Ship to Polar Sink next turn.',
|
|
travel:{kind:'ship', territory:'polar_sink', minimum:1, answer:true, dueTurn}});
|
|
const deal = game.deals?.at(-1); assert.ok(deal);
|
|
game = act(game, f.target, {type:'dealRespond', deal:deal.id, accept:true});
|
|
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'scheduled');
|
|
const scheduled = game.travelPromises?.find(row => row.sourceDeal === deal.id); assert.ok(scheduled);
|
|
assert.equal(scheduled.turn, dueTurn); assert.equal(scheduled.player, f.target);
|
|
assert.equal(scheduled.fulfilled, false); assert.equal(scheduled.released, false);
|
|
|
|
game = bind(f, 'yes', ship(), game).game;
|
|
const truth = game.turnActionPromises?.at(-1); assert.ok(truth);
|
|
assert.equal(truth.turn, f.game.turn); assert.equal(truth.player, f.target);
|
|
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'scheduled');
|
|
reject(game, f.target, f.end);
|
|
game = settle(act(game, f.target, f.shipment));
|
|
assert.equal(promise(game, f.target).fulfilled, true);
|
|
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'scheduled');
|
|
assert.equal(game.travelPromises?.find(row => row.sourceDeal === deal.id)?.fulfilled, false);
|
|
const firstForces = player(game, f.target).forces['polar_sink:0'];
|
|
game = settle(act(game, f.target, f.end));
|
|
game = finish(game);
|
|
assert.equal(game.turn, dueTurn);
|
|
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'pending');
|
|
assert.equal(promise(game, f.target).fulfilled, true);
|
|
|
|
game = advance(game, state => state.turn === dueTurn && state.phase === 5 &&
|
|
state.active === f.target && clean(state) && !state.pendingShipment, [], true);
|
|
reject(game, f.target, f.end);
|
|
game = settle(act(game, f.target, f.shipment));
|
|
assert.equal(viewGame(game, f.target).dealTravelStatus[deal.id], 'fulfilled');
|
|
assert.equal(player(game, f.target).forces['polar_sink:0'], firstForces + 1);
|
|
assert.equal(promise(game, f.target).fulfilled, true);
|
|
assert.deepEqual(inventory(game), originalCards);
|
|
});
|