Skip to content

Commit

Permalink
Allow defining normalize method on selector and call for both selecto…
Browse files Browse the repository at this point in the history
…r and resolver
  • Loading branch information
getdave committed Oct 13, 2023
1 parent f569a98 commit cd31934
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
21 changes: 19 additions & 2 deletions packages/data/src/redux-store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,24 @@ export default function createReduxStore( key, options ) {
selector.registry = registry;
}
const boundSelector = ( ...args ) => {
if (
selector.normalizeArgs &&
typeof selector.normalizeArgs === 'function' &&
args?.length
) {
args = selector.normalizeArgs( args );
}
const state = store.__unstableOriginalGetState();
return selector( state.root, ...args );
};

// Expose normalization method on the bound selector
// in order that it can be called when fullfilling
// the resolver.
boundSelector.normalizeArgs = selector.normalizeArgs;

const resolver = resolvers[ selectorName ];

if ( ! resolver ) {
boundSelector.hasResolver = false;
return boundSelector;
Expand Down Expand Up @@ -604,8 +617,12 @@ function mapSelectorWithResolver(
}

const selectorResolver = ( ...args ) => {
if ( resolver.normalizeArgs && args?.length ) {
args = resolver.normalizeArgs( args );
if (
selector.normalizeArgs &&
typeof selector.normalizeArgs === 'function' &&
args?.length
) {
args = selector.normalizeArgs( args );
}
fulfillSelector( args );
return selector( ...args );
Expand Down
36 changes: 21 additions & 15 deletions packages/data/src/redux-store/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,46 +288,52 @@ describe( 'resolveSelect', () => {
} );

describe( 'normalizing args', () => {
it( 'should call the .normalizeArgs method on the resolver if it exists', async () => {
it( 'should call the normalizeArgs method of the selector for both the selector and the resolver', async () => {
const registry = createRegistry();
const resolver = () => {};
const selector = () => {};

resolver.normalizeArgs = jest.fn( ( ...args ) => args );
const normalizingFunction = jest.fn( ( ...args ) => args );

selector.normalizeArgs = normalizingFunction;

registry.registerStore( 'store', {
reducer: () => {},
selectors: {
getItems: () => 'items',
getItems: selector,
},
resolvers: {
getItems: resolver,
getItems: () => 'items',
},
} );
registry.select( 'store' ).getItems( 'foo', 'bar' );

expect( resolver.normalizeArgs ).toHaveBeenCalledWith( [
'foo',
'bar',
] );
expect( normalizingFunction ).toHaveBeenCalledWith( [ 'foo', 'bar' ] );

// Needs to be call twice:
// 1. When the selector is called.
// 2. When the resolver is fullfilled.
expect( normalizingFunction ).toHaveBeenCalledTimes( 2 );
} );

it( 'should not call normalizeArgs if there are no arguments passed to the resolver', async () => {
it( 'should not call the normalizeArgs method if there are no arguments passed to the selector (and thus the resolver)', async () => {
const registry = createRegistry();
const resolver = () => {};
const selector = () => {};

resolver.normalizeArgs = jest.fn( ( ...args ) => args );
selector.normalizeArgs = jest.fn( ( ...args ) => args );

registry.registerStore( 'store', {
reducer: () => {},
selectors: {
getItems: () => 'items',
getItems: selector,
},
resolvers: {
getItems: resolver,
getItems: () => 'items',
},
} );

// Called with no args so the normalizeArgs method should not be called.
registry.select( 'store' ).getItems();

expect( resolver.normalizeArgs ).not.toHaveBeenCalled();
expect( selector.normalizeArgs ).not.toHaveBeenCalled();
} );
} );

0 comments on commit cd31934

Please sign in to comment.