tests/solving.test.js
- import { describe, it, expect, vi, afterEach } from "vitest";
- import { MOCKS, STUBS } from "./api.js";
- const { init, solvers, Model } = await MOCKS.minizinc;
- const { initSolvers, solveModel } =
- await import("../src/controller/solving.js");
- describe("initSolvers", () => {
- afterEach(() => {
- vi.clearAllMocks();
- vi.restoreAllMocks();
- });
-
- it("calls init then returns the available solvers", async () => {
- init.mockResolvedValue(undefined);
- solvers.mockResolvedValue([{ id: "gecode" }]);
- expect(await initSolvers()).toEqual([{ id: "gecode" }]);
- expect(init).toHaveBeenCalledOnce();
- });
- });
- describe("solveModel", () => {
- afterEach(() => {
- vi.clearAllMocks();
- vi.restoreAllMocks();
- });
-
- it("returns the solution, statistics and status; logs info for non-OK status", async () => {
- const okResult = {
- solution: { x: 1 },
- statistics: { time: 10 },
- status: "OPTIMAL_SOLUTION",
- };
- const mockModel = STUBS.minizincModel(Model, Promise.resolve(okResult));
- const [infoSpy] = STUBS.silenceConsole("info");
- expect(await solveModel("t.mzn", "var 1..3: x;", "gecode")).toEqual(
- okResult,
- );
- expect(mockModel.addFile).toHaveBeenCalledWith("t.mzn", "var 1..3: x;");
- expect(mockModel.solve).toHaveBeenCalledWith({
- options: { solver: "gecode", statistics: true },
- });
- expect(infoSpy).not.toHaveBeenCalled();
- STUBS.minizincModel(
- Model,
- Promise.resolve({
- solution: null,
- statistics: {},
- status: "UNSATISFIABLE",
- }),
- );
- expect((await solveModel("t.mzn", "...", "gecode")).status).toBe(
- "UNSATISFIABLE",
- );
- expect(infoSpy).toHaveBeenCalledOnce();
- });
-
- it("wraps solver errors for falsy solve and rejections with or without detail", async () => {
- STUBS.silenceConsole("error");
- STUBS.minizincModel(Model, null);
- await expect(solveModel("t.mzn", "...", "gecode")).rejects.toThrow(
- "Solver 'gecode' failed to initialize.",
- );
- STUBS.minizincModel(
- Model,
- Promise.reject({ message: "bad model", code: 1, type: "ERR" }),
- );
- await expect(solveModel("t.mzn", "...", "gecode")).rejects.toThrow(
- "Solver failed (code 1, type ERR): bad model",
- );
- STUBS.minizincModel(Model, Promise.reject({ code: 2, type: "ERR" }));
- await expect(solveModel("t.mzn", "...", "gecode")).rejects.toThrow(
- "Solver failed (code 2, type ERR):",
- );
- });
- });