Files
SnapOtter/tests/fixtures
SnapOtter b1afcfdf3c test: migrate 207 test files to typed fixture registry (phase 5)
Codemod rewrites all five ad-hoc fixture-path styles to import from the
typed registry (tests/fixtures/index.ts):
- join(__dirname, "..", "fixtures", ...) inline patterns (100 files)
- const FIXTURES = join(__dirname, ...) + join(FIXTURES, ...) (92 files)
- process.cwd()-based paths (10 files)
- path.resolve(__dirname, ...) patterns (5 files)

Registry extended with 8 new keys (portraitJpg, portraitHeic,
motorcycle, svgLogo, barcodeAvif, qrAvif, crossFormatChat,
multipageTiff) and directory accessors (fixtureDir, fixtureRoot).

Dynamic directory scanners (format-matrix-generated,
format-matrix-multimodal, hostile-inputs) preserved via fixtureDir
imports. No fixtures swapped, bytes identical.

Parity gate: dropped 0, net-new 388.
2026-06-20 04:20:17 +08:00
..

Test Fixtures

Shared test fixtures for the SnapOtter test suite. Organized 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 media/, documents/, data/, formats/, and root-level test-* files.

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

Layout (Modality-First, Phase 6 Target)

tests/fixtures/
  index.ts            # Typed registry (import paths from here, not raw strings)
  manifest.json       # sha256 + bytes + provenance for content/ heroes
  gen-manifest.mjs    # Script to re-stamp manifest hashes
  LICENSES.md         # Provenance audit trail
  content/            # Tier-2 real heroes
  formats/            # Tier-1 format samples (35 formats incl. RAW)
  media/              # Tier-1 tiny audio/video samples
  documents/          # Tier-1 tiny document samples
  data/               # Tier-1 tiny data samples (csv, json, xml, etc.)
  hostile/            # Malformed/bomb/polyglot files for rejection tests
  security/           # XXE, SSRF test vectors
  image/              # (Phase 6) modality-first target dir
  video/              # (Phase 6) modality-first target dir
  audio/              # (Phase 6) modality-first target dir
  document/           # (Phase 6) modality-first target dir
  data/               # (Phase 6) modality-first target dir

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 directory
  2. Add a key in tests/fixtures/index.ts pointing to it
  3. Run node tests/fixtures/gen-manifest.mjs if the file is in content/
  4. Fill in sourceUrl and license in manifest.json (required for Phase 2+)
  5. Update LICENSES.md with the provenance record
  6. Run the guards: pnpm vitest run tests/unit/fixtures/ tests/integration/fixtures/

Licensing Gate

Phase 1 allows UNVERIFIED provenance. Phase 2 enforces that every content/ hero has a verified license (CC0, CC-BY, CC-BY-SA, or public-domain). See LICENSES.md for the current audit status.

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