@wordpress/data
Version:
Data module for WordPress.
174 lines (154 loc) • 4.53 kB
JavaScript
/**
* Internal dependencies
*/
import { createRegistry, controls } from '..';
describe( 'controls', () => {
// Create a registry with store to test select controls.
function createSelectTestRegistry() {
const registry = createRegistry();
// State is initially null and can receive data.
// Typical for fetching data from remote locations.
const reducer = ( state = null, action ) => {
switch ( action.type ) {
case 'RECEIVE':
return action.data;
default:
return state;
}
};
// Select state both without and with a resolver.
const selectors = {
selectorWithoutResolver: ( state ) => state,
selectorWithResolver: ( state ) => state,
};
// The resolver receives data after a little delay.
const resolvers = {
*selectorWithResolver() {
yield new Promise( ( r ) => setTimeout( r, 10 ) );
return { type: 'RECEIVE', data: 'resolved-data' };
},
};
// actions that call the tested controls and return the selected value.
const actions = {
*resolveWithoutResolver() {
const value = yield controls.resolveSelect(
'test/select',
'selectorWithoutResolver'
);
return value;
},
*resolveWithResolver() {
const value = yield controls.resolveSelect(
'test/select',
'selectorWithResolver'
);
return value;
},
*selectWithoutResolver() {
const value = yield controls.select(
'test/select',
'selectorWithoutResolver'
);
return value;
},
*selectWithResolver() {
const value = yield controls.select(
'test/select',
'selectorWithResolver'
);
return value;
},
};
registry.registerStore( 'test/select', {
reducer,
actions,
selectors,
resolvers,
} );
return registry;
}
describe( 'resolveSelect', () => {
it( 'invokes selector without a resolver', async () => {
const registry = createSelectTestRegistry();
const value = await registry
.dispatch( 'test/select' )
.resolveWithoutResolver();
// Returns the state value without waiting for any resolver.
expect( value ).toBe( null );
} );
it( 'resolves selector with a resolver', async () => {
const registry = createSelectTestRegistry();
const value = await registry
.dispatch( 'test/select' )
.resolveWithResolver();
// Waits for the resolver to resolve and returns the resolved data.
// Never returns the initial `null` state.
expect( value ).toBe( 'resolved-data' );
} );
} );
describe( 'select', () => {
it( 'invokes selector without a resolver', async () => {
const registry = createSelectTestRegistry();
const value = await registry
.dispatch( 'test/select' )
.selectWithoutResolver();
// Returns the state value without waiting for any resolver.
expect( value ).toBe( null );
} );
it( 'invokes selector with a resolver', async () => {
const registry = createSelectTestRegistry();
// Check that the action with a control returns the initial state
// without waiting for any resolver.
const value = await registry
.dispatch( 'test/select' )
.selectWithResolver();
expect( value ).toBe( null );
// Check that re-running the action immediately still returns
// the initial state, as the resolution is still running.
const value2 = await registry
.dispatch( 'test/select' )
.selectWithResolver();
expect( value2 ).toBe( null );
} );
} );
describe( 'dispatch', () => {
function createDispatchTestRegistry() {
const registry = createRegistry();
// Store stores a counter that can be incremented.
const reducer = ( state = 0, action ) => {
switch ( action.type ) {
case 'INC':
return state + 1;
default:
return state;
}
};
const actions = {
// increment the counter.
inc() {
return { type: 'INC' };
},
// Increment the counter twice in an async routine with controls.
*doubleInc() {
yield controls.dispatch( 'test/dispatch', 'inc' );
yield controls.dispatch( 'test/dispatch', 'inc' );
},
};
const selectors = {
get: ( state ) => state,
};
registry.registerStore( 'test/dispatch', {
reducer,
actions,
selectors,
} );
return registry;
}
it( 'invokes dispatch action', async () => {
const registry = createDispatchTestRegistry();
expect( registry.select( 'test/dispatch' ).get() ).toBe( 0 );
await registry.dispatch( 'test/dispatch' ).doubleInc();
expect( registry.select( 'test/dispatch' ).get() ).toBe( 2 );
} );
} );
} );