From a90afaa5b5ce826bf9a8c3256de543ffbff6abe6 Mon Sep 17 00:00:00 2001 From: Lorenz Rosenthal Date: Sat, 8 Jan 2022 16:29:49 +0100 Subject: [PATCH 1/4] test: add test for finding manually managed components --- .../src/__tests__/RTTR.methods.test.tsx | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/test-renderer/src/__tests__/RTTR.methods.test.tsx b/packages/test-renderer/src/__tests__/RTTR.methods.test.tsx index 751af53a41..58f25013a2 100644 --- a/packages/test-renderer/src/__tests__/RTTR.methods.test.tsx +++ b/packages/test-renderer/src/__tests__/RTTR.methods.test.tsx @@ -1,8 +1,12 @@ +import { BoxHelper, Object3D } from 'three' + jest.mock('scheduler', () => require('scheduler/unstable_mock')) import * as React from 'react' import ReactThreeTestRenderer from '../index' +import { useThree } from '@react-three/fiber/src' +import { useRef } from 'react' describe('ReactThreeTestRenderer instance methods', () => { const ExampleComponent = () => { @@ -20,6 +24,28 @@ describe('ReactThreeTestRenderer instance methods', () => { ) } + const MANUALLY_MOUNTED_COMPONENT_NAME = 'not-mounted-by-r3f' + + const WithManuallyManagedComponent = () => { + const { scene } = useThree((three) => three) + const ref = useRef() + + React.useEffect(() => { + if (!ref.current) return + const manuallyManagedComponent = new BoxHelper(ref.current) + manuallyManagedComponent.name = MANUALLY_MOUNTED_COMPONENT_NAME + manuallyManagedComponent.visible = false + scene.add(manuallyManagedComponent) + }, []) + + return ( + + + + + ) + } + it('should pass the parent', async () => { const { scene } = await ReactThreeTestRenderer.create() @@ -98,4 +124,14 @@ describe('ReactThreeTestRenderer instance methods', () => { expect(() => scene.findByProps({ color: 0x0000ff })).toThrow() }) + + it('should also find three components which are not mounted via r3f and not throw', async () => { + const { scene } = await ReactThreeTestRenderer.create() + expect(() => scene.findByProps({ name: MANUALLY_MOUNTED_COMPONENT_NAME })).not.toThrow() + expect(() => scene.findByProps({ name: MANUALLY_MOUNTED_COMPONENT_NAME })).not.toThrow( + "Cannot read properties of undefined (reading 'memoizedProps')", + ) + const instance = scene.findByProps({ name: MANUALLY_MOUNTED_COMPONENT_NAME }).instance + expect(instance).toBeDefined() + }) }) From 90f834dd20c2ead00828cb05c6526409c74d52b3 Mon Sep 17 00:00:00 2001 From: Lorenz Rosenthal Date: Sat, 8 Jan 2022 16:31:00 +0100 Subject: [PATCH 2/4] fix: react three test renderer working also with manually managed components that are not mounted via r3f --- packages/test-renderer/src/createTestInstance.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/test-renderer/src/createTestInstance.ts b/packages/test-renderer/src/createTestInstance.ts index 28bc90d6ec..69d89f786d 100644 --- a/packages/test-renderer/src/createTestInstance.ts +++ b/packages/test-renderer/src/createTestInstance.ts @@ -12,7 +12,7 @@ export class ReactThreeTestInstance { } public get instance(): Object3D { - return (this._fiber as unknown) as TInstance + return this._fiber as unknown as TInstance } public get type(): string { @@ -20,7 +20,7 @@ export class ReactThreeTestInstance { } public get props(): Obj { - return this._fiber.__r3f.memoizedProps + return this._fiber.__r3f?.memoizedProps ?? this._fiber } public get parent(): ReactThreeTestInstance | null { @@ -50,7 +50,7 @@ export class ReactThreeTestInstance { */ return [ ...(fiber.children || []).map((fib) => wrapFiber(fib as MockInstance)), - ...fiber.__r3f.objects.map((fib) => wrapFiber(fib as MockInstance)), + ...(fiber.__r3f?.objects ?? []).map((fib) => wrapFiber(fib as MockInstance)), ] } else { return (fiber.children || []).map((fib) => wrapFiber(fib as MockInstance)) From fc5f349f95ae17bcd050b6d7b3fecf5175d442c0 Mon Sep 17 00:00:00 2001 From: Lorenz Rosenthal Date: Sat, 8 Jan 2022 17:10:41 +0100 Subject: [PATCH 3/4] test: get parent of manually managed three component without throwing --- packages/test-renderer/src/__tests__/RTTR.methods.test.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/test-renderer/src/__tests__/RTTR.methods.test.tsx b/packages/test-renderer/src/__tests__/RTTR.methods.test.tsx index 58f25013a2..69634e9868 100644 --- a/packages/test-renderer/src/__tests__/RTTR.methods.test.tsx +++ b/packages/test-renderer/src/__tests__/RTTR.methods.test.tsx @@ -134,4 +134,11 @@ describe('ReactThreeTestRenderer instance methods', () => { const instance = scene.findByProps({ name: MANUALLY_MOUNTED_COMPONENT_NAME }).instance expect(instance).toBeDefined() }) + + it('should find the parent of a three component that is mounted not via r3f', async () => { + const { scene } = await ReactThreeTestRenderer.create() + const testInstance = scene.findByProps({ name: MANUALLY_MOUNTED_COMPONENT_NAME }) + expect(() => testInstance.parent).not.toThrow() + expect(() => testInstance.parent).not.toThrow("Cannot read properties of undefined (reading 'parent')") + }) }) From 4e4eebbe33646711a32b084cc34db8bea04ab29b Mon Sep 17 00:00:00 2001 From: Lorenz Rosenthal Date: Sat, 8 Jan 2022 17:14:06 +0100 Subject: [PATCH 4/4] fix: getting a parent of manually managed three component threw an error now it returns the standard three parent as a fallback --- packages/test-renderer/src/createTestInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/test-renderer/src/createTestInstance.ts b/packages/test-renderer/src/createTestInstance.ts index 69d89f786d..4bb09a6f5b 100644 --- a/packages/test-renderer/src/createTestInstance.ts +++ b/packages/test-renderer/src/createTestInstance.ts @@ -24,7 +24,7 @@ export class ReactThreeTestInstance { } public get parent(): ReactThreeTestInstance | null { - const parent = this._fiber.__r3f.parent + const parent = this._fiber.__r3f?.parent ?? this._fiber.parent if (parent !== null) { return wrapFiber(parent) }