-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix/RTTR: find manually managed three components #1977
Changes from 2 commits
a90afaa
90f834d
fc5f349
4e4eebb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,15 +12,15 @@ export class ReactThreeTestInstance<TInstance extends Object3D = Object3D> { | |
} | ||
|
||
public get instance(): Object3D { | ||
return (this._fiber as unknown) as TInstance | ||
return this._fiber as unknown as TInstance | ||
} | ||
|
||
public get type(): string { | ||
return this._fiber.type | ||
} | ||
|
||
public get props(): Obj { | ||
return this._fiber.__r3f.memoizedProps | ||
return this._fiber.__r3f?.memoizedProps ?? this._fiber | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks good. I'd do the same for the parent getter below. External parts of the threejs scene don't have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this should be returning the node if memoized props is not there, you're confusing props with the instance properties. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What would you suggest then @joshuaellis ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well you're not passing props to the object cause it's not rendered by react. So it should either return an empty object or not be accessible in the tree which would be even harder to do. I don't mind the former. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This isn't necessarily true: expect(() => scene.find((node) => node.instance.name === MANUALLY_MOUNTED_COMPONENT_NAME)).not.toThrow() will not throw currently.
Which makes the public facing API confusing. To someone new to an existing codebase with implemented tests, they might start to ask "why can I access some props but not all of them on certain components". It should act differently for two different nodes. I'm not opposed to extending the API, we could have a new methods called public findByInstanceProperties = (properties: Obj): ReactThreeTestInstance =>
expectOne(this.findAllByInstanceProperties(properties), `with instance properties: ${JSON.stringify(properties)}`)
public findAllByInstanceProperties = (properties: Obj): ReactThreeTestInstance[] =>
findAll(this, (node: ReactThreeTestInstance) => Boolean(node.instance && matchProps(node.instance, properties))) This would create a clear mental differentiation between the two APIs whilst including the feature you're requesting (which I have no problem with adding, it's just about how we add it). What do you think? Also for more opinions cc @CodyJasonBennett There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The argument you made regarding the inconsistent API is true: returning a subset when the component is mounted via r3f and returning all props when it isn't is not good design. Your idea of adding a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Besides: I just tested your approach with the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just noticed that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer to discuss this in an issue. There's a clear separation between react and three, and I don't want design to hold back fixes if we can avoid it. |
||
} | ||
|
||
public get parent(): ReactThreeTestInstance | null { | ||
|
@@ -50,7 +50,7 @@ export class ReactThreeTestInstance<TInstance extends Object3D = Object3D> { | |
*/ | ||
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)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is important because the test below just tests a specific error but not if no error is thrown at all.