import { describe, expect, it } from "vitest"; import { correctedDimensions, isValidQuad, moveQuadPoint, polygonArea, squareToQuad, } from "../../src/scan/geometry"; import { DEFAULT_QUAD, type Quad } from "../../src/scan/types"; describe("document geometry", () => { it("validates ordered convex quadrilaterals", () => { expect(isValidQuad(DEFAULT_QUAD)).toBe(true); expect(polygonArea(DEFAULT_QUAD)).toBe(1); expect( isValidQuad([ { x: 0, y: 0 }, { x: 1, y: 1 }, { x: 1, y: 0 }, { x: 0, y: 1 }, ]), ).toBe(false); }); it("rejects a dragged corner that would invert the page", () => { expect(moveQuadPoint(DEFAULT_QUAD, 0, { x: 0.9, y: 0.9 })).toEqual( DEFAULT_QUAD, ); expect(moveQuadPoint(DEFAULT_QUAD, 0, { x: 0.1, y: 0.1 })[0]).toEqual({ x: 0.1, y: 0.1, }); }); it("maps every destination corner onto the selected source corner", () => { const quad: Quad = [ { x: 0.12, y: 0.08 }, { x: 0.9, y: 0.16 }, { x: 0.82, y: 0.94 }, { x: 0.05, y: 0.8 }, ]; const map = squareToQuad(quad); expect(map(0, 0)).toEqual(quad[0]); expect(map(1, 0).x).toBeCloseTo(quad[1].x); expect(map(1, 1).y).toBeCloseTo(quad[2].y); expect(map(0, 1).x).toBeCloseTo(quad[3].x); }); it("preserves aspect and obeys the pixel budget", () => { expect(correctedDimensions(DEFAULT_QUAD, 4000, 3000, 1_000_000)).toEqual({ width: 1154, height: 866, scale: expect.closeTo(Math.sqrt(1 / 12), 8), }); }); });