Skip to content

Commit 75f9cad

Browse files
Ronald Goedekeclaude
andcommitted
test(example): make the view harness exercise the RN >= 0.86 props path
The base-view-prop tests could not fail on the pinned RN 0.85.3: `Props::Props` still filled `Props::rawProps` there, so the missing `initializeDynamicProps` call in `ViewComponentDescriptor::cloneProps` had no visible effect. Turning on `enableExclusivePropsUpdateAndroid` makes 0.85 take the same path 0.86+ takes unconditionally, which is what the tests are meant to cover. It can be dropped once the floor is >= 0.86. Also fixes the opacity assertion: it asserted on PNG alpha, which is always 255 in a screen capture. It now asserts the blue surface washes out at 10% alpha. Measured on an API 36 emulator, full `nitro.views.harness`: without the cloneProps fix: 8 failed, 2 passed with it: 10 passed The 11 ArrayBuffer/HardwareBuffer failures in `nitro.harness` are pre-existing on this emulator and identical with and without the flag. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 89e0d2e commit 75f9cad

2 files changed

Lines changed: 42 additions & 0 deletions

File tree

‎apps/example/__tests__/nitro.views.harness.tsx‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,45 @@ describe('TestView', () => {
506506
})
507507
})
508508

509+
describe('base React Native view props', () => {
510+
const DIMMED_OPACITY = 0.1
511+
const MAX_DIMMED_PIXEL_COVERAGE = 0.05
512+
513+
it('applies opacity to the native view', async () => {
514+
await render(
515+
<TestView
516+
testID="test-view-dimmed"
517+
style={{ ...INITIAL_SIZE, opacity: DIMMED_OPACITY }}
518+
isBlue={true}
519+
hasBeenCalled={false}
520+
colorScheme="dark"
521+
someCallback={callback(fn())}
522+
/>,
523+
{ timeout: RENDER_TIMEOUT }
524+
)
525+
526+
const capture = await captureView('test-view-dimmed')
527+
expectRenderedSize(capture.size, INITIAL_SIZE)
528+
expect(capture.pixelCoverage.blue).toBeLessThan(MAX_DIMMED_PIXEL_COVERAGE)
529+
})
530+
531+
it('paints solid when no opacity is given', async () => {
532+
await render(
533+
<TestView
534+
testID="test-view-solid"
535+
style={INITIAL_SIZE}
536+
isBlue={true}
537+
hasBeenCalled={false}
538+
colorScheme="dark"
539+
someCallback={callback(fn())}
540+
/>,
541+
{ timeout: RENDER_TIMEOUT }
542+
)
543+
544+
expectBlue((await captureView('test-view-solid')).pixelCoverage)
545+
})
546+
})
547+
509548
describe('multiple RecyclableTestViews', () => {
510549
it('keeps instances isolated while one is updated and recycled', async () => {
511550
const firstRef = deferred<RecyclableTestViewRef>()

‎apps/example/android/app/src/main/java/com/nitroexample/MainApplication.kt‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsProvider
1414

1515
private val stableFlagsWithNitroViewRecycling: ReactNativeFeatureFlagsProvider =
1616
object : ReactNativeFeatureFlagsProvider by ReactNativeFeatureFlagsOverrides_RNOSS_Stable_Android() {
17+
// Unconditional from RN 0.86; on by default here so the view harness covers that path.
18+
override fun enableExclusivePropsUpdateAndroid(): Boolean = true
19+
1720
override fun enablePreparedTextLayout(): Boolean = false
1821

1922
override fun enableViewRecycling(): Boolean = true

0 commit comments

Comments
 (0)