-
-
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
Changes from 3 commits
6534d09
4fb1c1a
079fa50
7317c0d
ac1974c
1942422
bf0534b
a22721f
1dada66
0926357
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -195,12 +195,74 @@ test('serialize handles \\r\\n', () => { | |
|
||
describe('DeepMerge', () => { | ||
it('Correctly merges objects with property matchers', () => { | ||
const target = {data: {bar: 'bar', foo: 'foo'}}; | ||
const matcher = expect.any(String); | ||
const propertyMatchers = {data: {foo: matcher}}; | ||
/* eslint-disable sort-keys */ | ||
// to keep keys in numerical order rather than alphabetical | ||
const target = { | ||
data: { | ||
one: 'one', | ||
two: 'two', | ||
three: [ | ||
{ | ||
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 commentThe 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 |
||
{ | ||
six: 'six', | ||
seven: 'seven', | ||
}, | ||
], | ||
}, | ||
}; | ||
// Don't use `expect.any(string)` since that will cause a false positive | ||
jeysal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// 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 commentThe reason will be displayed to describe this comment to others. Learn more. This was originally |
||
const propertyMatchers = { | ||
data: { | ||
two: matcher, | ||
three: [ | ||
{ | ||
four: matcher, | ||
}, | ||
], | ||
}, | ||
}; | ||
|
||
const mergedOutput = deepMerge(target, propertyMatchers); | ||
expect(mergedOutput).toStrictEqual({ | ||
data: { | ||
one: 'one', | ||
two: matcher, | ||
three: [ | ||
{ | ||
four: matcher, | ||
five: 'five', | ||
}, | ||
{ | ||
six: 'six', | ||
seven: 'seven', | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
expect(mergedOutput).toStrictEqual({data: {bar: 'bar', foo: matcher}}); | ||
expect(target).toStrictEqual({data: {bar: 'bar', foo: 'foo'}}); | ||
// Ensure original target is not modified | ||
expect(target).toStrictEqual({ | ||
data: { | ||
one: 'one', | ||
two: 'two', | ||
three: [ | ||
{ | ||
four: 'four', | ||
five: 'five', | ||
}, | ||
{ | ||
six: 'six', | ||
seven: 'seven', | ||
}, | ||
], | ||
}, | ||
}); | ||
/* eslint-enable sort-keys */ | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -178,13 +178,32 @@ export const saveSnapshotFile = ( | |
); | ||
}; | ||
|
||
const deepMergeArray = (target, source) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inspired by the I looked at replacing |
||
// Clone target | ||
const mergedOutput = target.slice(); | ||
|
||
source.forEach((element, index) => { | ||
if (typeof mergedOutput[index] === 'undefined') { | ||
mergedOutput[index] = element; | ||
} else if (typeof element === 'undefined') { | ||
mergedOutput.push(target[index]); | ||
} else { | ||
mergedOutput[index] = deepMerge(target[index], element); | ||
} | ||
}); | ||
|
||
return mergedOutput; | ||
}; | ||
|
||
export const deepMerge = (target: any, source: any) => { | ||
const mergedOutput = Object.assign({}, target); | ||
if (isObject(target) && isObject(source)) { | ||
Object.keys(source).forEach(key => { | ||
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])) { | ||
mergedOutput[key] = deepMergeArray(target[key], source[key]); | ||
} else { | ||
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.
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.