import { describe, expect, it } from "vitest"; import { SUDOKU_DOCUMENT_SCHEMA, cloneSudokuDocument, normalizeSudokuDocument, parseSudokuDocument, serializeSudokuDocument, type SudokuDocument, } from "../../src/formats"; import { aidMemoireToPortable, createAidMemoire, enterAidMemoireCell, labelAidMemoireCell, MAX_AID_MEMOIRE_CELLS, } from "../../src/state/aidMemoire"; function baseDocument(): SudokuDocument { return { schema: SUDOKU_DOCUMENT_SCHEMA, version: 1, size: 9, givens: Array(81).fill(0), constraints: [], }; } describe("portable aid-mémoire document data", () => { it("normalizes, serializes and deeply clones scratch cells", () => { let state = createAidMemoire(9, { enabled: true, cellCount: 3, columns: 2, }); state = labelAidMemoireCell(state, 0, "Prime"); state = enterAidMemoireCell(state, 0, "corner", 2, 9); state = enterAidMemoireCell(state, 0, "center", 7, 9); state = enterAidMemoireCell(state, 0, "color", 4, 9); const source: SudokuDocument = { ...baseDocument(), aidMemoire: aidMemoireToPortable(state, 9), }; const parsed = parseSudokuDocument(serializeSudokuDocument(source)); expect(parsed.aidMemoire).toEqual(source.aidMemoire); const clone = cloneSudokuDocument(parsed); (clone.aidMemoire!.cells[0]!.cornerMarks as number[])[0] = 9; expect(parsed.aidMemoire?.cells[0]?.cornerMarks).toEqual([2]); }); it("rejects unbounded layouts and out-of-range scratch symbols", () => { expect(() => normalizeSudokuDocument({ ...baseDocument(), aidMemoire: { version: 1, enabled: true, columns: 1, cells: Array.from({ length: MAX_AID_MEMOIRE_CELLS + 1 }, () => ({})), }, }), ).toThrow(/aidMemoire.cells must contain 1 to 36/u); expect(() => normalizeSudokuDocument({ ...baseDocument(), aidMemoire: { version: 1, enabled: true, columns: 1, cells: [{ label: "Bad", value: 10 }], }, }), ).toThrow(/value must be an integer from 0 to 9/u); }); });