import { describe, expect, it } from "vitest"; import { createTransformPlan, normalizeCrop, orientedDimensions, } from "../../src/image/geometry"; import { DEFAULT_RECIPE } from "../../src/image/types"; describe("image transform geometry", () => { it("swaps dimensions for transpose orientations", () => { expect(orientedDimensions(400, 300, 6)).toEqual({ width: 300, height: 400, }); expect(orientedDimensions(400, 300, 3)).toEqual({ width: 400, height: 300, }); }); it("plans orientation-relative crop and quarter turn", () => { const plan = createTransformPlan( { orientedWidth: 1000, orientedHeight: 800 }, { ...DEFAULT_RECIPE, crop: { x: 0.1, y: 0.25, width: 0.5, height: 0.5 }, rotation: 90, }, ); expect(plan.crop).toEqual({ x: 100, y: 200, width: 500, height: 400 }); expect([plan.transformedWidth, plan.transformedHeight]).toEqual([400, 500]); }); it("fits without changing aspect ratio", () => { const plan = createTransformPlan( { orientedWidth: 4000, orientedHeight: 3000 }, { ...DEFAULT_RECIPE, resize: { mode: "fit", width: 1000, height: 1000 } }, ); expect([plan.outputWidth, plan.outputHeight]).toEqual([1000, 750]); }); it("center-crops fill while exact stretches", () => { const fill = createTransformPlan( { orientedWidth: 4000, orientedHeight: 3000 }, { ...DEFAULT_RECIPE, resize: { mode: "fill", width: 1000, height: 1000 }, }, ); expect(fill.resizeSource).toEqual({ x: 500, y: 0, width: 3000, height: 3000, }); expect([fill.outputWidth, fill.outputHeight]).toEqual([1000, 1000]); const exact = createTransformPlan( { orientedWidth: 4000, orientedHeight: 3000 }, { ...DEFAULT_RECIPE, resize: { mode: "exact", width: 1000, height: 1000 }, }, ); expect(exact.resizeSource).toEqual({ x: 0, y: 0, width: 4000, height: 3000, }); }); it("clamps crop rectangles and rejects unsafe output", () => { expect(normalizeCrop({ x: -1, y: 0.9, width: 5, height: 0.5 })).toEqual({ x: 0, y: 0.9, width: 1, height: 0.09999999999999998, }); expect(() => createTransformPlan( { orientedWidth: 10, orientedHeight: 10 }, { ...DEFAULT_RECIPE, resize: { mode: "exact", width: 100_000, height: 100_000 }, }, ), ).toThrow(/may not exceed/u); }); });