Files
Dune/tests/selected-independent-nexus-entry.test.ts
T
Quintine 8422cf1f2d Compose selected E1/E2 independent cards with Nexus rules
Retain selected decks and original optional modules through normal setup, distinguish native Ixian Betrayal from absent-faction replacement, route explicit CHOAM fuel before printed effects, and preserve native No-Field invoices and pair continuation. Connect canonical native cancellation stock and existing human/minimal AI consumers.

Validation: 194 affected tests across 19 files, types/lint/build, bounded native invoice review and seven finite original-action/rendered-control programmes. Runtime ec5ad6c18996d8d958ec0d01132ef3e3ea6d23d36188902eca9a63d4db2efbf8; documentation-only proof overlay a5892004937434429916496497c07a3838a324b4a5d64d4a0eb804ab5212d5bd. Other envelopes, full combinations, comprehensive assurance and deployed acceptance remain open. No saved-room/provider changes.
2026-10-18 10:46:21 +11:00

58 lines
3.9 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { selectedIndependentNexusProfile, nexusCoreProfile } from '../game/faction-module-profile';
import { createTechTokens } from '../game/tech-tokens';
import { createSelectedIndependentEntry, type SelectedIndependentEntryOptions } from './fixture-selected-independent-nexus-entry';
const entries: SelectedIndependentEntryOptions[] = [
{expansions:['ix'], factions:['ixians','tleilaxu','atreides']},
{expansions:['choam'], factions:['richese','choam','guild'], advanced:true, skills:true, homeworlds:true, tech:true, strongholds:true},
{expansions:['ix','choam'], factions:['ixians','richese','harkonnen','atreides'], advanced:true, skills:true, homeworlds:true, tech:true, strongholds:true},
{expansions:['ix','choam'], factions:['atreides','guild']},
{expansions:['choam'], factions:['emperor','atreides'], advanced:true, homeworlds:true, strongholds:true},
{expansions:['ix'], factions:['tleilaxu','guild'], homeworlds:true},
];
for (const options of entries) void test(`normal independent Nexus entry ${options.expansions.join('+')}/${options.factions.join('+')} retains selected components`, () => {
const {lobby, setup, game} = createSelectedIndependentEntry(options);
assert.equal(lobby.lobbyOptions?.ecazTreachery, true);
assert.equal(lobby.nexusCards?.cards, null);
assert.equal(game.ecazTreachery, true);
assert.deepEqual(game.expansions, options.expansions);
assert.equal(nexusCoreProfile(game), true);
assert.equal(selectedIndependentNexusProfile(game), true);
assert.equal(!!game.leaderSkills, !!options.skills);
assert.equal(!!game.homeworlds, !!options.homeworlds);
assert.equal(!!game.techTokens, !!options.tech);
assert.equal(!!game.strongholdCards, !!options.strongholds);
assert.equal(game.phase, 0);
assert.equal(game.nexusCards!.cards!.deck.length, 12);
assert.ok(Object.values(game.nexusCards!.cards!.hands).every(card => card === null));
const ordinary = game.deck.length + game.discard.length + game.players.reduce((sum, player) => sum + player.hand.length, 0);
assert.equal(ordinary, options.expansions.includes('ix') ? 50 : 38);
assert.equal(game.richeseCache?.length ?? 0, options.factions.includes('richese') ? 10 : 0);
assert.equal(!!game.nexusIxianReplacementPreview, !options.factions.includes('ixians'));
assert.equal(!!game.nexusIxianBetrayalPreview, options.factions.includes('ixians'));
assert.equal(!!game.nexusHarkonnenBetrayalPreview, options.factions.includes('harkonnen'));
assert.equal(!!game.guildBetrayalPreview, options.factions.includes('guild'));
if (options.skills) assert.ok(['skillTreachery','leaderSkills'].includes(setup.setupStage!),
'The original Ixian starting-card choice may precede skill training');
if (setup.techTokens) {
assert.ok(Object.values(lobby.techTokens!).every(token => token.owner === null));
assert.deepEqual(setup.techTokens, createTechTokens(setup.players),
'Original setup assigns each seated native its printed Tech token; missing natives wait for Storm');
}
if (game.strongholdCards) assert.ok(Object.values(game.strongholdCards.owners).every(owner => owner === null));
});
void test('selected core capability requires real independent cards and selected registered seats', () => {
const base = {advanced:true, expansions:['ix'], players:[{faction:'ixians'},{faction:'atreides'}], nexusCards:true, ecazTreachery:true};
assert.equal(selectedIndependentNexusProfile(base), true);
for (const invalid of [
{...base, ecazTreachery:false}, {...base, expansions:['ix','ix']},
{...base, players:[{faction:'ixians'},{faction:'richese'}]},
{...base, players:[{faction:'ixians'},{faction:'ixians'}]},
{...base, techTokens:true}, {...base, advanced:false, strongholdCards:true},
{...base, discoveryEnabled:true}, {...base, semutaPreview:true},
]) assert.equal(selectedIndependentNexusProfile(invalid), false);
});