Skip to content
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

Merged
merged 12 commits into from
Aug 9, 2018

Conversation

swcisel
Copy link
Contributor

@swcisel swcisel commented Jun 23, 2018

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.

@swcisel
Copy link
Contributor Author

swcisel commented Jun 23, 2018

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.

Object.keys(source).forEach(key => {
if (isObject(source[key]) && !source[key].$$typeof) {
if (!(key in target))
Object.assign(output, {[key]: source[key]});
Copy link
Contributor

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]});

Copy link
Contributor Author

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.

if (!(key in target))
Object.assign(output, {[key]: source[key]});
else
output[key] = deepMerge(target[key], source[key]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

else
output[key] = deepMerge(target[key], source[key]);
} else {
Object.assign(output, {[key]: source[key]});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Copy link
Contributor

@mattphillips mattphillips left a 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?

Copy link
Member

@SimenB SimenB left a 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))
Copy link
Member

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

return (item && typeof item === 'object' && !Array.isArray(item));
}

function deepMerge(target, source) {
Copy link
Member

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 🙂

Copy link
Contributor Author

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.

Copy link
Member

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

@SimenB
Copy link
Member

SimenB commented Jun 23, 2018

@SimenB @thymikee @rickhanlonii do we already have a deep merge function defined anywhere else in the codebase that can be reused?

Nope, we only have shallow merge (and that uses Object.assign)

correct typo variable name in deepMerge
@swcisel swcisel changed the title deep merge property matchers in snapshot objects Correctly merge property matchers with the rest of the snapshot in toMatchSnapshot. Jun 23, 2018
@swcisel
Copy link
Contributor Author

swcisel commented Jun 24, 2018

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.

@SimenB SimenB requested a review from rickhanlonii July 11, 2018 09:45
@SimenB
Copy link
Member

SimenB commented Jul 11, 2018

I think this is a good starting point, yeah 🙂

Copy link
Member

@rickhanlonii rickhanlonii left a 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'}});
Copy link
Member

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?

Copy link
Contributor Author

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")',
);
}
Copy link
Member

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-io
Copy link

codecov-io commented Jul 12, 2018

Codecov Report

Merging #6528 into master will increase coverage by 0.02%.
The diff coverage is 73.33%.

Impacted file tree graph

@@            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
Impacted Files Coverage Δ
packages/jest-snapshot/src/utils.js 100% <100%> (ø) ⬆️
packages/jest-snapshot/src/index.js 54.05% <20%> (-1.67%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0591f22...e4fbf98. Read the comment docs.

@rickhanlonii
Copy link
Member

@SimenB what do you think now?

@github-actions
Copy link

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.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
7 participants