Files
SnapOtter/tests/fixtures
SnapOtterandGitHub 991c981529 fix: make OCR portable and reliable across AMD64 and ARM64 (#519)
* fix: make OCR portable and reliable

* fix: harden OCR installation portability

* fix: pin OCR partials across downloads

* fix: make OCR execution reliably asynchronous

* fix: harden OCR portability and docs routes

* fix: preserve decoder and docs safeguards
2026-07-15 03:34:24 +08:00
..

Test Fixtures

Shared test fixtures for the SnapOtter test suite. Organized by modality in two tiers.

Two-Tier Structure

Tier 1: Tiny Synthetics (matrices/format coverage) Small, project-generated files for format-compatibility matrices and fast unit tests. Located in */formats/, */edge/, */hostile/, and security/.

Tier 2: Real Heroes (depth/fidelity testing) Larger, content-representative files for integration and fidelity tests. Located in */valid/. Each must be tracked in manifest.json with sha256 + provenance.

Modality-First Layout

tests/fixtures/
  index.ts            # Typed registry (import paths from here, not raw strings)
  manifest.json       # sha256 + bytes + provenance for all valid/ assets
  gen-manifest.mjs    # Script to re-stamp manifest hashes
  gen-synthetic-content.mjs  # Regenerate CC0 synthetics (QR, barcode, OCR, etc.)
  LICENSES.md         # Provenance audit trail
  image/
    valid/            # Base test images, portraits, OCR, barcodes, QR codes
    formats/          # 35 format samples (sample.png, sample.arw, sample.psd, ...)
    edge/             # Edge cases (1x1, blank, extreme aspect, fake transparency)
    hostile/          # Truncated, zero-byte, garbage, bomb, extension-mismatch
  video/
    valid/            # BBB heroes (mov/webm/mkv/avi), TTS speech, metadata MP4
    formats/          # tiny.{mp4,webm,avi,...}, subtitle files (srt/vtt/ass)
    hostile/          # Truncated MP4
  audio/
    valid/            # TTS speech (wav/flac/ogg/m4a/aac/opus), tagged MP3
    formats/          # tiny.{mp3,wav,flac,...}, tone-stereo, tone-gap
    hostile/          # Zero-byte WAV
  document/
    valid/            # PDFs (3-page, 6-page, encrypted, OCR-scanned)
    formats/          # tiny.{docx,xlsx,epub,html,md}
    edge/             # remote-img.html (SSRF test vector)
    hostile/          # Truncated DOCX, garbage PDF
  data/
    valid/            # tiny.{csv,json,xml,yaml,tsv,zip}
  security/           # SVG XXE test vectors (file-read, SSRF)

Using the Registry

Always import paths from tests/fixtures/index.ts rather than hard-coding paths:

import { fixtures, readFixture } from "../../fixtures/index.js";

// Direct path access
const pngPath = fixtures.image.base.png200;

// Read bytes
const buffer = readFixture(fixtures.image.base.png200);

// Format accessor (for matrix iteration)
const arwPath = fixtures.image.formats("arw");
const mp4Path = fixtures.video.tiny("mp4");

Adding a Fixture

  1. Add the file to the appropriate modality directory
  2. Add a key in tests/fixtures/index.ts pointing to it
  3. Run node tests/fixtures/gen-manifest.mjs (for valid/ files)
  4. Fill in sourceUrl and license in manifest.json (required)
  5. Update LICENSES.md with the provenance record
  6. Run the guards: pnpm vitest run tests/unit/fixtures/

Licensing Gate

Every valid/ hero must have a verified license (CC0, CC-BY, CC-BY-SA, or public-domain). Assets with UNVERIFIED-REVIEW need license review before release. The manifest guard test reports the current count.

Guard Tests

Four guard tests protect fixture integrity:

  • fixture-resolve (unit): every registry path exists and is non-empty
  • fixture-budget (unit): per-extension size caps prevent bloat
  • fixture-manifest (unit): sha256/bytes in manifest.json match disk
  • fixture-integrity (integration): real heroes decode through Sharp/ffprobe/qpdf

Generator Scripts

Three generators produce deterministic synthetics. All are idempotent and skip existing files to avoid breaking manifest hashes. See tests/README.md for details.