Repository navigation
fix(⚛️): build the Jest mock's ref handle once, and test Canvas under React Native Testing Library - #529
Open
YevheniiKotyrlo wants to merge 3 commits into
Open
fix(⚛️): build the Jest mock's ref handle once, and test Canvas under React Native Testing Library#529YevheniiKotyrlo wants to merge 3 commits into
YevheniiKotyrlo wants to merge 3 commits into
Conversation
… React Native Testing Library The Jest mock's Canvas built its ref handle on every render (useImperativeHandle without dependencies), so a ref got a new handle after each re-render, and a state setter used as the ref re-rendered its owner until React stopped with "Maximum update depth exceeded". It builds the handle once, as Canvas does. Every spec under src/__tests__ goes through the e2e harness, which waits for the example app, so nothing rendered a component under Jest. jest.unit.config.js runs src/__tests__/unit with React Native's Jest preset and React Native Testing Library 14 on test-renderer, React 19's replacement for react-test-renderer; CI runs it beside the plugin's tests. The Canvas spec drives a stand-in RNWebGPU module and View's measureLayout, and the mock's spec holds its handle and its loud failures. On a device, Canvas.spec.ts checks a canvas drawn at half its layout size under a scale transform: its context is sized from the layout, and its ref handle is the same after re-renders. setup.ts's isNativeApp() replaces the specs' inline platform checks, and WebPolyfill.spec.ts covers the web polyfill's native surface.
YevheniiKotyrlo
force-pushed
the
test/component-test-tier
branch
from
October 16, 2026 15:28
2c50ea9 to
3ce24a1
Compare
YevheniiKotyrlo
marked this pull request as ready for review
October 17, 2026 05:49
This branch has not been deployed
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.
Problem
The Jest mock's
Canvas, which apps render in their own Jest tests, builds its ref handle on every render (useImperativeHandlewithout dependencies). A ref gets a new handle after each re-render, and a state setter used as the ref re-renders its owner until React stops with "Maximum update depth exceeded".Canvasitself builds its handle once since #532.Nothing catches this: every spec under
packages/webgpu/src/__tests__goes through the e2e harness (jest.config.jsgives the tree aglobalSetupthat waits for the example app), so no test renders a component under Jest.Canvas's layout size (#531) and its single handle (#532) have no device test either.#525's two fixes reached
mainthrough #531 and #532; this carries what remained of it.Solution
jest.unit.config.jsrunssrc/__tests__/unitwith React Native's Jest preset and React Native Testing Library 14, which renders ontest-renderer, React 19's replacement for the deprecatedreact-test-renderer. The e2e config skips that directory, and CI runsyarn test:unitin the build job beside the plugin's tests.Canvas.spec.ts.setup.ts'sisNativeApp()replaces the specs' inline platform checks.Tests
unit/mock.test.tsx: the mock's handle survives re-renders, a state setter as its ref settles, it answers-1andnulland throws fromgetNativeSurface(), and it keeps its own props off theViewit renders. Without the fix, the first two fail: five ref calls instead of one, and "Maximum update depth exceeded".unit/Canvas.test.tsx, with a stand-inRNWebGPUandView'smeasureLayout: the context is created at the layout size the view measures relative to itself, the ref handle survives re-renders, a state setter as the ref settles, unmount retires the context once, and a context name other thanwebgputhrows. AgainstCanvas.tsxfrom before fix(🎨): size the canvas context from the view's layout, not its transformed box #531 and fix(🎨): add contextId to the useImperativeHandle dependencies in Canvas #532, the first three fail.Canvas.spec.tson a device: the scaled canvas's context has its layout size, not its transformed box, and its handle is the same after three re-renders.WebPolyfill.spec.ts: the web polyfill's native surface reports the canvas's layout size, reads it without touching the drawing buffer and delegates its DOM methods to the canvas, and a second context at the same size leaves the drawing buffer alone.Verification
yarn lint·yarn tsc·yarn turbo run build --filter='./packages/*'· the Expo template's web build ·yarn test:plugin·yarn test:unit(9 passed) ·yarn check-dawn·yarn build:docs. CI's Android e2e step (debug build, Metro withCI=true) on an Android 15 emulator: 225 of 227 passed,main's 219 and the six new cases; the YUV cases ofExternalTextureColorSpaceandNativeBufferWrapperfail onmainon that emulator too.On devices the whole suite passes, 227 of 227: on a Galaxy S23 (Android 14), and on an iPhone 12 Pro Max (iOS 27.0.1) built and run as CI's iOS job does on a simulator (Debug build, Metro with
CI=true).mainpasses 221 of 221 on both. Not run here: the SwiftPM example's build and the semantic-release dry run, which needs the repository's token.