-
Notifications
You must be signed in to change notification settings - Fork 47k
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] Allow shallow renderer to work with new API #14329
Conversation
@@ -143,7 +143,12 @@ class ReactShallowRenderer { | |||
|
|||
this._rendering = true; | |||
this._element = element; | |||
this._context = getMaskedContext(element.type.contextTypes, context); | |||
|
|||
if (element.type.contextType) { |
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 only be enabled for class components.
this._context = getMaskedContext(element.type.contextTypes, context); | ||
|
||
if (element.type.contextType) { | ||
this._context = context; |
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 the legacy context object. It has no relation to the new context API you're implementing.
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 doesn't implement the new context API. Your test should verify that this.context
is equal to 'hello world'
(because it's the default context value). I also don't think we want to support passing second value to shallowRenderer.render
for new context because which context component subscribes to is an implementation detail. Maybe we should support rendering <Provider value={...}><Thing /></Provider>
though. Not sure.
I agree with you that the shallow renderer should use the value of the default context if no context is provided, but I'm not really sure about rendering two levels deep and not being transparent about it in the shallow renderer for a select few components. Looking at
contextType and the legacy contextTypes APIs, so it doesn't seem like it would be problematic to use the same argument to set context on a component (just an object, used to set this.context). I don't have too much context (ba-dum-tss) about implementation details though, so I'm curious if there's something I'm missing. I'll update the PR so the default context renders if none is provided.
|
Details of bundled changes.Comparing: 409066a...1f656b3 react-test-renderer
Generated by 🚫 dangerJS |
Coming here from enzymejs/enzyme#1553, via https://stackoverflow.com/questions/53711166/unable-to-set-context-in-an-enzyme-test, and that's pretty much exactly how I expected it to work. |
To @gaearon's point, using the second argument to support It seems reasonable at first because, with the plain react shallow renderer, you're only ever rendering one component at a time, so you have a lot of control over what context you pass when you render a component; you know not to pass legacy context if the component you're testing is using But Enzyme has the concept of So, if this change were to be released, and no changes in Enzyme were made, if you were to Now, of course, Enzyme could be updated to inspect the component being |
The only thing coming to mind to that would avoid overloading the second argument, and supporting I'd think that a follow-up change should be made to enzyme regardless if this PR gets merged. Currently, if you shallow render a component with Let me know if you come up with an API that doesn't overload the second argument to render that's not super clunky. I'd be happy to implement it. |
Oh my. This is the first time I'm hearing and reading about this API 😳 |
|
The confusing thing to me is that the updates in the parent component wouldn't "reflect" in that "dived" version for |
@gaearon I'm pretty sure you're correct about this. If you change state/props in the parent, you'd need to re-dive to see the changes reflected in the "dived" version. This, however, probably isn't super surprising to users given the immutable nature of non-root enzyme wrappers. However, it does present itself if you ever want to test component lifecycle methods in the dived child by manipulating the props/state of the parent. |
That's also the case for both shallow and mount for any derived wrapper - ie, any |
Thanks for explaining! |
Guys, is there any workaround to pass context to component which uses new context API? |
@mprobber @gaearon Any chance we might move forward with this, or decide on an alternative API in the near future? Having shallow rendering support the new If we are thinking about alternatives, would passing a map of Provider/value pairs when creating an instance of
@DaveVoyles If the context your component uses happens to be an object, you can use the legacy API to test it for now by setting an appropriate value for |
Wanted to throw my hat into the ring too, having a solution here would greatly help unblocking our upgrade path to remove old-style, legacy context. Right now we code-modded most of it away and the code is functioning, but tests are an absolute mess. Can explore the workaround detailed above, but that feels a bit worse. |
I created module for workaround https://www.npmjs.com/package/shallow-with-context. The module works well in our projects. |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution. |
bump |
The shallow renderer has been extracted so please port this change to https://github.com/NMinhNguyen/react-shallow-renderer if you'd like. Thank you! |
Before submitting a pull request, please make sure the following is done:
master
.yarn
in the repository root.yarn test
). Tip:yarn test --watch TestName
is helpful in development.yarn test-prod
to test in the production environment. It supports the same options asyarn test
.yarn debug-test --watch TestName
, openchrome://inspect
, and press "Inspect".yarn prettier
).yarn lint
). Tip:yarn linc
to only check changed files.yarn flow
).Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html
Hi,
I really like the new
contextType
API in 16.6, but the shallow renderer doesn't seem to provide support for it. This pull request allows you to pass in an object forcontext
, and ifcontextType
is defined, will shallow render the component with the provided context, as it did for the old context API.