import { describe, it, expect } from 'vitest'; import { readFileSync } from 'node:fs'; import { RULESETS } from './ruleset'; import type { Variant } from '../model'; // The offline engine is self-contained: it carries each variant's tile values, bag counts and // blank count in ruleset.ts (these are not otherwise on the client — online scoring uses the // server-sent alphabet). This pins that hand-copied table to the Go rulesets // (scrabble-solver/rules), whose values the movegen tool dumps to testdata/rulesets.json. interface RulesetFix { size: number; rackSize: number; bingo: number; blanks: number; values: number[]; counts: number[]; } const fx = JSON.parse( readFileSync(new URL('./testdata/rulesets.json', import.meta.url), 'utf8'), ) as Record; describe('offline ruleset table parity vs Go rules', () => { for (const variant of Object.keys(fx) as Variant[]) { it(variant, () => { const rs = RULESETS[variant]; expect({ size: rs.size, rackSize: rs.rackSize, bingo: rs.bingo, blanks: rs.blanks, values: [...rs.values], counts: [...rs.counts], }).toEqual(fx[variant]); }); } });