life.test.js

2.5 kB · javascript · 61 lines

1import { expect, test } from "bun:test";2import * as life from "./life.js";34const bytes = await Bun.file(new URL("./pkg/life/mrlyjs_life_bg.wasm", import.meta.url)).arrayBuffer();5life.initSync({ module: bytes });6const rows = await Bun.file(new URL("../mrlyrs/fixtures/life.json", import.meta.url)).json();7const row = (fn) => rows.find((r) => r.fn === fn);8const grid = (seed) => ({ shape: seed.shape, types: Uint8Array.from(seed.data) });9const carpet = grid({ shape: [4, 4], data: [1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0] });10const fates = { Dead: "dead", Alive: "alive", Loop: "loop", Timeout: "timeout" };1112function run(r) {13  const config = new life.Config(life.moore(), life.Counts.list(r.in.config.birth), life.Counts.list(r.in.config.survive));14  expect(config.boundary).toBe(r.in.config.boundary);15  expect(config.max_generations).toBe(r.in.config.max_generations);16  expect(config.grid_size).toBe(r.in.config.grid_size);17  expect(config.padding).toBe(r.in.config.padding);18  return life.animate(grid(r.in.seed), config);19}2021test("life::history", () => {22  const r = row("life::history");23  const diagram = life.history(r.in.row, r.in.rule, r.in.steps, r.in.wrap);24  expect(diagram.shape).toEqual(r.out.shape);25  expect(Array.from(diagram.data)).toEqual(r.out.data);26});2728test("life::animate::animate", () => {29  const r = row("life::animate::animate");30  const played = run(r);31  expect(fates[played.fate]).toBe(r.out.fate);32  expect(played.count).toBe(r.out.count);33  expect(played.loop_length).toBe(r.out.loop_length);34  const last = played.last();35  expect(last.shape).toEqual([r.out.last.height, r.out.last.width]);36  expect(Array.from(last.types)).toEqual(r.out.last.types.flat());37});3839test("life::entropy", () => {40  const r = row("life::entropy");41  expect(Number(life.entropy(carpet))).toBe(r.out);42});4344test("life::churn", () => {45  const r = row("life::churn");46  const zeros = grid({ shape: r.in.grids[0].zeros.shape, data: new Array(16).fill(0) });47  expect(life.churn([zeros, carpet])).toBeCloseTo(r.out, 12);48});4950test("life::counts", () => {51  const r = row("life::counts");52  const counts = life.counts(life.Source.from(r.in.seq), r.in.max_neighbors, r.in.include_zeros, r.in.include_ones);53  expect(Array.from(counts)).toEqual(r.out);54});5556test("life::heatmap", () => {57  const r = row("life::heatmap");58  const frames = life.heatmap(run(r.in.grids).grids, r.in.scale);59  expect(frames.length).toBe(r.out.length);60  frames.forEach((frame, i) => expect(Array.from(frame)).toEqual(r.out[i]));61});