-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Lodash: Refactor away from
_.set()
in core-data (#48784)
* Lodash: Refactor away from _.set() in core-data * Add graceful support and more tests
- Loading branch information
Showing
5 changed files
with
119 additions
and
5 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
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
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,37 @@ | ||
/** | ||
* Sets the value at path of object. | ||
* If a portion of path doesn’t exist, it’s created. | ||
* Arrays are created for missing index properties while objects are created | ||
* for all other missing properties. | ||
* | ||
* This function intentionally mutates the input object. | ||
* | ||
* Inspired by _.set(). | ||
* | ||
* @see https://lodash.com/docs/4.17.15#set | ||
* | ||
* @param {Object} object Object to modify | ||
* @param {Array} path Path of the property to set. | ||
* @param {*} value Value to set. | ||
*/ | ||
export default function setNestedValue( object, path, value ) { | ||
if ( ! object || typeof object !== 'object' ) { | ||
return object; | ||
} | ||
|
||
path.reduce( ( acc, key, idx ) => { | ||
if ( acc[ key ] === undefined ) { | ||
if ( Number.isInteger( path[ idx + 1 ] ) ) { | ||
acc[ key ] = []; | ||
} else { | ||
acc[ key ] = {}; | ||
} | ||
} | ||
if ( idx === path.length - 1 ) { | ||
acc[ key ] = value; | ||
} | ||
return acc[ key ]; | ||
}, object ); | ||
|
||
return object; | ||
} |
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,72 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import setNestedValue from '../set-nested-value'; | ||
|
||
describe( 'setNestedValue', () => { | ||
it( 'should return the same object unmodified if path is an empty array', () => { | ||
const input = { x: 'y' }; | ||
const result = setNestedValue( input, [], 123 ); | ||
|
||
expect( result ).toBe( input ); | ||
expect( result ).toEqual( { x: 'y' } ); | ||
} ); | ||
|
||
it( 'should set values at deep level', () => { | ||
const input = { x: { y: { z: 123 } } }; | ||
const result = setNestedValue( input, [ 'x', 'y', 'z' ], 456 ); | ||
|
||
expect( result ).toEqual( { x: { y: { z: 456 } } } ); | ||
} ); | ||
|
||
it( 'should create nested objects if necessary', () => { | ||
const result = setNestedValue( {}, [ 'x', 'y', 'z' ], 123 ); | ||
|
||
expect( result ).toEqual( { x: { y: { z: 123 } } } ); | ||
} ); | ||
|
||
it( 'should create nested arrays when keys are numeric', () => { | ||
const result = setNestedValue( {}, [ 'x', 0, 'z' ], 123 ); | ||
|
||
expect( result ).toEqual( { x: [ { z: 123 } ] } ); | ||
} ); | ||
|
||
it( 'should also work with arrays', () => { | ||
const result = setNestedValue( [], [ 0, 1, 2 ], 123 ); | ||
|
||
expect( result ).toEqual( [ [ , [ , , 123 ] ] ] ); | ||
} ); | ||
|
||
it( 'should keep remaining properties unaffected', () => { | ||
const input = { x: { y: { z: 123, z1: 'z1' }, y1: 'y1' }, x1: 'x1' }; | ||
const result = setNestedValue( input, [ 'x', 'y', 'z' ], 456 ); | ||
|
||
expect( result ).toEqual( { | ||
x: { y: { z: 456, z1: 'z1' }, y1: 'y1' }, | ||
x1: 'x1', | ||
} ); | ||
} ); | ||
|
||
it( 'should intentionally mutate the original object', () => { | ||
const input = { x: 'y' }; | ||
const result = setNestedValue( input, [ 'x' ], 'z' ); | ||
|
||
expect( result ).toBe( input ); | ||
expect( result ).toEqual( { x: 'z' } ); | ||
} ); | ||
|
||
it.each( [ | ||
undefined, | ||
null, | ||
0, | ||
5, | ||
NaN, | ||
Infinity, | ||
'test', | ||
false, | ||
true, | ||
Symbol( 'foo' ), | ||
] )( 'should return the original input if it is %s', ( value ) => { | ||
expect( setNestedValue( value, [ 'x' ], 123 ) ).toBe( value ); | ||
} ); | ||
} ); |
c9b83b5
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.
Flaky tests detected in c9b83b5.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.
🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4405117455
📝 Reported issues:
/test/e2e/specs/site-editor/title.spec.js
/test/e2e/specs/site-editor/template-part.spec.js