import { describe, expect, it } from "vitest"; import { getBoundedSampleRegion, mapClientPointToPixel, validateImageDimensions, validateImageFile, } from "../../src/palette/bounds"; import type { ImageLimits } from "../../src/palette/types"; const limits: ImageLimits = { maxBytes: 1_000, maxPixels: 100, maxDimension: 20, acceptedMimeTypes: ["image/png"], }; describe("local image bounds", () => { it("rejects empty, oversized, and unsupported files", () => { expect( validateImageFile( { name: "empty.png", size: 0, type: "image/png" }, limits, ).valid, ).toBe(false); expect( validateImageFile( { name: "large.png", size: 1_001, type: "image/png" }, limits, ).valid, ).toBe(false); expect( validateImageFile( { name: "vector.svg", size: 10, type: "image/svg+xml" }, limits, ).valid, ).toBe(false); }); it("accepts a bounded raster file", () => { expect( validateImageFile( { name: "pixel.png", size: 999, type: "IMAGE/PNG" }, limits, ), ).toEqual({ valid: true, }); expect( validateImageFile({ name: "pixel.png", size: 999, type: "" }, limits) .valid, ).toBe(true); }); it("checks decoded dimensions and pixel area", () => { expect(validateImageDimensions(10, 10, limits).valid).toBe(true); expect(validateImageDimensions(21, 2, limits).valid).toBe(false); expect(validateImageDimensions(11, 10, limits).valid).toBe(false); expect(validateImageDimensions(Number.NaN, 10, limits).valid).toBe(false); }); it("maps CSS-scaled canvas coordinates to bounded image pixels", () => { const rect = { left: 100, top: 50, width: 200, height: 100 }; expect(mapClientPointToPixel(200, 100, rect, 1_000, 500)).toEqual({ x: 500, y: 250, }); expect(mapClientPointToPixel(500, -20, rect, 1_000, 500)).toEqual({ x: 999, y: 0, }); expect( mapClientPointToPixel(200, 100, { ...rect, width: 0 }, 1_000, 500), ).toBeNull(); }); it("clips sampling regions at image edges", () => { expect(getBoundedSampleRegion(0, 0, 2, 10, 8)).toEqual({ left: 0, top: 0, width: 3, height: 3, centerX: 0, centerY: 0, }); expect(getBoundedSampleRegion(Number.NaN, 0, 2, 10, 8)).toBeNull(); }); });