import { describe, expect, it } from "vitest"; import { digitCompletions, matchingDigitCells, matchingDigitCellsAt, placedDigitAt, toggledDigitHighlight, } from "../../src/state/gameplayHelpers"; describe("digit completion helpers", () => { it.each([4, 6, 9, 12, 16])( "reports undone, done and overdone digits on a %i by %i grid", (size) => { const values = new Array(size * size).fill(0); values.fill(1, 0, size - 1); values.fill(2, size, size * 2); values.fill(3, size * 2, size * 3 + 1); const progress = digitCompletions(size, values); expect(progress).toHaveLength(size); expect(progress[0]).toEqual({ digit: 1, placed: size - 1, target: size, remaining: 1, excess: 0, status: "undone", }); expect(progress[1]).toEqual({ digit: 2, placed: size, target: size, remaining: 0, excess: 0, status: "done", }); expect(progress[2]).toEqual({ digit: 3, placed: size + 1, target: size, remaining: 0, excess: 1, status: "overdone", }); }, ); it("ignores empty, invalid and out-of-grid values without mutating input", () => { const values = [1, 1, 0, -1, 5, Number.NaN, ...new Array(12).fill(0), 1]; const before = [...values]; expect(digitCompletions(4, values)[0]).toMatchObject({ placed: 2, remaining: 2, status: "undone", }); expect(values).toEqual(before); }); it.each([0, 3, 17, 4.5, Number.NaN])( "rejects unsupported puzzle size %s", (size) => { expect(() => digitCompletions(size, [])).toThrow(RangeError); }, ); }); describe("digit match highlighting", () => { const values = [4, 0, 2, 4, 0, 3, 4, 0, 2, 0, 3, 0, 4, 2, 0, 3]; it("resolves a placed digit and all of its matching cells", () => { expect(placedDigitAt(4, values, 3)).toBe(4); expect(matchingDigitCells(4, values, 4)).toEqual([0, 3, 6, 12]); expect(matchingDigitCellsAt(4, values, 3)).toEqual([0, 3, 6, 12]); }); it("treats empty, invalid and out-of-grid cells as no match", () => { expect(placedDigitAt(4, values, 1)).toBeNull(); expect(placedDigitAt(4, values, -1)).toBeNull(); expect(placedDigitAt(4, values, 16)).toBeNull(); expect(matchingDigitCellsAt(4, values, 1)).toEqual([]); expect(matchingDigitCells(4, values, 0)).toEqual([]); expect(matchingDigitCells(4, values, 5)).toEqual([]); }); it("toggles repeated Ctrl/Cmd-style activation and preserves empty clicks", () => { expect(toggledDigitHighlight(4, values, 0, null)).toBe(4); expect(toggledDigitHighlight(4, values, 3, 4)).toBeNull(); expect(toggledDigitHighlight(4, values, 2, 4)).toBe(2); expect(toggledDigitHighlight(4, values, 1, 4)).toBe(4); }); it("never returns cells beyond the declared grid", () => { expect(matchingDigitCells(4, [...values, 4, 4], 4)).toEqual([0, 3, 6, 12]); }); });