feat: expand sudoku analysis and interoperability
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import { render, screen, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { HelpersWorkspace } from "../../src/components/HelpersWorkspace";
|
||||
import { createEmptyPuzzle, normalizePuzzle } from "../../src/domain";
|
||||
|
||||
function mask(...digits: number[]): number {
|
||||
return digits.reduce((value, digit) => value | (2 ** (digit - 1)), 0);
|
||||
}
|
||||
|
||||
describe("Sum Lab helper", () => {
|
||||
const puzzle = normalizePuzzle(createEmptyPuzzle(9));
|
||||
|
||||
it("eliminates and restores combinations without changing the inputs", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
<HelpersWorkspace
|
||||
size={9}
|
||||
puzzle={puzzle}
|
||||
values={puzzle.givens}
|
||||
selectedCells={[]}
|
||||
candidateMasks={Array<number>(81).fill(0)}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("tab", { name: "Sum Lab" }));
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Generalized Sum Lab" }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("4", { selector: "strong" })).toBeInTheDocument();
|
||||
|
||||
const combination = screen.getByRole("button", {
|
||||
name: "1 + 9; eliminate",
|
||||
});
|
||||
await user.click(combination);
|
||||
|
||||
expect(
|
||||
screen.getByRole("button", { name: "1 + 9; restore" }),
|
||||
).toHaveAttribute("aria-pressed", "true");
|
||||
expect(
|
||||
screen.getByText("3", { selector: ".metric-row strong" }).parentElement,
|
||||
).toHaveTextContent("3 active of 4");
|
||||
expect(screen.getByRole("button", { name: "Restore all" })).toBeEnabled();
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Restore all" }));
|
||||
expect(
|
||||
screen.getByRole("button", { name: "1 + 9; eliminate" }),
|
||||
).toHaveAttribute("aria-pressed", "false");
|
||||
});
|
||||
|
||||
it("filters through selected board-cell candidate masks", async () => {
|
||||
const user = userEvent.setup();
|
||||
const candidateMasks = Array<number>(81).fill(0);
|
||||
candidateMasks[0] = mask(1, 2);
|
||||
candidateMasks[1] = mask(8, 9);
|
||||
render(
|
||||
<HelpersWorkspace
|
||||
size={9}
|
||||
puzzle={puzzle}
|
||||
values={puzzle.givens}
|
||||
selectedCells={[0, 1]}
|
||||
candidateMasks={candidateMasks}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("tab", { name: "Sum Lab" }));
|
||||
await user.click(
|
||||
screen.getByRole("checkbox", {
|
||||
name: "Use 2 board cells and candidates",
|
||||
}),
|
||||
);
|
||||
|
||||
const positions = screen.getByRole("list");
|
||||
expect(within(positions).getByText("r1c1: 1 2")).toBeInTheDocument();
|
||||
expect(within(positions).getByText("r1c2: 8 9")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "3 + 7; eliminate" }),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("resets digit bounds when the puzzle size changes", async () => {
|
||||
const user = userEvent.setup();
|
||||
const { rerender } = render(
|
||||
<HelpersWorkspace
|
||||
key={9}
|
||||
size={9}
|
||||
puzzle={puzzle}
|
||||
values={puzzle.givens}
|
||||
selectedCells={[]}
|
||||
candidateMasks={Array<number>(81).fill(0)}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("tab", { name: "Sum Lab" }));
|
||||
expect(
|
||||
screen.getByRole("spinbutton", { name: "Maximum digit" }),
|
||||
).toHaveValue(9);
|
||||
|
||||
const smallerPuzzle = normalizePuzzle(createEmptyPuzzle(4));
|
||||
rerender(
|
||||
<HelpersWorkspace
|
||||
key={4}
|
||||
size={4}
|
||||
puzzle={smallerPuzzle}
|
||||
values={smallerPuzzle.givens}
|
||||
selectedCells={[]}
|
||||
candidateMasks={Array<number>(16).fill(0)}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("tab", { name: "Sum Lab" }));
|
||||
expect(
|
||||
screen.getByRole("spinbutton", { name: "Maximum digit" }),
|
||||
).toHaveValue(4);
|
||||
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user