-
-
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
Handle arrays when merging snapshots #7089
Conversation
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed. If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
@rickhanlonii mind reviewing this? |
packages/jest-snapshot/src/utils.js
Outdated
@@ -185,6 +185,15 @@ export const deepMerge = (target: any, source: any) => { | |||
if (isObject(source[key]) && !source[key].$$typeof) { | |||
if (!(key in target)) Object.assign(mergedOutput, {[key]: source[key]}); | |||
else mergedOutput[key] = deepMerge(target[key], source[key]); | |||
} else if (Array.isArray(source[key])) { | |||
// Convert arrays to objects, merge, convert back to array |
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.
Sounds expensive. Can we instead make deepMergeArray
similar to what we have in deepCyclicCopy.js
?
https://github.com/facebook/jest/blob/fb61bfffb803bad0c2ff9ab1798a6c4c31cb14fa/packages/jest-util/src/deepCyclicCopy.js#L83-L105
Hey @timtrinidad, sorry for the delay I think we can close this if we do #7128 instead cc @thymikee |
Thanks for looking at this! I think #7128 is still different - the snapshot test in this issue only includes asymmetric matchers. |
Ah, yes I understand now, thanks @timtrinidad |
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.
Agree with @thymikee that we should use deepMergeArray, and the changelog needs fixed, then this can go 👍
Sorry again for the delay
@@ -195,12 +195,57 @@ test('serialize handles \\r\\n', () => { | |||
|
|||
describe('DeepMerge', () => { | |||
it('Correctly merges objects with property matchers', () => { | |||
const target = {data: {bar: 'bar', foo: 'foo'}}; | |||
/* eslint-disable sort-keys */ | |||
// to keep keys in numerical order rather than alphabetical |
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.
Are you just adding a missing test or is this a changed behavior?
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 is adding a missing test for the case of nested matchers.
four: 'four', | ||
five: 'five', | ||
}, | ||
// Include an array element not present in the propertyMatchers |
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 added an extra array element to ensure behavior between differently-sized arrays works as expected
}; | ||
// Don't use `expect.any(string)` since that will cause a false positive | ||
// if deepMerge incorrectly keeps two as 'two' from the target | ||
const matcher = '--matcher--'; |
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 was originally const matcher = expect.any(string)
, but when messing with util.deepMerge()
I noticed if I just return the target unmodified, this returned a false positive.
packages/jest-snapshot/src/utils.js
Outdated
@@ -178,13 +178,32 @@ export const saveSnapshotFile = ( | |||
); | |||
}; | |||
|
|||
const deepMergeArray = (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.
Inspired by the deepmerge
documentation.
I looked at replacing util.deepMerge()
with that npm package since it's already used indirectly by jest-website
, but it looks like we had to implement the array merging logic manually either way.
@rickhanlonii ping :) |
Hi guys, when will this get merged, I've been waiting for months, thank you :) |
… instead of a dummy matcher
Codecov Report
@@ Coverage Diff @@
## master #7089 +/- ##
==========================================
+ Coverage 62.22% 62.22% +<.01%
==========================================
Files 266 266
Lines 10720 10731 +11
Branches 2609 2611 +2
==========================================
+ Hits 6670 6677 +7
- Misses 3463 3465 +2
- Partials 587 589 +2
Continue to review full report at Codecov.
|
packages/jest-snapshot/src/utils.ts
Outdated
@@ -185,8 +185,6 @@ const deepMergeArray = (target: Array<any>, source: Array<any>) => { | |||
source.forEach((element, index) => { | |||
if (typeof mergedOutput[index] === 'undefined') { | |||
mergedOutput[index] = element; | |||
} else if (typeof element === 'undefined') { |
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.
In adding tests to cover this line, I realized that this case really shouldn't happen (i.e. source
having an array element that's undefined)
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.
Nice work @timtrinidad!
Sorry this was left open so long, and thanks for your swift responses after Simen brought this up again :)
I have to revert this PR for now. It introduces a simple regression around strings being converted to objects, which I took the time to fix here scotthovestadt@3fd5434 but it also introduces a regression around breaking Happy to have this merged in once it doesn't break those use-cases. |
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.
Nevermind. I was in the wrong place when I did this.
@timtrinidad the revert included regression tests, so if you feel up for it I'd love a new PR landing this 🙂 |
This updated PR (#8408) checks specifically for arrays of arrays and arrays of scalars. The various tests were also split into cases for readability and DRYness. |
Is this issue fixed? If it is, in what version of jest was fixed? |
Not yet - PR #8408 is still open. |
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
#6455 fixes properties in an object being left out of the snapshot if they are not specified in
propertyMatchers
by merging the matchers and the received snapshot.However, arrays are not being merged so fields are being left out in the snapshot. For example:
Expected Snapshot:
Actual snapshot:
Test plan
The test case has been updated to include an array to be merged for testing
deepMerge
.