import assert from 'node:assert/strict'; import test from 'node:test'; import { registerHooks } from 'node:module'; import { readFileSync } from 'node:fs'; import { createElement } from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { viewGame, type Action, type GameView } from '../game/engine'; import { RicheseBidPromiseGuide } from '../components/richese-bid-promise-panel'; import { act, inventory, passTruthRicheseFreshDiscard, createTruthRicheseBidFixture, declareTruthRicheseBid, askTruthRicheseBid } from './fixture-truth-richese-bid'; const aliases = registerHooks({ resolve(specifier, context, next) { return next(specifier === 'next/image' ? 'vinext/shims/image' : specifier === 'next/link' ? 'vinext/shims/link' : specifier, context); }, load(url, context, next) { if (!url.endsWith('.module.css')) return next(url, context); const css = readFileSync(new URL(url), 'utf8'); const classes = Object.fromEntries([...css.matchAll(/\.([a-zA-Z_][\w-]*)/g)].map(match => [match[1], match[1]])); return { format: 'module', source: `export default ${JSON.stringify(classes)}`, shortCircuit: true }; }, }); const { GameTable } = await import('../components/game-table'); const { Truthtrance } = await import('../components/truthtrance'); const { RicheseAuctionLot } = await import('../components/richese-auctions'); aliases.deregister(); function table(game: GameView) { return renderToStaticMarkup(createElement(GameTable, { game, busy: false, send: async () => {}, onExit() {} })); } function truth(game: GameView) { return renderToStaticMarkup(createElement(Truthtrance, { game, busy: false, act() {} })); } function auction(game: GameView) { return renderToStaticMarkup(createElement(RicheseAuctionLot, { game, busy: false, act() {} })); } for (const advanced of [false, true]) void test( `${advanced ? 'Advanced' : 'Basic'} real Once Around question, answers and guide connect to the original Richese table`, () => { // Original public R/A/E setup, actual dealt Truth and native cache lot. // The fixture selects only unopened original deal/Spice positions and scalar lotteries. const f = createTruthRicheseBidFixture(advanced); const source = act(f.game, f.asker, { type: 'richeseBid', event: f.lot, amount: null }); assert.equal(source.richeseAuction?.active, f.target); const declared = declareTruthRicheseBid(f, source); const asker = viewGame(declared, f.asker); assert.ok(asker.truthRicheseBidTargets.includes(f.target)); assert.match(truth(asker), /