-
Notifications
You must be signed in to change notification settings - Fork 167
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
baa33fc
commit b7bbc8e
Showing
3 changed files
with
107 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { smartMergeArraysWithNameObjects } from '../utils/objUtils'; | ||
|
||
describe('objUtils', () => { | ||
describe('smartMergeArraysWithNameObjects', () => { | ||
/** we only use the first two params of the customization utility, so ignore the last 3 */ | ||
const smartMergeArraysWithNameObjectsWithUsedParams = (v1: any, v2: any) => | ||
smartMergeArraysWithNameObjects(v1, v2, undefined, undefined, undefined); | ||
|
||
it('should do nothing with nulls', () => { | ||
expect(smartMergeArraysWithNameObjectsWithUsedParams(null, null)).toBe(undefined); | ||
}); | ||
|
||
it('should do nothing with objects', () => { | ||
expect( | ||
smartMergeArraysWithNameObjectsWithUsedParams({ a: true }, { a: false, b: true }), | ||
).toBe(undefined); | ||
}); | ||
|
||
it('should do nothing with string[]', () => { | ||
expect(smartMergeArraysWithNameObjectsWithUsedParams(['test'], ['test2'])).toBe(undefined); | ||
}); | ||
|
||
it('should do nothing with invalid object arrays', () => { | ||
expect( | ||
smartMergeArraysWithNameObjectsWithUsedParams([{ id: 'test' }], [{ id: 'test2' }]), | ||
).toBe(undefined); | ||
}); | ||
|
||
it('should replace 2nd object if given two same correct objects arrays', () => { | ||
expect( | ||
smartMergeArraysWithNameObjectsWithUsedParams( | ||
[{ name: 'test', value: '1' }], | ||
[{ name: 'test', value: '2' }], | ||
), | ||
).toEqual([{ name: 'test', value: '2' }]); | ||
}); | ||
|
||
it('should add 2nd object if given two different correct object arrays', () => { | ||
expect( | ||
smartMergeArraysWithNameObjectsWithUsedParams( | ||
[{ name: 'test', value: '1' }], | ||
[{ name: 'test2', value: '2' }], | ||
), | ||
).toEqual([ | ||
{ name: 'test', value: '1' }, | ||
{ name: 'test2', value: '2' }, | ||
]); | ||
}); | ||
|
||
it('should and and replace as appropriate if given two correct object arrays', () => { | ||
expect( | ||
smartMergeArraysWithNameObjectsWithUsedParams( | ||
[ | ||
{ name: 'test', value: '1' }, | ||
{ name: 'test3', value: '3' }, | ||
], | ||
[ | ||
{ name: 'test', value: '1b' }, | ||
{ name: 'test2', value: '2' }, | ||
], | ||
), | ||
).toEqual([ | ||
{ name: 'test', value: '1b' }, | ||
{ name: 'test3', value: '3' }, | ||
{ name: 'test2', value: '2' }, | ||
]); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { MergeWithCustomizer } from 'lodash'; | ||
|
||
/** | ||
* When given two object arrays that have "name" keys, replace when keys are the same, or add to | ||
* the end when new key. | ||
* | ||
* Note: returns `undefined` if invalid data is provided. | ||
* | ||
* @see mergeWith -- lodash mergeWith customizer | ||
*/ | ||
export const smartMergeArraysWithNameObjects: MergeWithCustomizer = (objValue, srcValue) => { | ||
type GoodArray = { name: string }[]; | ||
const isGoodArray = (v: any): v is GoodArray => Array.isArray(v) && v.length > 0 && v[0].name; | ||
if (isGoodArray(objValue) && isGoodArray(srcValue)) { | ||
// Arrays with objects that have a .name property, sync on merge for the name | ||
return srcValue.reduce<GoodArray>((newArray, elm) => { | ||
const key = elm.name; | ||
const index = newArray.findIndex(({ name }) => name === key); | ||
if (index >= 0) { | ||
// existing value, replace | ||
newArray[index] = elm; | ||
} else { | ||
// didn't find existing name, add to end | ||
newArray.push(elm); | ||
} | ||
|
||
return newArray; | ||
}, objValue); | ||
} | ||
}; |