Files
Dune/tests/richese-no-field-hidden-return.test.ts
T
Quintine bb9d292c4c Compose native Ecaz Betrayal and Moritani Atomics
Retain original selected modules, typed native returns, advisors and hidden No-Field recall. Preserve a full unspent Guild/Sapho opening, paid ordered arrivals, capped provisional No-Field destruction and native World Sneak withdrawal. Bind desert Aftermath to its original Moritani Cunning placement.

Validation: frozen 16-file115/115, types/lint/build, eight finite original-action and GameTable SSR programmes, four minimal legal policies. Document provisional overlaps and corrected genuine recipes. No stored-game change or deployment; full combinations, comprehensive assurance and deployed acceptance remain required.
2026-10-18 11:21:28 +11:00

45 lines
2.9 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
createRicheseNoField, deployRicheseNoField, deployRicheseNoFieldPair,
recallRicheseNoField, projectRicheseNoField, revealRicheseNoField,
validateRicheseNoField, type NoFieldValue,
} from '../game/richese-no-field';
for (const value of [0,3,5] as const) void test(`forced face-down ${value} No-Field return keeps its last-shipment ban without revealing its value`, () => {
const start = createRicheseNoField(['zero','three','five']);
const token = start.tokens.find(token => token.value === value)!;
const location = {territory:'imperial_basin',sector:9};
const deployed = deployRicheseNoField(start, {tokenId:token.id,controller:'richese',location});
const before = structuredClone(deployed);
const returned = recallRicheseNoField(deployed,token.id);
assert.deepEqual(deployed,before);
assert.deepEqual(projectRicheseNoField(returned,false), {deployed:null,lastUsed:null});
assert.equal(returned.lastShipped,token.id);
assert.equal(returned.hiddenReturn,true);
assert.deepEqual(projectRicheseNoField(returned,true).private,returned);
assert.throws(()=>recallRicheseNoField(returned,token.id),/not deployed/);
assert.throws(()=>deployRicheseNoField(returned,{tokenId:token.id,controller:'richese',location}),/twice in a row/);
const next = returned.tokens.find(candidate=>candidate.id!==token.id)!;
const redeployed = deployRicheseNoField(returned,{tokenId:next.id,controller:'richese',location});
assert.equal(Object.hasOwn(redeployed,'hiddenReturn'),false);
const revealed = revealRicheseNoField(redeployed,{tokenId:next.id,reserves:2,cause:'atomics'});
assert.equal(revealed.forces,Math.min(next.value,2));
assert.equal(projectRicheseNoField(revealed.state,false).lastUsed,next.value);
const other = returned.tokens.find(candidate=>candidate.id!==token.id&&candidate.id!==next.id)!;
const pair = deployRicheseNoFieldPair(returned,{tokenId:next.id,controller:'richese',location},other.id,7);
assert.equal(Object.hasOwn(pair.state,'hiddenReturn'),false);
assert.equal(pair.revealed.forces,other.value);
});
void test('the hidden-return marker requires an actual prior shipment and cannot coexist with a deployed token', () => {
const start = createRicheseNoField(['zero','three','five']);
assert.throws(()=>validateRicheseNoField({...start,hiddenReturn:true}),/previous shipment/);
const deployed=deployRicheseNoField(start,{tokenId:'three',controller:'richese',location:{territory:'arrakeen',sector:10}});
assert.throws(()=>validateRicheseNoField({...deployed,hiddenReturn:true}),/previous shipment/);
assert.throws(()=>recallRicheseNoField(deployed,'five'),/not deployed/);
const oldReveal=revealRicheseNoField(deployed,{tokenId:'three',reserves:7,cause:'voluntary'});
assert.equal(Object.hasOwn(oldReveal.state,'hiddenReturn'),false);
assert.equal(projectRicheseNoField(oldReveal.state,false).lastUsed,3 as NoFieldValue);
});