-
Notifications
You must be signed in to change notification settings - Fork 78
[Testing] Test layout in RelatedArtist + Gene test fix #409
Conversation
} | ||
}> | ||
<ImageView | ||
imageURL="" | ||
style={ | ||
Object { | ||
"height": 105, |
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 was happening because the layout would rely on Dimensions
, which would assume iPhone dimensions if window
returned nothing.
Object { | ||
"margin": 5, | ||
"paddingBottom": 20, | ||
"width": 242, |
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.
Now we have a calculated value for width based on the mocked nativeEvent
width.
d7ce60f
to
5548615
Compare
tree.props.onLayout(mockNativeEvent) | ||
|
||
// re-render | ||
tree = component.toJSON() |
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 dance is admittedly a bit cumbersome but could be wrapped?
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.
I took a lot of inspiration from this: https://facebook.github.io/jest/docs/tutorial-react.html#snapshot-testing
|
||
jest.mock('../../opaque_image_view.js', () => 'ImageView') | ||
|
||
it('lays out correctly', () => { |
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.
so we could make a few of these, for iPhone and iPad, say?
const mockNativeEvent = { | ||
nativeEvent: { | ||
layout: { | ||
width: 768, |
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.
and then change the associated widths here - and get different dom outputs
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.
Yes. The problem with this approach though is that the parent components can't propagate layout down to the children, so the higher-level snapshots will be sort of inaccurate. i.e. in this example, the Gene's About section snapshot has a RelatedArtists
component with a width of 1.
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.
So this is great for testing layout logic in the component itself but not in anything it instantiates. It would be lovely to have some sort of global LayoutEvent
type thing, so I'll look into that next.
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.
ohhh interesting. Thanks for explaining!
} | ||
|
||
let component = renderer.create(<RelatedArtists artists={artists}/>) | ||
let tree = component.toJSON() |
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.
so you have to json-ify the component, trigger onlayout, and then jsonify again? e.g. skipping L29 wouldn't work? :o
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.
Yeah... that's the annoying thing. I am using the approach here for manually triggering a callback.
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 could be wrapped in a helper method though. Something like runOnLayout(component)
.
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.
Agreed, the toJSON and tree var are a little confusing. I'd suggest having that helper take the dimensions and do the mocking in there as well.
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.
yeah, this all looks 👍
Great stuff! |
Maybe we can mock |
Shouldn't need to do mocking, as an event is just a normal javascript object - you can pass in whatever you want, here's a test where I pass in a Ah yeah- that's exactly what you did |
Aye, looks a tad cumbersome - but that's what they're doing - seems like the right way to do it to me @sarahscott 💯 Want to look into a helper method in this PR or anohter? |
I think I can timebox myself for the wrapper method in this PR - it would be a nice precedent to set. The reason I would consider mocking is so that a parent component like the I think if we make the assumption that parent components are only testing logic and fonts and maybe their own layouts, and that the children in their snapshots will be layout-less, the approach in this pr is fine. It would be nice if the snapshots were more accurate though. |
@sarahscott did you look at this? |
All set for review ☑️ |
@sarahscott Awesome, loving that test helper 👌 💯 Just a question about the location on disk, though. I’m still getting used to the “tests next to the lib files” convention of Jest, is |
I was looking at how metaphysics organizes smaller helper functions and modeled the I'll look into conventions within the community today. I was thinking the |
I feel things like these should probably go in the I looked through the Jest source code, and couldn't find any examples of using helper functions in there tests. So I couldn't get anything useful from there. |
@@ -0,0 +1,19 @@ | |||
import renderer from 'react-test-renderer' | |||
|
|||
export const setupWithLayout = (component, layout) => { |
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 should probably be more descriptive, and ideally be typed - I wouldn't be able to know from the name what objects to put in, perhaps something like?
/** Renders a React Component after applying a nativeEvent to an onLayout function passed in to props */
export const jsonAfterApplyingNativeLayoutDimentions = (component: any, layout: { width?: number, height?:number } ) => {
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.
I agree with adding the comments but the method name is too verbose 😉 !
But what if a component (instead of a container) needs those methods? Would we traverse from the |
I know I'm going to need the exact same method for testing components. If we really don't want a |
@@ -1,6 +1,7 @@ | |||
import renderer from 'react-test-renderer' | |||
|
|||
export const setupWithLayout = (component, layout) => { | |||
/** Renders a React Component with specified layout using onLayout callback */ | |||
export const renderWithLayout = (component: any, layout: { width?: number, height?:number }) => { |
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.
Inconsistent spacing in layout type info.
@orta bump |
Alright - yeah, that makes sense, those two are both siblings on the same hierarchy, so IMO it should probably go in |
I think using a |
Personally, I'm not sold, but if you're sure 👍 - we do need to put tests on the files in there anyway But you shouldn't move the |
I see - @alloy do you have an opinion on the name for this shared directory of testing utilities? Is |
ah nice one 👍 My point is to not make a generic |
@sarahscott I agree with @orta 👍 |
👍 |
Jest doesn't automatically call
onLayout
, so this test started failing after I updated Related Artists with a more responsive approach.I put together a proof-of-concept test for injecting
width
intoonLayout
in theRelatedArtist
component. The nice thing about this approach is we can specify any dimensions we want in the mockednativeEvent
and can make them correspond to actual expected values for iPhone and iPad.