test: add TS API contract test suite scaffold#1203
Closed
msluszniak wants to merge 5 commits into
Closed
Conversation
Adds Jest-based scaffold and two representative tests that catch drift across the package's public API surface. The tests intentionally do not exercise the JSI runtime — they discover modules/hooks via the index exports and assert shared structural contracts. Refs #1018
Two more layers on the API contract scaffold:
- hookContracts.test.ts: compile-time assertion that every public
useXxx hook returns at least { error, isReady, isGenerating,
downloadProgress }. Drift in any hook surfaces as a tsc error
naming the offending hook.
- modelUrls.test.ts: walks every accessor in the model registry,
collects every string field that looks like a URL, and asserts
each one is a non-empty https URL pointing at the
software-mansion HuggingFace org.
Refs #1018, #1202.
Three more API consistency layers: - errorCodes.test.ts: walks RnExecutorchErrorCode and asserts every entry is a unique non-negative integer with a working reverse lookup, and that constructing RnExecutorchError(code) produces a non-empty message. - ttsVoices.test.ts: walks every Kokoro voice constant and asserts the voice variable-name region (e.g. KOKORO_FRENCH_*) matches the phonemizerConfig.lang, that the voiceSource URL points at the voices/ directory, and that every phonemizer URL lives under the matching /phonemizer/<lang>/ tree. Catches copy-paste bugs across voice configs. - apiSurface.test.ts: snapshots the sorted list of public exports from src/index.ts. Accidental adds/removals show up in the diff; intentional changes need --updateSnapshot. Refs #1018, #1202.
…ests Three more API consistency layers: - hookPropsContract.test.ts: compile-time check that every *Props type exposes preventLoad?: boolean, and that every public useXxx hook takes a single object argument. Surfaces useTextToSpeech as the lone two-arg outlier. - registryHookCompatibility.test.ts: compile-time assertion that every category sample from the model registry is assignable to the matching hook's model prop type. Catches drift between the registry's static return shape and the hook prop shapes. - modulePrototype.test.ts: walks each concrete module's prototype chain (using property descriptors so accessor getters aren't invoked) and asserts at least one public method is reachable and delete() is callable. Also snapshots BaseModule's intrinsic surface so silent additions/renames there fail loudly. Surfaces TokenizerModule's missing delete() as a documented opt-out in SKIPS_DELETE (tracked in #1202). Refs #1018, #1202.
- moduleConstruction.test.ts: mocks the ResourceFetcher adapter and constructs every from*-factory-bearing module against a sample config from the registry. Asserts the awaited result is the expected instance and that delete() is callable on the stubbed native module. - moduleHookSignatureAlignment.test.ts: compile-time alignment check between non-generic module prototype methods and the matching hook return field. Catches drift between e.g. LLMModule.prototype.generate and useLLM().generate. Surfaces the TextToImageModule.forward → useTextToImage().generate rename via a dedicated row. - setup-globals.ts: the stubbed loadXxx now resolves to a native module shape with unload() and generateFromFrame() so module delete() and VisionModule's worklet getter work in tests. - .github/workflows/ci.yml: adds a `test` job that runs typecheck:tests and `jest --ci` so the contract suite gates PRs. Refs #1018, #1202.
Member
Author
|
This PR will be updated after issues from #1202 |
12 tasks
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds a Jest-based scaffold and twelve API contract test suites under packages/react-native-executorch/tests/api/, with
typecheck:tests+testscripts wired into a new CI job. Catches drift across the public TypeScript surface (modules, hooks, types, registry, error codes, voices, URLs) without exercising native code.Introduces a breaking change?
Type of change
Tested on
Testing instructions
yarn workspace react-native-executorch typecheck:tests yarn workspace react-native-executorch testExpected: 12 test suites, 971 passed, 9 skipped (documented in #1202), 1 snapshot. The new
testjob in.github/workflows/ci.ymlruns the same on PRs.Screenshots
N/A — no UI changes.
Related issues
Closes #1018. Findings catalogued in #1202.
Checklist
Additional notes
Tests do not touch native code: `global.loadXxx` and `ResourceFetcher` are stubbed at the JS layer. Module classes are discovered via `Object.entries(RNE)` and the hook return contract is enforced via `satisfies` (tsc-checked).
Inconsistencies the tests surface are encoded as explicit exception sets (`SKIPS_BASE_MODULE`, `SKIPS_STATIC_FACTORY`, `SKIPS_DELETE`, `HOOK_NAME_EXCEPTIONS`, `PARAMETERIZED_ACCESSORS`) so the suite stays green on today's codebase. Each exception entry maps to a bullet in #1202 and can be removed as the underlying API is normalized.