-
Notifications
You must be signed in to change notification settings - Fork 45.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
Jest + test renderer helpers for concurrent mode #13751
Conversation
Details of bundled changes.Comparing: 36c5d69...07619df scheduler
jest-react
Generated by 🚫 dangerJS |
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.
Didn't really read the ReactSuspenseWithTestRenderer-test
case too closely, just left a thought about the matchers.
packages/jest-react/src/JestReact.js
Outdated
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import jestDiff from 'jest-diff'; |
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 import is not used.
ReactFeatureFlags.enableSuspense = true; | ||
React = require('react'); | ||
ReactTestRenderer = require('react-test-renderer'); | ||
JestReact = require('jest-react'); |
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 isn't actually used anywhere within this test.
packages/jest-react/README.md
Outdated
@@ -0,0 +1,3 @@ | |||
# `jest-react` | |||
|
|||
Jest matchers and utilities for testing React components. |
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.
We might want to add future clarity about whether this package is meant for generic React testing or only for testing with react-test-renderer
. (I assume the latter.)
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.
Is react-test-renderer not for generic React testing? :D
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.
No. People will see this and then it's meant for use with Enzyme.
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.
What's an Enzyme? :D
But yeah good point :(
packages/jest-react/src/JestReact.js
Outdated
return captureAssertion(() => expect(actualYields).toEqual(expectedYields)); | ||
} | ||
|
||
export function toClearYields(ReactTestRenderer, expectedYields) { |
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 still think it's weird that this matcher accepts the ReactTestRenderer
rather than a renderer instance.
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.
You can yield from anywhere, not just a root.
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.
It's more a matter of consistency. I expect people will accidentally use expect(renderer).toClearYields
because that's what they do everywhere else
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.
Ok I'll make it throw with a helpful message
export function toMatchRenderedOutput(renderer, expectedJSX) { | ||
const actualJSON = renderer.toJSON(); | ||
|
||
let actualJSX; |
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...interesting. I guess it allows you to avoid the inline require, but it also seems more complex and less powerful than what I originally wrote. Why the change?
For example, the following test would work with this matcher:
const ExampleComponent = ({ foo }) => foo;
const renderer = ReactTestRenderer.create(<ExampleComponent foo="bar" />);
expect(renderer).toMatchRenderedOutput('bar');
But this test wouldn't:
const ExampleComponent = ({ foo }) => <div>{foo}</div>;
const renderer = ReactTestRenderer.create(<ExampleComponent foo="bar" />);
expect(renderer).toMatchRenderedOutput(<div>bar</div>);
And so I wouldn't be able to use this matcher for the tests in ErrorBoundaryReconciliation
.
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.
The tricky bit is that ReactTestRenderer.create will run the renderer synchronously on a new root, so it will cause React to interrupt the previous root and switch to a new one. That makes it unsuitable for some tests, and it’s a non-obvious/surprising behavior when it happens.
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.
Also why wouldn't that test work? It should! I just used strings in the Suspense test because it was less to type.
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.
That's fair. I think it's reasonable
I'm concerned that what we have with this PR isn't flexible enough to be very useful with many "real" components.
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.
Oh whoops, missed your second comment.
Also why wouldn't that test work?
Lots of undefined property access errors. If you think it should be possible for it to work with more complex test cases, then I can help dig into how we'd fix it.
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 it's probably just a bug. I'll add more tests as I go.
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.
Cool. In that case, it would be great to update ErrorBoundaryReconciliation
to use the new matcher.
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 it was just a bug :) Updated ErrorBoundaryReconciliation-test
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.
Nice!
Most of our concurrent React tests use the noop renderer. But most of those tests don't test the renderer API, and could instead be written with the test renderer. We should switch to using the test renderer whenever possible, because that's what we expect product devs and library authors to do. If test renderer is sufficient for writing most React core tests, it should be sufficient for others, too. (The converse isn't true but we should aim to dogfood test renderer as much as possible.) This PR adds a new package, jest-react (thanks @cpojer). I've moved our existing Jest matchers into that package and added some new ones. I'm not expecting to figure out the final API in this PR. My goal is to land something good enough that we can start dogfooding in www. TODO: Continue migrating Suspense tests, decide on better API names
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.
Accept to unblock. Let's tweak the README to make the scope of this package clearer. Also fix the CI failure.
- Errors if user attempts to flush when log of yields is not empty - Throws if argument passed to toClearYields is not ReactTestRenderer
- toFlushAll -> toFlushAndYield - toFlushAndYieldThrough -> - toClearYields -> toHaveYielded Also added toFlushWithoutYielding
c981713
to
180f925
Compare
* Jest + test renderer helpers for concurrent mode Most of our concurrent React tests use the noop renderer. But most of those tests don't test the renderer API, and could instead be written with the test renderer. We should switch to using the test renderer whenever possible, because that's what we expect product devs and library authors to do. If test renderer is sufficient for writing most React core tests, it should be sufficient for others, too. (The converse isn't true but we should aim to dogfood test renderer as much as possible.) This PR adds a new package, jest-react (thanks @cpojer). I've moved our existing Jest matchers into that package and added some new ones. I'm not expecting to figure out the final API in this PR. My goal is to land something good enough that we can start dogfooding in www. TODO: Continue migrating Suspense tests, decide on better API names * Add additional invariants to prevent common errors - Errors if user attempts to flush when log of yields is not empty - Throws if argument passed to toClearYields is not ReactTestRenderer * Better method names - toFlushAll -> toFlushAndYield - toFlushAndYieldThrough -> - toClearYields -> toHaveYielded Also added toFlushWithoutYielding * Fix jest-react exports * Tweak README
* Jest + test renderer helpers for concurrent mode Most of our concurrent React tests use the noop renderer. But most of those tests don't test the renderer API, and could instead be written with the test renderer. We should switch to using the test renderer whenever possible, because that's what we expect product devs and library authors to do. If test renderer is sufficient for writing most React core tests, it should be sufficient for others, too. (The converse isn't true but we should aim to dogfood test renderer as much as possible.) This PR adds a new package, jest-react (thanks @cpojer). I've moved our existing Jest matchers into that package and added some new ones. I'm not expecting to figure out the final API in this PR. My goal is to land something good enough that we can start dogfooding in www. TODO: Continue migrating Suspense tests, decide on better API names * Add additional invariants to prevent common errors - Errors if user attempts to flush when log of yields is not empty - Throws if argument passed to toClearYields is not ReactTestRenderer * Better method names - toFlushAll -> toFlushAndYield - toFlushAndYieldThrough -> - toClearYields -> toHaveYielded Also added toFlushWithoutYielding * Fix jest-react exports * Tweak README
* Jest + test renderer helpers for concurrent mode Most of our concurrent React tests use the noop renderer. But most of those tests don't test the renderer API, and could instead be written with the test renderer. We should switch to using the test renderer whenever possible, because that's what we expect product devs and library authors to do. If test renderer is sufficient for writing most React core tests, it should be sufficient for others, too. (The converse isn't true but we should aim to dogfood test renderer as much as possible.) This PR adds a new package, jest-react (thanks @cpojer). I've moved our existing Jest matchers into that package and added some new ones. I'm not expecting to figure out the final API in this PR. My goal is to land something good enough that we can start dogfooding in www. TODO: Continue migrating Suspense tests, decide on better API names * Add additional invariants to prevent common errors - Errors if user attempts to flush when log of yields is not empty - Throws if argument passed to toClearYields is not ReactTestRenderer * Better method names - toFlushAll -> toFlushAndYield - toFlushAndYieldThrough -> - toClearYields -> toHaveYielded Also added toFlushWithoutYielding * Fix jest-react exports * Tweak README
* Jest + test renderer helpers for concurrent mode Most of our concurrent React tests use the noop renderer. But most of those tests don't test the renderer API, and could instead be written with the test renderer. We should switch to using the test renderer whenever possible, because that's what we expect product devs and library authors to do. If test renderer is sufficient for writing most React core tests, it should be sufficient for others, too. (The converse isn't true but we should aim to dogfood test renderer as much as possible.) This PR adds a new package, jest-react (thanks @cpojer). I've moved our existing Jest matchers into that package and added some new ones. I'm not expecting to figure out the final API in this PR. My goal is to land something good enough that we can start dogfooding in www. TODO: Continue migrating Suspense tests, decide on better API names * Add additional invariants to prevent common errors - Errors if user attempts to flush when log of yields is not empty - Throws if argument passed to toClearYields is not ReactTestRenderer * Better method names - toFlushAll -> toFlushAndYield - toFlushAndYieldThrough -> - toClearYields -> toHaveYielded Also added toFlushWithoutYielding * Fix jest-react exports * Tweak README
Most of our concurrent React tests use the noop renderer. But most of those tests don't test the renderer API, and could instead be written with the test renderer. We should switch to using the test renderer whenever possible, because that's what we expect product devs and library authors to do. If test renderer is sufficient for writing most React core tests, it should be sufficient for others, too. (The converse isn't true but we should aim to dogfood test renderer as much as possible.)
This PR adds a new package, jest-react (thanks @cpojer). I've moved our existing Jest matchers into that package and added some new ones.
I'm not expecting to figure out the final API in this PR. My goal is to land something good enough that we can start dogfooding in www.
TODO: Continue migrating Suspense tests, decide on better API names