scripts/fixtures/ holds the scripts that produced the 2026-11-11 fixtures, with a README on running them safely into a copy. Run in order they reproduce the content of every fixture they touch. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
42 lines
2.9 KiB
JavaScript
42 lines
2.9 KiB
JavaScript
import fs from 'node:fs'
|
|
// Fixture regeneration aid (see scripts/fixtures/README.md). Written during the 2026-11-11 build, kept for reference.
|
|
// Writes into fixtures/ unless FIXTURES_OUT names another directory (with a trailing slash).
|
|
const FIX = process.env.FIXTURES_OUT ?? new URL('../../fixtures/', import.meta.url).pathname
|
|
const SOL = new URL('../../js/solutions/', import.meta.url).href
|
|
const HERE = new URL('./', import.meta.url).pathname
|
|
const S = SOL
|
|
const { update } = await import(S + 'game.js')
|
|
const { Action } = await import(S + 'model.js')
|
|
const p = (x, y) => ({ x, y })
|
|
const base = {
|
|
width: 10, height: 10, snake: [p(5, 5), p(4, 5), p(3, 5)], dir: 'Right', nextDir: 'Right',
|
|
apple: p(0, 0), seed: 1, score: 0, status: 'Playing', frame: 0, queued: null,
|
|
}
|
|
const pending = { ...base, nextDir: 'Up' }
|
|
const queuedLeft = { ...pending, queued: 'Left' }
|
|
const atTop = { ...queuedLeft, snake: [p(5, 0), p(4, 0), p(3, 0)] }
|
|
const cases = [
|
|
['turn-with-no-turn-pending-sets-next-dir', base, Action.Turn('Up')],
|
|
['turn-straight-back-with-no-turn-pending-is-ignored', base, Action.Turn('Left')],
|
|
['perpendicular-key-while-a-turn-is-pending-is-queued', pending, Action.Turn('Left')],
|
|
['key-in-the-current-direction-while-a-turn-is-pending-is-queued', pending, Action.Turn('Right')],
|
|
['a-later-key-replaces-the-queued-one', queuedLeft, Action.Turn('Right')],
|
|
['repeating-the-pending-turn-changes-nothing', queuedLeft, Action.Turn('Up')],
|
|
['reversing-the-pending-turn-changes-nothing', queuedLeft, Action.Turn('Down')],
|
|
['turn-while-paused-with-a-turn-pending-is-not-queued', { ...pending, status: 'Paused' }, Action.Turn('Left')],
|
|
['tick-moves-then-takes-the-queued-turn', queuedLeft, Action.Tick],
|
|
['tick-with-nothing-queued-leaves-next-dir', pending, Action.Tick],
|
|
['frame-step-takes-the-queued-turn', { ...queuedLeft, frame: 7 }, Action.Frame],
|
|
['frame-without-a-step-keeps-the-queue', { ...queuedLeft, frame: 3 }, Action.Frame],
|
|
['tick-that-ends-the-game-keeps-the-queue', atTop, Action.Tick],
|
|
['tick-while-paused-keeps-the-queue', { ...queuedLeft, status: 'Paused' }, Action.Tick],
|
|
['toggle-pause-keeps-the-queue', queuedLeft, Action.TogglePause],
|
|
['restart-clears-the-queue', queuedLeft, Action.Restart],
|
|
].map(([name, s, a]) => ({ name, args: [s, a], expected: update(s, a) }))
|
|
const f = FIX + 'm10-update.json'
|
|
const fx = JSON.parse(fs.readFileSync(f, 'utf8'))
|
|
const names = new Set(cases.map((c) => c.name))
|
|
const out = { ...fx, cases: [...fx.cases.filter((c) => !names.has(c.name)), ...cases] }
|
|
fs.writeFileSync(f, JSON.stringify(out, null, 2) + '\n')
|
|
for (const c of cases) { const [s] = c.args; const e = c.expected; console.log(c.name.padEnd(66), `${s.status} d=${s.dir} n=${s.nextDir} q=${s.queued} head=${JSON.stringify(s.snake[0])} f=${s.frame} -> ${e.status} d=${e.dir} n=${e.nextDir} q=${e.queued} head=${JSON.stringify(e.snake[0])} f=${e.frame} apple=${JSON.stringify(e.apple)} seed=${e.seed}`) }
|