Files
Dune/tests/guild-overlap-child-runtime.test.ts

62 lines
3.8 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { viewGame } from '../game/engine';
import { act, player, type First } from './fixture-basic-native-overlap';
import { createGuildOverlapChildFixture } from './fixture-guild-overlap-child';
for (const first of ['ambassador','terror'] as const satisfies readonly First[])
for (const same of [true,false])
for (const reveal of [false,true]) {
void test(`Basic Guild child ${same?'same':'different'} stronghold, ${first} first, child ${reveal?'reveals':'declines'}`,()=>{
const f=createGuildOverlapChildFixture(first,same), source=f.game;
const originalSpice=player(source,f.entrant).spice;
const beneficiary=player(source,f.owner);
const reserve=beneficiary.reserves,spice=beneficiary.spice;
let game=act(source,f.entrant,f.shipment);
assert.equal(game.pendingArrivalOverlap?.first,first);
const overlapEvent=game.pendingArrivalOverlap!.event;
assert.equal(player(game,f.entrant).spice,originalSpice-1);
assert.equal(player(game,f.entrant).forces[`${f.destination}:${f.sector}`],1);
if(first==='terror') {
assert.equal(game.pendingTerrorEntry?.entrant,f.entrant);
game=act(game,f.moritani,{type:'decision',decline:true});
}
const entry=game.pendingAmbassador; assert.ok(entry);
assert.equal(entry.token,f.ambassador);
const projection=viewGame(game,f.owner).ambassadorEntry; assert.ok(projection);
game=act(game,f.owner,{type:'decision',event:entry.event,trigger:true,beneficiary:f.owner});
assert.equal(game.pendingAmbassador?.stage,'ship');
assert.equal(game.decision?.kind,'ecazAmbassador');
game=act(game,f.owner,{type:'decision',event:entry.event,amount:1,elite:0,
territory:f.childDestination,sector:f.childSector});
assert.equal(player(game,f.owner).reserves,reserve-1);
assert.equal(player(game,f.owner).forces[`${f.childDestination}:${f.childSector}`],1);
assert.equal(player(game,f.owner).spice,spice,'The independent Guild shipment is free');
assert.equal(game.pendingTerrorEntry?.entrant,f.owner);
assert.equal(game.pendingTerrorEntry?.token,f.childTerror);
assert.equal(game.pendingTerrorEntry?.resume,'ambassador');
assert.equal(game.pendingArrivalOverlap?.event,overlapEvent);
assert.equal(game.pendingArrivalOverlap?.ambassadorEvent,entry.event);
if(reveal) {
game=act(game,f.moritani,{type:'decision',reveal:true});
assert.equal(game.pendingTerrorEntry?.stage,'robbery');
game=act(game,f.moritani,{type:'decision',choice:'spice'});
assert.equal(player(game,f.owner).spice,Math.floor(spice/2));
assert.equal(game.moritaniTerror?.tokens.find(token=>token.id===f.childTerror)?.status,'removed');
} else game=act(game,f.moritani,{type:'decision',decline:true});
if(first==='ambassador' && (!same || !reveal)) {
assert.equal(game.pendingTerrorEntry?.entrant,f.entrant,'The original live token keeps its own prior opportunity');
assert.equal(game.pendingTerrorEntry?.token,f.originalTerror);
game=act(game,f.moritani,{type:'decision',decline:true});
}
assert.equal(game.pendingArrivalOverlap,null);
assert.equal(game.pendingAmbassador,null);
assert.equal(game.pendingTerrorEntry,null);
assert.equal(game.ecazAmbassadors?.tokens.find(token=>token.id===f.ambassador)?.zone,'used');
assert.equal(player(game,f.entrant).forces[`${f.destination}:${f.sector}`],1);
assert.equal(player(game,f.entrant).spice,originalSpice-1);
assert.equal(player(game,f.owner).forces[`${f.childDestination}:${f.childSector}`],1);
assert.equal(player(game,f.owner).reserves,reserve-1);
});
}