Files
2026-09-01 14:34:51 +02:00

57 lines
1.5 KiB
TypeScript

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),
});
});
});