import { describe, expect, it } from "vitest"; import { samplePixels } from "../../src/palette/sample"; const pixels = ( width: number, colours: readonly (readonly [number, number, number, number])[], ) => ({ width, height: colours.length / width, data: new Uint8ClampedArray(colours.flat()), }); describe("pixel sampling", () => { it("returns the exact pixel for a zero-radius sample", () => { const result = samplePixels( pixels(2, [ [12, 34, 56, 255], [200, 100, 50, 128], ]), 1, 0, 0, "average", ); expect(result).toMatchObject({ r: 200, g: 100, b: 50, a: 128, hex: "#C8643280", pixelCount: 1, }); }); it("uses a circular neighbourhood and alpha-weighted RGB average", () => { const data = pixels(3, [ [0, 0, 0, 0], [255, 0, 0, 255], [0, 0, 0, 0], [0, 255, 0, 255], [0, 0, 255, 0], [0, 0, 0, 0], [0, 0, 0, 0], [255, 255, 255, 255], [0, 0, 0, 0], ]); const result = samplePixels(data, 1, 1, 1, "average"); expect(result).toMatchObject({ r: 170, g: 170, b: 85, a: 153, pixelCount: 5, }); }); it("calculates channel medians from visible samples", () => { const result = samplePixels( pixels(3, [ [10, 90, 200, 255], [200, 50, 10, 128], [100, 10, 90, 0], ]), 1, 0, 1, "median", ); expect(result).toMatchObject({ r: 105, g: 70, b: 105, a: 128, pixelCount: 3, }); }); it("rejects invalid coordinates and truncated buffers", () => { expect( samplePixels(pixels(1, [[1, 2, 3, 4]]), 1, 0, 0, "average"), ).toBeNull(); expect( samplePixels( { width: 2, height: 2, data: new Uint8ClampedArray(4) }, 0, 0, 0, "average", ), ).toBeNull(); }); });