66 lines
3.6 KiB
TypeScript
66 lines
3.6 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { applyAction, createGame, newPlayer } from '../game/engine';
|
|
import { baseDeck } from '../game/cards';
|
|
import { createDukeVidal, DUKE_VIDAL_ID } from '../game/duke-vidal';
|
|
import { newRevivalRules } from '../game/revival';
|
|
import { actDukeAmbassador, createDukeAmbassadorFixture } from './fixture-duke-ambassador';
|
|
|
|
/** Stage the public dead Duke and capture marker in an Advanced roster; the
|
|
* actual return uses the native action. */
|
|
function revivalSource(legacy = false) {
|
|
const game = createGame('DUKEPUBLICREVIVAL', newPlayer('ec', 'Ecaz', 'ecaz'), true, ['ecaz']);
|
|
game.players.push(newPlayer('m', 'Moritani', 'moritani'), newPlayer('g', 'Guild', 'guild'));
|
|
Object.assign(game, { status: 'playing', turn: 3, phase: 4, order: ['ec', 'm', 'g'],
|
|
revivalRules: newRevivalRules() });
|
|
game.dukeVidal = createDukeVidal();
|
|
Object.assign(game.dukeVidal.leader, { dead: true, deaths: 1 });
|
|
game.players[0].spice = 10;
|
|
game.players[0].leaders.slice(0, 4).forEach(leader => Object.assign(leader, { dead: true, deaths: 1 }));
|
|
game.deck = baseDeck();
|
|
if (legacy) delete game.dukeCaptureUncertain;
|
|
else game.dukeCaptureUncertain = true;
|
|
return game;
|
|
}
|
|
|
|
for (const legacy of [false, true]) {
|
|
void test(`public paid Duke revival clears ${legacy ? 'legacy' : 'uncertain'} capture history`, () => {
|
|
const source = revivalSource(legacy), initial = structuredClone(source), before = source.players[0].spice;
|
|
assert.throws(() => applyAction(source, 'ec', { type: 'reviveLeader', leader: 'not-a-leader' }));
|
|
assert.deepEqual(source, initial, 'Rejected action does not clear uncertainty or spend spice');
|
|
const done = applyAction(source, 'ec', { type: 'reviveLeader', leader: DUKE_VIDAL_ID });
|
|
assert.equal(done.dukeCaptureUncertain, false);
|
|
assert.equal(done.dukeVidal!.leader.dead, false);
|
|
assert.equal(done.dukeVidal!.controller, null);
|
|
assert.equal(done.players[0].spice, before - 5);
|
|
assert.ok(done.log.some(entry => entry.text.includes('revived Duke Prad Vidal')));
|
|
});
|
|
|
|
void test(`public Ghola Duke revival clears ${legacy ? 'legacy' : 'uncertain'} capture history`, () => {
|
|
const source = revivalSource(legacy);
|
|
const index = source.deck.findIndex(card => card.effect === 'ghola'); assert.ok(index >= 0);
|
|
const card = source.deck.splice(index, 1)[0]; source.players[0].hand.push(card);
|
|
const done = applyAction(source, 'ec', { type: 'card', card: card.id, leader: DUKE_VIDAL_ID });
|
|
assert.equal(done.dukeCaptureUncertain, false);
|
|
assert.equal(done.dukeVidal!.leader.dead, false);
|
|
assert.equal(done.dukeVidal!.controller, null);
|
|
assert.ok(done.log.some(entry => entry.text.includes('revived Duke Prad Vidal with Ghola')));
|
|
assert.ok(done.discard.some(item => item.id === card.id));
|
|
});
|
|
}
|
|
|
|
void test('public Tleilaxu Ambassador Duke return clears uncertainty, but decline does not', () => {
|
|
const f = createDukeAmbassadorFixture(), source = structuredClone(f.currentGrant);
|
|
source.dukeCaptureUncertain = true;
|
|
const declined = actDukeAmbassador(structuredClone(source), f.owner,
|
|
{ type: 'decision', event: f.event, decline: true });
|
|
assert.equal(declined.dukeCaptureUncertain, true);
|
|
assert.equal(declined.dukeVidal!.leader.dead, true);
|
|
const done = actDukeAmbassador(source, f.owner,
|
|
{ type: 'decision', event: f.event, leader: DUKE_VIDAL_ID });
|
|
assert.equal(done.dukeCaptureUncertain, false);
|
|
assert.equal(done.dukeVidal!.leader.dead, false);
|
|
assert.equal(done.dukeVidal!.controller, null);
|
|
assert.ok(done.log.some(entry => entry.text.includes('revived Duke Prad Vidal for free through the Tleilaxu Ambassador')));
|
|
});
|