-
-
Notifications
You must be signed in to change notification settings - Fork 17
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
Integrate new compat shallow renderer into Enzyme #233
Conversation
945a33a
to
ae0590f
Compare
test/shared.tsx
Outdated
if (isNewShallowRender) { | ||
allMethods.forEach(method => Test.prototype[method].resetHistory()); | ||
} else { | ||
// Calling reset here not only resets call counts, but also any behaviors | ||
// setup, such as `.returns(true)`. Calling reset here, removes our | ||
// `.returns(true)` setup on shouldComponentUpdate, causing the method to | ||
// return `undefined`. In shallow rendering, Enzyme spies on the return | ||
// value of `sCU` and chooses to invoke lifecycle methods based on its | ||
// return value. Because it returns `undefined` in this case, Enzyme skips | ||
// invoking `cDU`. | ||
// | ||
// In the default shallow renderer, Preact invokes lifecycles. In this | ||
// test, once `.reset()` is called, `.sCU` returns `undefined` and so | ||
// enzyme does not invoke `cDU`. In a real test environment, cDU would be | ||
// invoked twice. A simpler test that doesn't use spies can see this behavior. | ||
allMethods.forEach(method => Test.prototype[method].reset()); | ||
} |
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.
More context: The new shallow renderer does not invoke componentDidUpdate or componentDidMount. It relies on Enzyme to handle that. Without the change to resetHistory()
, it fails this test because when reset()
is used, shouldComponentUpdate
returns undefined
which Enzyme interprets to mean to not invoked componentDidUpdate
.
If I understand this test correctly, I think the intention is to only reset the call counts and not to clear all stub returns, hence my change to call resetHistory()
. However this breaks the test for the old shallow renderer because now it demonstrates how componentDidUpdate
will be invoked twice (once by Preact and once by Enzyme). So I left that behavior as is for now.
I have approved the other PR. Please give me a ping when this is rebased. |
…Preact10ShallowDiff
ae0590f
to
5e08b63
Compare
@robertknight PR is rebased and ready for review! |
@robertknight Updated per our comment thread about adding a compat sub package. I've moved all the compat shallow renderer related code into this sub package to better isolate and encapsulate that logic. I think in my next PR I'll add a new test example that uses the compat renderer as a way to check that we are properly packaging and exposing the compat renderer so it can be included (i.e. I haven't missed any files in the root package.json |
Thanks @andrewiggins. I'm going to take a look this weekend. |
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 had a few queries but this looks good in big picture terms. Are there other changes to come after this for the new shallow renderer?
} | ||
|
||
const appKey = 'app'; | ||
const wrapper = mount(<App key={appKey} />); |
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.
Searching the Enzyme codebase for references to getElement
and getElements
I only find it documented for the shallow rendering mode. Is this a mistake in the Enzyme docs?
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.
Huh that's true. It appears to be. It is definitely implemented in their mount wrapper (source). As well as tested (source). I think I was researching what the right behavior here is for the shallow renderer and ended up writing the test for the mount renderer to compare and figured I'd add them. But if you don't think they are useful, happy to remove these.
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 think the missing documentation is probably an oversight on Enzyme's side. Would you mind filing an issue against the Enzyme repo and referencing it here?
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.
Opend! enzymejs/enzyme#2574
Co-authored-by: Robert Knight <robertknight@gmail.com>
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.
Thanks for the review! I have no other big work items for the new shallow renderer planned at the moment, though I expect there will be incremental bug fixes as we start to use it at work.
I think with this change we have a good release candidate to get the first version of the new compat renderer out there.
} | ||
|
||
const appKey = 'app'; | ||
const wrapper = mount(<App key={appKey} />); |
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.
Huh that's true. It appears to be. It is definitely implemented in their mount wrapper (source). As well as tested (source). I think I was researching what the right behavior here is for the shallow renderer and ended up writing the test for the mount renderer to compare and figured I'd add them. But if you don't think they are useful, happy to remove these.
@@ -60,6 +80,23 @@ export default class Adapter extends EnzymeAdapter { | |||
// Work around a bug in Enzyme where `ShallowWrapper.getElements` calls | |||
// the `nodeToElement` method with undefined `this`. | |||
this.nodeToElement = this.nodeToElement.bind(this); | |||
|
|||
if (this.preactAdapterOptions.ShallowRenderer) { | |||
this.isFragment = node => node?.type === Fragment; |
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.
Yup! I wasn't entirely sure what would happen. If I enable it for all renderers, our test suite still passes. I believe it won't impact our existing renderers cuz we already remove fragments from the RST tree in rstNodeFromVNode
. I was just being more conservative here, but it appears to be safe for us to enable for all renderers. Would you like me to do that?
I agree. Let's get this landed. We don't have a convention in this repo for publishing pre-releases for early testing. What do other Preact projects do? |
I don't think we have any formal guidelines. In the past we've used -experimental, -alpha, -beta, and -rc tags when making major changes. Actually, since everything here is behind flags, maybe we don't need to do a release candidate or pre-release. We could just do a minor release? Or would you rather do some sort of pre-release first to test changes? If so, perhaps we could use the |
This PR adds a new
CompatShallowRenderer
that implements Enzyme's shallow renderer interface using the preact shallow rendering algorithm from #223. Usage of the new renderer is behind theuseCompatShallowRendering
flag.