Files
Dune/tests/ghola-leader-promise-controls.test.tsx
T
Quintine bdd5aaf18c
Verify and publish checkpoint container / container (push) Canceled after 0s
Support multiple named Ghola commitments
2026-10-29 17:50:08 +11:00

67 lines
4.2 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { createElement } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import { GholaLeaderPromises, GholaLeaderPromiseGuideButton } from '../components/ghola-leader-promises';
import { createGame, joinGame, newPlayer, viewGame, type Action } from '../game/engine';
function projected() {
const source = createGame('GHOLAGUIDECONTROLS', newPlayer('p', 'Player', 'emperor'), false);
joinGame(source, newPlayer('a', 'Asker', 'atreides'));
const game = viewGame(source, 'p');
game.status = 'playing'; game.turn = 2; game.phase = 4;
game.allLeaders = [{ id: 'named', name: 'Named Commander', faction: 'emperor', strength: 3 }];
const me = game.players.find(p => p.id === 'p')!;
me.hand = [{ id: 'ghola', name: 'Ghola', kind: 'special', effect: 'ghola' }];
game.ghola = { cards: ['ghola'], leaders: [{ id: 'named', name: 'Named Commander', strength: 3 }],
kwisatz: false, maxForces: 0, eliteRemaining: 0, eliteBlock: null, available: true, reason: null };
game.gholaLeaderPromises = [{ event: 'event', turn: 2, player: 'p', asker: 'a', leader: 'named', answer: true }];
game.gholaLeaderPromiseGuide = { action: { type: 'card', card: 'ghola', leader: 'named' } };
return game;
}
void test('private Ghola promises describe the named actual return and statuses', () => {
const game = projected();
game.gholaLeaderPromises.push({ event: 'foreign', turn: 2, player: 'a', asker: 'p', leader: 'secret', answer: false });
const html = renderToStaticMarkup(createElement(GholaLeaderPromises, { game, busy: false, send() {} }));
assert.match(html, /Named Commander/);
assert.match(html, /ordinary return, a force return, or an earlier Ghola play does not fulfill it/);
assert.doesNotMatch(html, /secret|foreign/);
});
void test('the Ghola guide forwards only the current legal card and leader', () => {
const game = projected(), sent: Action[] = [];
const props = { game, busy: false, send(action: Action) { sent.push(action); } };
const button = GholaLeaderPromiseGuideButton(props); assert.ok(button);
assert.equal(button.props.disabled, false); button.props.onClick();
assert.deepEqual(sent, [game.gholaLeaderPromiseGuide!.action]);
game.ghola.available = false; button.props.onClick();
assert.equal(sent.length, 1);
game.ghola.available = true; game.truthtrance = { stage: 'priority', queue: [], passed: [], question: null } as typeof game.truthtrance;
button.props.onClick(); assert.equal(sent.length, 1);
});
void test('Ghola guide starts the current Box and rejects a stale quote', () => {
const game = projected(), me = game.players.find(player => player.id === 'p')!;
const box = { id: 'box', name: 'Nullentropy Box', kind: 'special' as const, effect: 'nullentropyBox' };
me.hand = [box]; game.nullentropy = { card: box, blocked: null, search: null };
game.gholaLeaderPromiseGuide = { action: { type: 'card', card: box.id } };
const sent: Action[] = [], button = GholaLeaderPromiseGuideButton({ game, busy: false, send(action) { sent.push(action); } });
assert.ok(button); assert.equal(button.props.disabled, false); button.props.onClick();
assert.deepEqual(sent, [game.gholaLeaderPromiseGuide.action]);
game.nullentropy.blocked = 'The search is no longer available.'; button.props.onClick();
assert.equal(sent.length, 1);
});
void test('Ghola guide selects only its current paid Box search card', () => {
const game = projected(), box = { id: 'box', name: 'Nullentropy Box', kind: 'special' as const, effect: 'nullentropyBox' };
const ghola = { id: 'recovered', name: 'Ghola', kind: 'special' as const, effect: 'ghola' };
game.decision = { kind: 'nullentropy', player: 'p' };
game.nullentropy = { card: box, blocked: null, search: { event: 'paid', cards: [ghola] } };
game.gholaLeaderPromiseGuide = { action: { type: 'decision', event: 'paid', card: ghola.id } };
const sent: Action[] = [], button = GholaLeaderPromiseGuideButton({ game, busy: false, send(action) { sent.push(action); } });
assert.ok(button); assert.equal(button.props.disabled, false); button.props.onClick();
assert.deepEqual(sent, [game.gholaLeaderPromiseGuide.action]);
game.nullentropy.search!.cards = []; button.props.onClick(); assert.equal(sent.length, 1);
});