[FIX] Allow shallow renderer to work with new API#14329
[FIX] Allow shallow renderer to work with new API#14329mprobber wants to merge 3 commits intofacebook:masterfrom
Conversation
| this._element = element; | ||
| this._context = getMaskedContext(element.type.contextTypes, context); | ||
|
|
||
| if (element.type.contextType) { |
There was a problem hiding this comment.
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.
This is the legacy context object. It has no relation to the new context API you're implementing.
gaearon
left a comment
There was a problem hiding this comment.
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 there is no way for a component to support both thecontextType 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.yarnin the repository root.yarn test). Tip:yarn test --watch TestNameis helpful in development.yarn test-prodto 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 lincto only check changed files.yarn flow).Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html
Hi,
I really like the new
contextTypeAPI 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 ifcontextTypeis defined, will shallow render the component with the provided context, as it did for the old context API.