Files
findr-api/test/led-map.test.ts
T
mars3142 cadc280761 Scaffold Fastify + Drizzle API with pick-by-light
Layered: routes -> services -> repositories -> db, over PostgreSQL 18 with
split roles (findr_migrator for DDL, findr_app for DML). Keycloak JWT auth
with per-endpoint scope guards. Drizzle migrations run with the DDL role at
container start.

Pick-by-light: one ESP32 controller drives one WS2812 chain through several
boxes; each box owns a contiguous LED slice. MQTT contract in
src/lib/mqtt-topics.ts / docs/mqtt.md. /v1/pick controls light/idle/off and
/v1/boxes + /v1/controllers manage the strip mapping.

Reference resource /v1/parts wired end to end. Vitest, Biome, multi-stage
Dockerfile, local compose.yml with Postgres.

Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
2026-09-03 01:07:35 +02:00

31 lines
1.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { columnIndex, gridLedIndex, ledIndexFor } from "../src/lib/led-map.js";
describe("led-map", () => {
it("maps column letters to indices", () => {
expect(columnIndex("A")).toBe(0);
expect(columnIndex("d")).toBe(3);
});
it("progressive wiring is row-major", () => {
const grid = { columns: 8, rows: 5, wiring: "progressive" as const };
expect(gridLedIndex("A", 1, grid)).toBe(0);
expect(gridLedIndex("D", 1, grid)).toBe(3);
expect(gridLedIndex("A", 2, grid)).toBe(8);
expect(gridLedIndex("D", 4, grid)).toBe(27);
});
it("serpentine wiring reverses every other row", () => {
const grid = { columns: 8, rows: 5, wiring: "serpentine" as const };
expect(gridLedIndex("A", 1, grid)).toBe(0); // row 1: L→R
expect(gridLedIndex("A", 2, grid)).toBe(15); // row 2: R→L, so col A is last
expect(gridLedIndex("H", 2, grid)).toBe(8);
});
it("an explicit ledIndex overrides the grid", () => {
const grid = { columns: 8, rows: 5, wiring: "progressive" as const };
expect(ledIndexFor({ column: "A", row: 1, ledIndex: 99 }, grid)).toBe(99);
expect(ledIndexFor({ column: "A", row: 1, ledIndex: null }, grid)).toBe(0);
});
});