67 lines
4.2 KiB
TypeScript
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);
|
|
});
|