Files
Dune/tests/fixture-sapho-truth-auction.ts

71 lines
4.7 KiB
TypeScript

import assert from 'node:assert/strict';
import { type Game } from '../game/engine';
import { createSaphoStartedMovementFixture, advanceSaphoStartedMovement,
saphoStartedMovementClean } from './fixture-sapho-started-movement';
import { act, inventory, player, truthOrderFrame } from './fixture-sapho-truth-order';
export { act, inventory, player };
/** Genuine public R/A/E/G setup and original cache1 Sapho purchase. Continue
* that acquired snapshot through native actions to a quiet original ordinary
* auction. Controlled supplemental custody swaps one actually dealt Truth
* with Emperor's other held original card so the Sapho owner is a holder.
* No purse, force, phase, auction, receipt or physical card is installed. */
export function createSaphoTruthAuctionFixture(options: {
advanced?:boolean; standingBid?:boolean; mode?:'first'|'last';
} = {}) {
const advanced = options.advanced ?? false, standingBid = options.standingBid ?? false, mode = options.mode ?? 'first';
const source = createSaphoStartedMovementFixture({advanced,truthFor:['richese','guild']});
let game = advanceSaphoStartedMovement(structuredClone(source.acquired), state =>
state.phase === 3 && !!state.auction && saphoStartedMovementClean(state));
assert.ok(game.auction); assert.equal(game.auction.bid,0); assert.equal(game.auction.bidder,null);
if (standingBid) {
const actor = game.auction.active;
game = act(game,actor,{type:'bid',amount:1,allyPayment:0});
assert.equal(game.auction?.bid,1); assert.equal(game.auction?.bidder,actor);
assert.ok(saphoStartedMovementClean(game));
}
const owner = source.owner;
const possible = (['richese','guild'] as const).filter(id => mode === 'first'
? game.order.indexOf(id) < game.order.indexOf(owner)
: game.order.indexOf(id) > game.order.indexOf(owner));
assert.ok(possible.length,`Original public storm order needs a holder on the ${mode} side of Emperor`);
const other = possible[0], donor = other === 'richese' ? 'guild' : 'richese';
const from = player(game,donor), receiver = player(game,owner);
const truthAt = from.hand.findIndex(card => card.effect === 'truthtrance'); assert.ok(truthAt >= 0);
const exchangeAt = receiver.hand.findIndex(card => card.id !== source.card && card.effect !== 'truthtrance'); assert.ok(exchangeAt >= 0);
const [truth] = from.hand.splice(truthAt,1), [exchange] = receiver.hand.splice(exchangeAt,1);
from.hand.push(exchange); receiver.hand.push(truth);
const otherTruth = player(game,other).hand.find(card => card.effect === 'truthtrance'); assert.ok(otherTruth);
assert.ok(receiver.hand.some(card => card.id === source.card));
assert.deepEqual(inventory(game),source.originalInventory);
const parent = {auction:structuredClone(game.auction), aid:structuredClone(game.aid),
turn:game.turn, phase:game.phase, active:game.active, order:[...game.order],
players:game.players.map(row => ({id:row.id,spice:row.spice,reserves:row.reserves,tanks:row.tanks}))};
const beforeTruth = structuredClone(game);
for (const actor of [owner,other]) {
const card = player(game,actor).hand.find(row => row.effect === 'truthtrance'); assert.ok(card);
game = act(game,actor,{type:'card',card:card.id});
}
while (game.truthtrance?.stage === 'priority') {
const actor = game.players.find(row => !game.truthtrance!.passed.includes(row.id)); assert.ok(actor);
game = act(game,actor.id,{type:'truthPass'});
}
const frame = truthOrderFrame(game);
assert.deepEqual([...frame.holders].sort(),[owner,other].sort());
assert.deepEqual(game.auction,parent.auction); assert.deepEqual(game.aid,parent.aid);
const queue = game.truthtrance!.queue.map(row => row.player);
assert.equal(mode === 'first' ? queue.at(-1) : queue[0],owner);
assert.deepEqual(inventory(game),source.originalInventory);
return {game,source,beforeTruth,advanced,standingBid,mode,owner,other,donor,card:source.card,
truth:truth.id,otherTruth:otherTruth.id,parent,originalCards:source.originalInventory,
disclosure:'Original public setup, real cache Sapho purchase and ordinary lot; one labelled original dealt Truth↔held card swap.'};
}
export type SaphoTruthAuctionFixture = ReturnType<typeof createSaphoTruthAuctionFixture>;
/** Keep the actual ordinary lot and winning invoice intact while the overlay is live. */
export function assertAuctionParent(game: Game, parent: SaphoTruthAuctionFixture['parent']) {
assert.equal(game.turn,parent.turn); assert.equal(game.phase,parent.phase); assert.equal(game.active,parent.active);
assert.deepEqual(game.order,parent.order); assert.deepEqual(game.auction,parent.auction); assert.deepEqual(game.aid,parent.aid);
assert.deepEqual(game.players.map(row => ({id:row.id,spice:row.spice,reserves:row.reserves,tanks:row.tanks})),parent.players);
}