Files
functional-programming-snake/js/test/m10-extensions.test.js
T

52 lines
2.2 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { update, movesEvery } from '../src/game.js'
import { keyToAction } from '../src/input.js'
import { speedActions, main, FRAME_MS } from '../src/app.js'
import { run } from '../src/stream.js'
import { trace } from '../src/io.js'
import { view } from '../src/view.js'
import { newGame } from '../src/spawn.js'
import { Action } from '../src/model.js'
import { loadFixture, freeze } from './helpers.js'
const fixtureTests = (name, f) => {
const fx = loadFixture(name)
fx.cases.forEach((c) =>
test(`m10 ${fx.function}: ${c.name}`, () => assert.deepStrictEqual(f(...freeze(c.args)), c.expected)))
}
fixtureTests('m10-update', update)
fixtureTests('m10-moves-every', movesEvery)
fixtureTests('m10-input', keyToAction)
const time = (t) => ({ tag: 'Time', t })
test('m10 the animation clock runs every 25 ms', () => assert.equal(FRAME_MS, 25))
test('m10 speedActions turns the clock into Frame actions every 25 ms', () =>
assert.deepStrictEqual(
run(speedActions, freeze([25, 50, 75, 100, 125, 150, 175, 200].map(time))),
Array.from({ length: 8 }, () => Action.Frame)))
test('m10 speedActions still turns keys into actions, including pause and restart', () =>
assert.deepStrictEqual(
run(speedActions, freeze([{ tag: 'KeyDown', key: ' ' }, { tag: 'KeyDown', key: 'r' }, { tag: 'KeyDown', key: 'ArrowUp' }])),
[Action.TogglePause, Action.Restart, Action.Turn('Up')]))
test('m10 main (seed 42) draws a moved snake after eight 25 ms frames', () => {
const { ops, result: stream } = trace(main, 42)
assert.deepStrictEqual(ops, [{ tag: 'RandomSeed' }])
const [first, afterFirst] = stream.step(time(0))
assert.deepStrictEqual(trace(first[0], 0).ops.map((o) => o.shape), view(newGame(42)))
const [drawings] = [25, 50, 75, 100, 125, 150, 175, 200].reduce(
([outs, s], t) => {
const [out, next] = s.step(time(t))
return [[...outs, ...out], next]
},
[[], afterFirst])
assert.equal(drawings.length, 8)
const moved = { ...newGame(42), snake: newGame(42).snake.map((p) => ({ x: p.x + 1, y: p.y })), frame: 8 }
assert.deepStrictEqual(trace(drawings[7], 0).ops.map((o) => o.shape), view(moved))
})