test: add real-photo fixture harness for detection regressions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
immortaly007andClaude Opus 5.5 committed 2026-10-15 14:45:10 +02:00
1 parent fad7deed5d
commit 0a97cb88af
3 files changed
+73

No files matched your search

+45
View File
@@ -0,0 +1,45 @@
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import jpeg from 'jpeg-js';
import { beforeAll, describe, expect, it } from 'vitest';
import { detect, otsuThreshold } from '../src/lib/detect';
import { prepareForExport, shapeSize } from '../src/lib/geometry';
import { loadOpenCV, type CV } from '../src/lib/opencv-loader';
import type { Point, RasterImage } from '../src/lib/types';
type FixtureCase = {
file: string;
threshold: number | null;
invert: boolean;
seed: Point | null;
pxPerMm: number;
expected: { widthMm: number; heightMm: number; holes: number };
toleranceMm: number;
};
const dir = fileURLToPath(new URL('./fixtures/', import.meta.url));
const cases: FixtureCase[] = JSON.parse(readFileSync(dir + 'manifest.json', 'utf8'));
function readJpeg(path: string): RasterImage {
const decoded = jpeg.decode(readFileSync(path), { useTArray: true, formatAsRGBA: true });
return { width: decoded.width, height: decoded.height, data: new Uint8ClampedArray(decoded.data) };
}
describe.skipIf(cases.length === 0)('detect on real photos', () => {
let cv: CV;
beforeAll(async () => {
({ cv } = await loadOpenCV());
});
it.each(cases)('$file', (c) => {
const image = readJpeg(dir + c.file);
const threshold = c.threshold ?? otsuThreshold(cv, image);
const shape = detect(cv, image, { threshold, invert: c.invert, seed: c.seed, marginPx: 0 });
expect(shape).not.toBeNull();
const mm = prepareForExport(shape!, c.pxPerMm)!;
const size = shapeSize(mm);
expect(Math.abs(size.width - c.expected.widthMm)).toBeLessThanOrEqual(c.toleranceMm);
expect(Math.abs(size.height - c.expected.heightMm)).toBeLessThanOrEqual(c.toleranceMm);
expect(mm.holes).toHaveLength(c.expected.holes);
});
});