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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions