Files
Dune/tests/truth-revival-expression-funding.test.ts
T

105 lines
5.9 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { viewGame } from '../game/engine';
import {
createTruthRevivalExpressionFixture as fixture, declareTruthRevivalExpression as declare,
askTruthRevivalExpression as ask, answerTruthRevivalExpression as answer,
bindTruthRevivalExpression as bind, actTruthRevivalExpression as act,
settleTruthRevivalExpression as settle, finishTruthRevivalExpression as finish,
truthRevivalExpressionPlayer as player, truthRevivalExpressionInventory as inventory,
} from './fixture-truth-revival-expression';
void test('grouped Yes retains whole progress through actual bribe and owned income preparation', () => {
const f = fixture(); let game = declare(f, f.game, { copies: 2 }).game;
game = answer(ask(game, f.asker, f.target, f.claim), f.target, 'yes');
game = act(game, f.asker, { type: 'truthAsk', question: {
kind: 'bribe', target: f.target, turn: game.turn, recipient: f.opponent, minimum: 4,
} });
assert.deepEqual(viewGame(game, f.target).truthBribeAnswers, ['no']);
game = answer(game, f.target, 'no');
const before = structuredClone(game);
assert.throws(() => act(game, f.target, { type: 'bribe', target: f.opponent, amount: 4 }));
assert.deepEqual(game, before);
game = act(game, f.target, { type: 'bribe', target: f.opponent, amount: 3 });
let guide = viewGame(game, f.target).revivalExpressionPromiseGuide; assert.ok(guide);
assert.equal(guide.action.type, 'revive');
game = settle(act(game, f.target, guide.action));
assert.equal(player(game, f.target).spice, 2);
assert.equal(game.revivalExpressionPromises![0].progress.total, 1);
assert.ok(!game.revivalExpressionPromises![0].fulfilled);
guide = viewGame(game, f.target).revivalExpressionPromiseGuide; assert.ok(guide);
assert.equal(guide.action.type, 'reviveLeader');
game = settle(act(game, f.target, guide.action));
assert.equal(player(game, f.target).spice, 0);
assert.equal(game.revivalExpressionPromises![0].fulfilled, true);
assert.equal(player(game, f.opponent).bribes, 3);
game = finish(game); assert.ok(!game.bribePromises![0].fulfilled);
assert.deepEqual(inventory(game), f.originalCards);
});
void test('prior funded Bribe Yes excludes an impossible later grouped AND Yes', () => {
const f = fixture(); let game = declare(f, f.game, { copies: 2 }).game;
game = act(game, f.asker, { type: 'truthAsk', question: {
kind: 'bribe', target: f.target, turn: game.turn, recipient: f.opponent, minimum: 4,
} });
game = answer(game, f.target, 'yes'); game = ask(game, f.asker, f.target, f.claim);
assert.deepEqual(viewGame(game, f.target).truthRevivalExpressionAnswers, ['no']);
const before = structuredClone(game);
assert.throws(() => answer(game, f.target, 'yes')); assert.deepEqual(game, before);
game = answer(game, f.target, 'no');
const guide = viewGame(game, f.target).bribePromiseGuide; assert.ok(guide);
game = act(game, f.target, guide.action); assert.equal(player(game, f.target).spice, 0);
game = finish(game); assert.equal(game.revivalExpressionPromises![0].fulfilled, true);
assert.equal(game.bribePromises![0].fulfilled, true);
assert.deepEqual(inventory(game), f.originalCards);
});
void test('partial ordinary forces preserve a grouped OR until the alternate real leader return', () => {
const f = fixture(), claim = { kind: 'or' as const, terms: [
{ kind: 'forces' as const, counter: 'normal' as const, minimum: 2 }, { kind: 'leader' as const, leader: f.leader },
] };
let game = bind(f, 'yes', claim).game;
game = settle(act(game, f.target, { type: 'revive', amount: 1, elite: 0 }));
assert.equal(game.revivalExpressionPromises![0].progress.normal, 1);
assert.ok(!game.revivalExpressionPromises![0].fulfilled);
const guide = viewGame(game, f.target).revivalExpressionPromiseGuide; assert.ok(guide);
assert.equal(guide.action.type, 'reviveLeader');
game = settle(act(game, f.target, guide.action));
assert.equal(game.revivalExpressionPromises![0].fulfilled, true);
assert.deepEqual(game.revivalExpressionPromises![0].progress.leaders, [f.leader]);
assert.deepEqual(inventory(finish(game)), f.originalCards);
});
void test('earlier native shipment funding excludes a later grouped AND beyond the shared purse', () => {
const f = fixture(); let game = declare(f, f.game, { copies: 2 }).game;
game = act(game, f.asker, { type: 'truthAsk', question: {
kind: 'shipment', target: f.target, claim: { territory: 'arrakeen', minimum: 4 },
} });
game = answer(game, f.target, 'yes'); game = ask(game, f.asker, f.target, f.claim);
assert.deepEqual(viewGame(game, f.target).truthRevivalExpressionAnswers, ['no']);
const before = structuredClone(game);
assert.throws(() => answer(game, f.target, 'yes')); assert.deepEqual(game, before);
game = answer(game, f.target, 'no');
assert.equal(game.shipmentPromises![0].answer, true);
assert.ok(!game.shipmentPromises![0].released);
assert.deepEqual(inventory(game), f.originalCards);
});
void test('earlier grouped AND reserves its real native return budget before a later shipment answer', () => {
const f = fixture(); let game = declare(f, f.game, { copies: 2 }).game;
game = answer(ask(game, f.asker, f.target, f.claim), f.target, 'yes');
game = act(game, f.asker, { type: 'truthAsk', question: {
kind: 'shipment', target: f.target, claim: { territory: 'arrakeen', minimum: 4 },
} });
assert.deepEqual(viewGame(game, f.target).truthShipmentAnswers, ['no']);
game = answer(game, f.target, 'no');
for (let count = 0; count < 3 && !game.revivalExpressionPromises![0].fulfilled; count++) {
const guide = viewGame(game, f.target).revivalExpressionPromiseGuide; assert.ok(guide);
game = settle(act(game, f.target, guide.action));
}
assert.equal(game.revivalExpressionPromises![0].fulfilled, true);
assert.equal(player(game, f.target).spice, 3);
assert.ok(!game.shipmentPromises![0].fulfilled);
assert.deepEqual(inventory(game), f.originalCards);
});