From 108583bc1a997c75deba9b5f15ee9a88aa8d4388 Mon Sep 17 00:00:00 2001 From: SnapOtter Date: Fri, 19 Jun 2026 20:14:26 +0800 Subject: [PATCH] test(fixtures): add real-fixture integrity guard (phase 1) --- .../fixtures/fixture-integrity.test.ts | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/integration/fixtures/fixture-integrity.test.ts diff --git a/tests/integration/fixtures/fixture-integrity.test.ts b/tests/integration/fixtures/fixture-integrity.test.ts new file mode 100644 index 00000000..0b0f1df8 --- /dev/null +++ b/tests/integration/fixtures/fixture-integrity.test.ts @@ -0,0 +1,44 @@ +import { execFileSync } from "node:child_process"; +import sharp from "sharp"; +import { describe, expect, it } from "vitest"; +import { fixtures } from "../../fixtures/index.js"; + +const ffprobe = process.env.FFPROBE_PATH || "ffprobe"; +const qpdf = process.env.QPDF_PATH || "qpdf"; + +describe("real fixtures decode through their real tools", () => { + // JPEG/PNG/WEBP only -- formats Sharp decodes unconditionally. HEIC/HEIF heroes + // (portrait.heic, motorcycle.heif) are exercised by the real tool routes in the + // Phase 2 depth tests, where the factory's HEIC decode path is in play. + it.each([ + fixtures.image.portrait.jpg, + fixtures.image.redEye, + fixtures.image.ocr.clean, + fixtures.image.ocr.japanese, + fixtures.image.multiFace, + ])("Sharp decodes %s with sane dimensions", async (path) => { + const meta = await sharp(path).metadata(); + expect((meta.width ?? 0) * (meta.height ?? 0)).toBeGreaterThan(64 * 64); + }); + + it.each([ + fixtures.video.hero.mp4, + fixtures.audio.speech.wav, + fixtures.audio.tagged, + ])("ffprobe reads a positive duration from %s", (path) => { + const out = execFileSync( + ffprobe, + ["-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", path], + { encoding: "utf8" }, + ); + expect(Number.parseFloat(out.trim())).toBeGreaterThan(0); + }); + + it.each([ + fixtures.document.pdfMulti, + fixtures.document.pdfScanned, + ])("qpdf reports pages for %s", (path) => { + const out = execFileSync(qpdf, ["--show-npages", path], { encoding: "utf8" }); + expect(Number.parseInt(out.trim(), 10)).toBeGreaterThan(0); + }); +});