-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Support shallow rendering #1648
Conversation
🦋 Changeset is good to goLatest commit: 0bdff0e We got this. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
const svgNode = wrapper.find('svg') | ||
expect(svgNode).toHaveStyleRule('width', '100%') | ||
expect(svgNode).not.toHaveStyleRule('color', 'red') | ||
if (method !== 'shallow') { |
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.
If we're using a shallow render, we won't be able to find the svg element, as it will be wrapped - this is expected behavior, and inline with other CSS-in-JS libs.
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.
could we maybe split that into a separate test then? Seems like pre condition and post condition assertions are testing slightly different things here
Codecov Report
|
Thanks for preparing a PR! ❤️ I'll try to review this over the weekend. |
I've started looking into this, but unfortunately, I'm too tired right now to focus on this properly. Gonna finish the review tomorrow. |
if (isEmotionCssPropElementType(val)) { | ||
return printer({ | ||
...val, | ||
props: filterEmotionProps(val.props), | ||
type: val.props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__ | ||
}) | ||
} | ||
if (isEmotionCssPropEnzymeElement(val)) { |
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.
could you explain why things weren't working before and how they got fixed now?
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.
When the emotion element is shallow rendered, the actual element that would have the className prop is not rendered. The idea here is to swap the emotion element for an element of the underlying type (from __EMOTION_TYPE_PLEASE_DO_NOT_USE__
) with the className prop added.
packages/jest-emotion/src/index.js
Outdated
.filter(Boolean) | ||
.join(' ') | ||
return !classNames.some(className => | ||
new RegExp(className).test(renderedClassNames) |
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.
classNames
are just strings, so I think it would be better to just use a simple:
renderedClassNames.includes(className)
Or create a regexp out of all class names with smth like new RegExp(
(${classNames.join('|')}))
and run this on renderedClassNames
Or even create an areIntersecting
helper that could be used as follows:
return !areIntersecting(classNames, renderedClassNames)
toMatchShallowSnapshot: createEnzymeSnapshotMatcher(), | ||
toMatchDeepSnapshot: createEnzymeSnapshotMatcher({ mode: 'deep' }) | ||
}) | ||
const testWithMethods = (description, testCase) => |
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.
would prefer gathering all those test cases in a single object or something to call jest-in-case
only once (not that it's heavy or this here is bad, I'd only want to have this written in a similar fashion as other, existing, tests are written already). Look for an example here -
cases( |
|
||
test('enzyme mount test', () => { | ||
const expectToMatchSnapshot = (component, method, mode) => { |
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 would move handling method
into testWithMethods
, and keep that helper focused on calling appropriate mode
, that way the last test which is using this helper directly could just use method directly (on its own) and only delegate to this helper for handling mode - that alone test looks a little bit weird when it calls this method parametrized with both
Could you describe the limitations of this approach?
Don't quite see if this tested somewhere, could you point me to a test for this? |
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.
Overall looks good! I left a few comments (mostly nit-picking, so sorry for that 😅 ) and 2 questions. I think we should be able to wrap this up quickly and release it by the end of the week. Thank you for preparing this ❤️
@Andarist - thanks for the review! Let me know if there's anything else. In terms of the two questions:
then we get this:
This unfortunately appears to be a result of way shallow works. Don't quite see if this tested somewhere, could you point me to a test for this?
|
Couldn't you recognize that you have rendered a consumer and if yes then grab its first children and dive into it? I'm not too familiar with enzyme, so I'm not sure if this is possible. |
As far as I can tell, we're not serializing an enzyme element at this point, so dive won't work. Won't be able to investigate further for a few days. |
The serializer as it stands works downstream of the enzyme toJson method, meaning we can’t dive at that point. The only real option to solve this would be to have some sort of “prepare” method to call before passing the component to the expect method. |
Thank you! I've just released it and going to also work on pulling this into |
This should be an breaking change for emotion-jest. |
@chyzwar how comes? I was expecting this to be what shallow users have expected. Was easier for me to postpone this until upcoming v11 hits stable but thought this is an expected improvement |
Because all of snapshot test are now broken. emotion-jest is now producing different snapshots with the same components. |
I have to admit I kind of feel the same way. Releasing things like this one and breaking type changes as patches tends to be pretty frustrating. Is there any reason why no minor versions are being released? We end up with emotion packages that are all locked at different patch versions because of varying issues introduced by later ones and it gets hard to keep track. I'm also starting to think that some of the issues are possibly introduced by other packages being locked at lower versions and... I'm starting to avoid updating at all. |
Seems like this does indeed change existing snapshots, had thought this was going to leave the existing snapshots intact. @Andarist - should I roll back the snapshot changes and/or put them behind a flag? Let me know how I can help. |
I also noticed that some of the updated snapshots go back to using the normal emotion classes that contain hashes instead of the ones with numbers that we typically get from the jest serializer, i.e. |
This is a development-only package. I fail to see how this could be considered a breaking change as it:
Semver is hard and sometimes we just need to use common sense to decide what type of change a particular thing is, especially given that literally every change can be considered by somebody a breaking change. There is a saying that "your bug fix is my breaking change".
I'm actually not sure - was following a pattern used up to this date here when deciding about this. I think releasing a minor would be indeed more appropriate here, but I also don't see how this would improve a frustration about this? What type of semver ranges are you using in your package.json? Are you using lock files?
We really try to keep backward compatibility seriously - we never introduce runtime breaking changes intentionally. I would encourage you to skip pinning our dependencies (just use lock file) and report any issues encountered - I will gladly take a look at fixing them.
This doesn't sound right, could you prepare a repro case at which I could take a look? |
This is not how semver work. Any change to public API is breaking change. If this package does not follow semver you should explicitly warn users. Additionally, if you plan to release breaking change on path release you should at least head up people and version this like 0.10.25 where version before 1.0.0 allows for breaking changes. As someone suggested bumping minor versions would also send a stronger signals It is not the first time emotion broke our builds in path releases. |
This change was an unforeseen breaking change and it just got reverted - sorry for the inconvenience.
Sorry to hear that - it's never our intention and as mentioned before we care about semver. I wasn't expecting this to be a breaking change. That being said I believe it's impractical in general to treat such a change as a breaking one. If this is breaking then basically it would mean that NO change can ever be introduced to jest-emotion (which would change the snapshot output). I just don't see the snapshot output as a public API, it's just a string representation of a particular thing. By using snapshots for testing you are putting yourself at such risk (not from emotion, but in general) - this only IMHO showcase that a snapshot test is brittle and often not a good test. A good test would be a one not failing upon an implementation detail change - after all for your users nothing has changed, so why would your tests suddenly fail without a change in your public API (your application)? I'm not saying that snapshots test should be avoided at all costs - they are easy to write, maintain and have their place in the world BUT you should be ready to just press that Also as mentioned before - there is no such thing as "how semver work". It's a guideline, at best, and it's execution is put purely on humans, so by definition, it's error-prone. If we'd like to have ideal semver then EVERY change would bump a major version:
but that just wouldn't work well in the real-life, so we need to fallback to:
Given the nature of this change, I still believe it was not a breaking change deserving a major bump, however indeed it should have been a minor bump and not a patch. |
* Support shallow rendering * Clean-up and add comments * Fix flow errors * Use jest-in-case * Refactoring tests * Remove empty test remnant * refactor enzyme tests structure * Split enzyme+matchers test * Tweak changeset
* Revert "Fix printing names of nested shallow-rendered components (emotion-js#1665)" This reverts commit 9328cd7. * Revert "Improve support for Enzyme's shallow rendering (emotion-js#1648)" This reverts commit 858c6e7. * add changeset
What:
Fix #949, support Shallow Rendering
Why:
While using shallow rendering is generally considered unwise, there are projects that wish to convert from CSS to CSS-in-JS and that already use shallow rendering in their tests.
How:
The
jest-emotion
package was updated to dive into shallow rendered components to trigger the addition of the styles to the DOM to supporttoHaveStyleRule
. Snapshots are supported by adding classNames to the shallow-rendered object by leveraging thecss
prop.Checklist:
The snapshot support is less than ideal, but it is much improved over the existing behavior. For example, it ensures that the
map
props aren't included in the snapshot. If this PR is accepted, it is probably a good idea to still recommend against shallow rendering in general, and noting that YMMV with shallow rendered snapshots.