Skip to content

Migrate SPECS.md to an executable test suite #175

@thomasttvo

Description

@thomasttvo

Problem

SPECS.md is the authoritative consumer-visible behavior contract for ReactNativeZoomableView and StaticPin. Today it is enforced only by human/agent review against src/, which means:

  • Drift between spec and code is caught only when someone notices
  • Contract breaks ship when a reviewer misses them
  • New contributors have no fast feedback loop ("did I break the contract?")
  • Refactors require manual re-verification of every documented behavior

The spec already enumerates the contract in a structured way (props, ref methods, callback fire order/count, gesture classification, zoom/pan math, coordinate spaces). That structure maps naturally onto executable tests.

Proposal

Migrate the behavior described in SPECS.md into a test suite that runs in CI on every PR. Each section of SPECS.md becomes one or more tests; failing tests = contract break OR spec drift, surfaced automatically.

Suggested layering

  1. Unit tests — pure helpers (applyContainResizeMode, getImageOriginOnTransformSubject, viewportPositionToImagePosition, sensitivity math, double-tap zoom-step ceiling derivation). No RN runtime needed; fast.
  2. Component tests (RN Testing Library + jest) — props, ref methods, callback fire order/count, the legacy movementSensibility warning + forwarding, zoomEnabled: false cancel-and-snap behavior. Mock gesture-handler/reanimated where needed.
  3. Gesture / interaction tests — pinch classification, pan resistance, double-tap (delay window, doubleTapZoomToCenter), tap handling. May need react-native-gesture-handler/jest-utils or a lightweight gesture simulator.
  4. (Optional) E2E on the example app — Maestro/Detox for the static-pin flows and worklet callback contracts that are hardest to fake in unit tests.

Migration approach

  • Walk SPECS.md section by section; for each documented behavior, write the test and link the test back to the spec section in a comment (e.g. // SPECS.md §7 Zoom behavior — double-tap).
  • Keep SPECS.md as the human-readable contract; tests are the executable mirror. When they diverge, that's the bug — fix one or the other.
  • Consider a CI check that flags PRs touching src/ without a corresponding test update, similar to the current CLAUDE.md review guidance.

Out of scope (for this issue)

  • Rewriting any documented behavior — migration is a transcription, not a redesign.
  • Internal implementation details that produce identical observable output (listener ordering, private SharedValue names) — SPECS.md excludes these and the test suite should too.

Acceptance

  • Test suite runs in CI on every PR
  • Each SPECS.md section has at least one corresponding test
  • Failing tests block merge
  • README/CONTRIBUTING updated to describe how spec ↔ tests relate

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions