Refactor klona usage (https://github.com/woocommerce/woocommerce-blocks/pull/9320)
* cloneObject in tests * Create custom updateNested function instead of deepCloning objects * Update type based on feedback
This commit is contained in:
parent
fed679cbeb
commit
3743b024b7
|
@ -3,8 +3,7 @@
|
|||
*/
|
||||
import { dispatch, select } from '@wordpress/data';
|
||||
import { previewCart } from '@woocommerce/resource-previews';
|
||||
import { klona } from 'klona/json';
|
||||
import { Cart, CartResponse } from '@woocommerce/types';
|
||||
import { Cart } from '@woocommerce/types';
|
||||
import { camelCaseKeys } from '@woocommerce/base-utils';
|
||||
|
||||
/**
|
||||
|
@ -12,6 +11,9 @@ import { camelCaseKeys } from '@woocommerce/base-utils';
|
|||
*/
|
||||
import { notifyQuantityChanges } from '../notify-quantity-changes';
|
||||
|
||||
// Deep clone an object to avoid mutating it later.
|
||||
const cloneObject = ( obj ) => JSON.parse( JSON.stringify( obj ) );
|
||||
|
||||
jest.mock( '@wordpress/data' );
|
||||
|
||||
const mockedCreateInfoNotice = jest.fn();
|
||||
|
@ -35,12 +37,8 @@ select.mockImplementation( () => {
|
|||
* Clones the preview cart and turns it into a `Cart`.
|
||||
*/
|
||||
const getFreshCarts = (): { oldCart: Cart; newCart: Cart } => {
|
||||
const oldCart = camelCaseKeys(
|
||||
klona< CartResponse >( previewCart )
|
||||
) as Cart;
|
||||
const newCart = camelCaseKeys(
|
||||
klona< CartResponse >( previewCart )
|
||||
) as Cart;
|
||||
const oldCart = camelCaseKeys( cloneObject( previewCart ) ) as Cart;
|
||||
const newCart = camelCaseKeys( cloneObject( previewCart ) ) as Cart;
|
||||
return { oldCart, newCart };
|
||||
};
|
||||
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
/**
|
||||
* External dependencies
|
||||
* Utility for updating nested state in the path that changed.
|
||||
*/
|
||||
import { klona } from 'klona/json';
|
||||
function updateNested< T >( // The state being updated
|
||||
state: T,
|
||||
// The path being updated
|
||||
path: string[],
|
||||
// The value to update for the path
|
||||
value: unknown,
|
||||
// The current index in the path
|
||||
index = 0
|
||||
): T {
|
||||
const key = path[ index ] as keyof T;
|
||||
if ( index === path.length - 1 ) {
|
||||
return { ...state, [ key ]: value };
|
||||
}
|
||||
|
||||
const nextState = state[ key ] || {};
|
||||
return {
|
||||
...state,
|
||||
[ key ]: updateNested( nextState, path, value, index + 1 ),
|
||||
} as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for updating state and only cloning objects in the path that changed.
|
||||
*/
|
||||
export default function updateState< Type extends Record< string, unknown > >(
|
||||
export default function updateState< T >(
|
||||
// The state being updated
|
||||
state: Type,
|
||||
state: T,
|
||||
// The path being updated
|
||||
path: Array< keyof Type >,
|
||||
path: string[],
|
||||
// The value to update for the path
|
||||
value: unknown
|
||||
): Type {
|
||||
const newState = klona( state ) as Type;
|
||||
|
||||
let current: Record< string, unknown > = newState;
|
||||
for ( let i = 0; i < path.length; i++ ) {
|
||||
const key = path[ i ] as string;
|
||||
|
||||
if ( i === path.length - 1 ) {
|
||||
current[ key ] = value;
|
||||
} else {
|
||||
current[ key ] = current[ key ] || {};
|
||||
}
|
||||
|
||||
current = current[ key ] as Record< string, unknown >;
|
||||
}
|
||||
|
||||
return newState;
|
||||
): T {
|
||||
return updateNested( state, path, value );
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -199,12 +199,12 @@
|
|||
"glob-promise": "4.2.2",
|
||||
"husky": "8.0.3",
|
||||
"ignore-loader": "0.1.2",
|
||||
"jest": "^29.5.0",
|
||||
"jest-circus": "27.5.1",
|
||||
"jest-environment-puppeteer": "6.1.1",
|
||||
"jest-fetch-mock": "3.0.3",
|
||||
"jest-html-reporters": "3.0.10",
|
||||
"json2md": "1.12.0",
|
||||
"klona": "^2.0.6",
|
||||
"lint-staged": "13.2.0",
|
||||
"lodash": "4.17.21",
|
||||
"markdown-it": "13.0.1",
|
||||
|
|
Loading…
Reference in New Issue