Files
Dune/tests/nexus-ixian-betrayal-selected-decks.test.ts
T
Quintine 7680e1ee69
Verify and publish checkpoint container / container (push) Canceled after 0s
Fix mixed-deck Nexus Betrayal continuations
2026-10-30 18:12:45 +11:00

41 lines
2.5 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { treacheryDeck } from '../game/cards';
import { ecazTreacheryCards } from '../game/ecaz-cards';
import { NEXUS_FACTIONS } from '../game/nexus-cards';
import { richeseCards } from '../game/richese-cards';
import {
closeIxianBetrayalSource, createIxianBetrayalSource, initialIxianBetrayalCursor,
ixianBetrayalResponders, validateIxianBetrayalFrame, validateIxianBetrayalHistory,
type IxianBetrayalContext,
} from '../game/nexus-ixian-betrayal';
for (const independent of [false, true]) void test(
`Basic Ixian Nexus uses actual selected decks with${independent ? '' : 'out'} independent Ecaz cards`, () => {
const expansions = ['ix', 'choam', 'ecaz'];
const ctx: IxianBetrayalContext = {
status:'playing', phase:3, turn:2, advanced:false, sequence:0, expansions, ecazTreachery:independent,
players:[{id:'ix',faction:'ixians'}, {id:'h',faction:'harkonnen'},
{id:'r',faction:'richese'}, {id:'g',faction:'guild'}],
cards:{version:1, deck:NEXUS_FACTIONS.filter(id => id !== 'ixians'),
discard:[], hands:{ix:null,h:'ixians',r:null,g:null}},
physicalCards:[...treacheryDeck(expansions), ...richeseCards(), ...(independent ? ecazTreacheryCards() : [])],
};
const selection = {expansions, ecazTreachery:independent, richese:true};
assert.deepEqual(ixianBetrayalResponders(ctx.cards, ctx.players, selection), ['h']);
validateIxianBetrayalHistory([], initialIxianBetrayalCursor(), ctx.physicalCards, selection);
const authority = {kind:'bidding' as const, provider:'ix', nativeWindow:'ixAuction' as const,
nativeContext:'actual-native-bidding', nativeRequired:[], nativePassed:[]};
const source = createIxianBetrayalSource(ctx, authority, 'parent');
validateIxianBetrayalFrame(ctx, source, authority, 'parent', ['h'], []);
for (const outcome of ['pass', 'use'] as const) {
const result = closeIxianBetrayalSource(source, outcome, outcome === 'use' ? 'h' : null, initialIxianBetrayalCursor());
validateIxianBetrayalHistory([result.receipt], result.cursor, ctx.physicalCards, selection);
}
assert.throws(() => validateIxianBetrayalHistory([], initialIxianBetrayalCursor(), ctx.physicalCards.slice(1), selection));
assert.throws(() => validateIxianBetrayalHistory([], initialIxianBetrayalCursor(), ctx.physicalCards,
{...selection, expansions:['ix', 'choam', 'ecaz', 'ecaz']}));
assert.throws(() => ixianBetrayalResponders(ctx.cards, ctx.players, {...selection, expansions:['ix', 'ecaz']}));
},
);