-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Correctly merge property matchers with the rest of the snapshot in toMatchSnapshot
.
#6528
Correctly merge property matchers with the rest of the snapshot in toMatchSnapshot
.
#6528
Conversation
I believe this fixes the issue mentioned in #6455. This is my first PR on this project, so I'll happily take any advice or guidance from the community. |
packages/jest-snapshot/src/index.js
Outdated
Object.keys(source).forEach(key => { | ||
if (isObject(source[key]) && !source[key].$$typeof) { | ||
if (!(key in target)) | ||
Object.assign(output, {[key]: source[key]}); |
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'm not sure where output
is defined? Should this not be:
Object.assign(mergedOutput, {[key]: source[key]});
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 catching that, it was late when I submitted this and I overlooked it.
packages/jest-snapshot/src/index.js
Outdated
if (!(key in target)) | ||
Object.assign(output, {[key]: source[key]}); | ||
else | ||
output[key] = deepMerge(target[key], source[key]); |
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.
Same as above
packages/jest-snapshot/src/index.js
Outdated
else | ||
output[key] = deepMerge(target[key], source[key]); | ||
} else { | ||
Object.assign(output, {[key]: source[key]}); |
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.
Same as above
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.
It might make sense to move the deepMerge
function out of src/index.js
and into src/utils
and then add some tests for the logic in: https://github.com/facebook/jest/blob/master/packages/jest-snapshot/src/__tests__/utils.test.js
EDIT: It might be useful to add a new integration test for this too: https://github.com/facebook/jest/blob/master/e2e/__tests__/to_match_snapshot.test.js#L225
@SimenB @thymikee @rickhanlonii do we already have a deep merge function defined anywhere else in the codebase that can be reused?
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 tackling this!
This is missing tests, both for the snapshots and the merge function itself.
Tests for snapshots can be added here: https://github.com/facebook/jest/blob/404da0f53bd9c6204823e4ce96c1b6742e7470e3/e2e/__tests__/to_match_snapshot.test.js
If you're unable to find a deep merge module which handles the edge cases, it should receive some unit tests as well.
CHANGELOG.md
Outdated
@@ -14,6 +14,7 @@ | |||
- `[expect]` `toEqual` no longer tries to compare non-enumerable symbolic properties, to be consistent with non-symbolic properties. ([#6398](https://github.com/facebook/jest/pull/6398)) | |||
- `[jest-util]` `console.timeEnd` now properly log elapsed time in milliseconds. ([#6456](https://github.com/facebook/jest/pull/6456)) | |||
- `[jest-mock]` Fix `MockNativeMethods` access in react-native `jest.mock()` ([#6505](https://github.com/facebook/jest/pull/6505)) | |||
- `[jest-snapshot]` Correctly merge property matchers with the rest of the snapshot in `toMatchSnapshot`. ([#6455](https://github.com/facebook/jest/issues/6455)) |
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 refer to this PR, not the issue
packages/jest-snapshot/src/index.js
Outdated
return (item && typeof item === 'object' && !Array.isArray(item)); | ||
} | ||
|
||
function deepMerge(target, source) { |
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'd very much prefer if we could find some deep merge on npm. If that's not possible, this should be moved to a util file and receive quite extensive unit tests 🙂
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.
That's a very good point. It doesn't make a lot of sense to clutter this file up with a general-purpose merge function. I'll take a look at this tonight.
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.
The issue with all of the deep merge libs I tried is that they don't copy the prototype so they break the asymmetric matchers -- the strategy here is the solution I was going to go with as well
Nope, we only have shallow merge (and that uses |
correct typo variable name in deepMerge
toMatchSnapshot
.
I've moved the deepMerge function to jest-snapshot's utils, and added a simple test. Before I add more thorough tests, would anyone mind weighing in on whether I'm headed in the right direction? I also did some digging into existing deep merge solutions, but I think keeping it local is our best bet. |
I think this is a good starting point, yeah 🙂 |
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.
Looks great, I added integration tests, updated the unit test, and added a fix for #6581
Here's the new error I added:
const mergedOutput = deepMerge(target, propertyMatchers); | ||
|
||
expect(mergedOutput).toStrictEqual({data: {bar: 'bar', foo: matcher}}); | ||
expect(target).toStrictEqual({data: {bar: 'bar', foo: 'foo'}}); |
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.
@swcisel I updated your tests here, does this make sense?
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.
Looks good to me. thanks!
throw new Error( | ||
'Property matchers must be an object.\n\nTo provide a snapshot test name without property matchers, use: toMatchSnapshot("name")', | ||
); | ||
} |
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.
Added the checks here to close #6581
Codecov Report
@@ Coverage Diff @@
## master #6528 +/- ##
==========================================
+ Coverage 63.55% 63.57% +0.02%
==========================================
Files 235 235
Lines 9030 9044 +14
Branches 3 3
==========================================
+ Hits 5739 5750 +11
- Misses 3290 3293 +3
Partials 1 1
Continue to review full report at Codecov.
|
@SimenB what do you think now? |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Summary
Correct an issue where snapshots that were tested against property matchers would not be merged with the rest of the object being tested.
Closes #6581
Closes #6684
Closes #6455
Test plan
All tests pass.