64 lines
3.3 KiB
TypeScript
64 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 {
|
|
createTruthRevivalFixture as fixture, declareTruthRevival as declare,
|
|
actTruthRevival as act, askTruthRevival as ask, answerTruthRevival as answer,
|
|
advanceTruthRevival as advance, finishTruthRevival as finish,
|
|
truthRevivalClean as clean, truthRevivalPlayer as player, truthRevivalInventory as inventory,
|
|
} from './fixture-truth-revival';
|
|
|
|
function reject(game: Game, actor: string, action: Action) {
|
|
const before = structuredClone(game);
|
|
assert.throws(() => act(game, actor, action));
|
|
assert.deepEqual(game, before);
|
|
}
|
|
const shipmentQuestion = (target: string) => ({ kind: 'shipment', target,
|
|
claim: { territory: 'arrakeen', minimum: 3 } });
|
|
|
|
void test('earlier actual shipment Yes reserves its three spice when a later ordinary Revival question is answered', () => {
|
|
const f = fixture();
|
|
let game = declare(f, f.game, { copies: 2 }).game;
|
|
game = act(game, f.asker, { type: 'truthAsk', question: shipmentQuestion(f.target) });
|
|
assert.ok(viewGame(game, f.target).truthShipmentAnswers?.includes('yes'));
|
|
game = answer(game, f.target, 'yes');
|
|
game = ask(game, f.asker, f.target, 3);
|
|
assert.deepEqual(viewGame(game, f.target).truthRevivalAnswers, ['no']);
|
|
reject(game, f.target, { type: 'truthAnswer', answer: 'yes' });
|
|
game = answer(game, f.target, 'no');
|
|
game = act(game, f.target, { type: 'revive', amount: 1, elite: 0 });
|
|
assert.equal(player(game, f.target).spice, 4);
|
|
assert.equal(game.revivalPromises![0].progress, 1);
|
|
reject(game, f.target, { type: 'revive', amount: 2, elite: 0 });
|
|
game = finish(game);
|
|
game = advance(game, state => state.phase === 5 && state.active === f.target && clean(state));
|
|
game = act(game, f.target, { type: 'ship', territory: 'arrakeen', sector: 10, amount: 3, elite: 0, allyPayment: 0 });
|
|
game = advance(game, clean);
|
|
assert.equal(player(game, f.target).spice, 1);
|
|
assert.equal(player(game, f.target).forces['arrakeen:10'], 3);
|
|
assert.ok(game.shipmentPromises!.every(promise => promise.fulfilled));
|
|
assert.ok(game.revivalPromises!.every(promise => promise.fulfilled));
|
|
assert.deepEqual(inventory(game), f.originalCards);
|
|
});
|
|
|
|
void test('earlier ordinary Revival Yes excludes an unaffordable later shipment Yes before the public answer', () => {
|
|
const f = fixture();
|
|
let game = declare(f, f.game, { copies: 2 }).game;
|
|
game = ask(game, f.asker, f.target, 3);
|
|
game = answer(game, f.target, 'yes');
|
|
game = act(game, f.asker, { type: 'truthAsk', question: shipmentQuestion(f.target) });
|
|
assert.deepEqual(viewGame(game, f.target).truthShipmentAnswers, ['no']);
|
|
reject(game, f.target, { type: 'truthAnswer', answer: 'yes' });
|
|
game = answer(game, f.target, 'no');
|
|
const guide = viewGame(game, f.target).revivalPromiseGuide; assert.ok(guide);
|
|
game = act(game, f.target, guide.action);
|
|
assert.equal(player(game, f.target).spice, 0);
|
|
assert.equal(player(game, f.target).tanks, 0);
|
|
assert.ok(game.revivalPromises![0].fulfilled);
|
|
game = finish(game);
|
|
game = advance(game, state => state.phase === 5 && state.active === f.target && clean(state));
|
|
game = act(game, f.target, { type: 'endMovement' });
|
|
assert.ok(game.shipmentPromises!.every(promise => promise.fulfilled));
|
|
assert.deepEqual(inventory(game), f.originalCards);
|
|
});
|