Skip to content
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

Merged
merged 5 commits into from
Oct 4, 2018

Conversation

acdlite
Copy link
Collaborator

@acdlite acdlite commented Sep 29, 2018

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

@sizebot
Copy link

sizebot commented Sep 29, 2018

Details of bundled changes.

Comparing: 36c5d69...07619df

scheduler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
scheduler.development.js n/a n/a 0 B 19.17 KB 0 B 5.74 KB UMD_DEV
scheduler.production.min.js n/a n/a 0 B 3.16 KB 0 B 1.53 KB UMD_PROD

jest-react

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
jest-react.development.js n/a n/a 0 B 8.86 KB 0 B 2.97 KB NODE_DEV
jest-react.production.min.js n/a n/a 0 B 3.57 KB 0 B 1.62 KB NODE_PROD
JestReact-dev.js n/a n/a 0 B 5.77 KB 0 B 1.77 KB FB_WWW_DEV
JestReact-prod.js n/a n/a 0 B 4.98 KB 0 B 1.58 KB FB_WWW_PROD

Generated by 🚫 dangerJS

Copy link
Contributor

@bvaughn bvaughn left a 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.

* LICENSE file in the root directory of this source tree.
*/

import jestDiff from 'jest-diff';
Copy link
Contributor

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');
Copy link
Contributor

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.

@@ -0,0 +1,3 @@
# `jest-react`

Jest matchers and utilities for testing React components.
Copy link
Contributor

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.)

Copy link
Collaborator Author

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

Copy link
Contributor

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.

Copy link
Collaborator Author

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 :(

return captureAssertion(() => expect(actualYields).toEqual(expectedYields));
}

export function toClearYields(ReactTestRenderer, expectedYields) {
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Copy link
Contributor

@bvaughn bvaughn Oct 3, 2018

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

Copy link
Collaborator Author

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;
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

@acdlite acdlite Oct 1, 2018

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.

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Copy link
Contributor

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.

Copy link
Collaborator Author

@acdlite acdlite Oct 3, 2018

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

Copy link
Contributor

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
@acdlite acdlite changed the title [WIP] Jest + test renderer helpers for concurrent mode Jest + test renderer helpers for concurrent mode Oct 3, 2018
Copy link
Contributor

@bvaughn bvaughn left a 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
@acdlite acdlite force-pushed the jest-react branch 4 times, most recently from c981713 to 180f925 Compare October 4, 2018 00:14
@acdlite acdlite merged commit 96bcae9 into facebook:master Oct 4, 2018
acdlite added a commit to plievone/react that referenced this pull request Oct 5, 2018
* 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
linjiajian999 pushed a commit to linjiajian999/react that referenced this pull request Oct 22, 2018
* 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
jetoneza pushed a commit to jetoneza/react that referenced this pull request Jan 23, 2019
* 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
NMinhNguyen referenced this pull request in enzymejs/react-shallow-renderer Jan 29, 2020
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants