import assert from 'node:assert/strict'; import test from 'node:test'; import { readFileSync } from 'node:fs'; import { registerHooks } from 'node:module'; import { createElement } from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { viewGame } from '../game/engine'; import { nexusOfferGame } from './fixture-nexus-offer'; 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(m => [m[1], m[1]])); return { format: 'module', source: `export default ${JSON.stringify(classes)}`, shortCircuit: true }; }, }); const { DrawPiles } = await import('../components/draw-piles'); const { GameTable } = await import('../components/game-table'); aliases.deregister(); void test('live table connects named draw counts without an action while controls are busy', () => { const g = nexusOfferGame(); const before = JSON.stringify(g); const html = renderToStaticMarkup(createElement(GameTable, { game: viewGame(g, 'e'), busy: true, send: async () => { assert.fail('Read-only counts must not act.'); }, onExit() {}, })); assert.match(html, /aria-label="Draw piles"/); assert.match(html, /Treachery draw pile<\/dt>