fix(non-nested): Address issue where non-nested actions and selectors required nesting in return object

This commit is contained in:
Kai Moseley 2017-05-07 18:25:26 +01:00
parent 003501c00e
commit a899de7144
2 changed files with 33 additions and 16 deletions

View File

@ -1,6 +1,5 @@
import { import {
buildStoreChunk, buildStoreChunk,
processStructure,
} from '../buildStoreChunk'; } from '../buildStoreChunk';
import { import {
Types, Types,
@ -9,6 +8,7 @@ import {
createStore, createStore,
combineReducers, combineReducers,
} from 'redux'; } from 'redux';
import isFunction from 'lodash/isFunction';
describe('buildStoreChunk', () => { describe('buildStoreChunk', () => {
describe('buildStoreChunk', () => { describe('buildStoreChunk', () => {
@ -50,8 +50,8 @@ describe('buildStoreChunk', () => {
it('Selectors object has the correct top level structure for a nested chunk', () => { it('Selectors object has the correct top level structure for a nested chunk', () => {
expect(Object.keys(chunk.selectors)).toEqual(['nested1', 'nested2', 'nested3', 'nested4']); expect(Object.keys(chunk.selectors)).toEqual(['nested1', 'nested2', 'nested3', 'nested4']);
}); });
it('Selectors object has the correct top level structure for a non nested chunk', () => { it('Selectors object is a function for a non-nested chunk', () => {
expect(Object.keys(nonNestedChunk.selectors)).toEqual(['example2']); expect(isFunction(nonNestedChunk.selectors)).toBe(true);
}); });
it('Nested selectors object has the correct structure for a defined reducer', () => { it('Nested selectors object has the correct structure for a defined reducer', () => {
expect(Object.keys(chunk.selectors.nested4)).toEqual(['innerNested1', 'innerNested2']); expect(Object.keys(chunk.selectors.nested4)).toEqual(['innerNested1', 'innerNested2']);
@ -69,7 +69,7 @@ describe('buildStoreChunk', () => {
expect(Object.keys(chunk.actions)).toEqual(['nested1', 'nested2', 'nested3', 'nested4']); expect(Object.keys(chunk.actions)).toEqual(['nested1', 'nested2', 'nested3', 'nested4']);
}); });
it('Actions object has the correct top level structure for a non nested chunk', () => { it('Actions object has the correct top level structure for a non nested chunk', () => {
expect(Object.keys(nonNestedChunk.actions)).toEqual(['example2']); expect(Object.keys(nonNestedChunk.actions)).toEqual(['replace', 'reset']);
}); });
it('Nested actions object has the correct structure for a chunk', () => { it('Nested actions object has the correct structure for a chunk', () => {
expect(Object.keys(chunk.actions.nested4)).toEqual(['innerNested1', 'innerNested2']); expect(Object.keys(chunk.actions.nested4)).toEqual(['innerNested1', 'innerNested2']);
@ -103,19 +103,15 @@ describe('buildStoreChunk', () => {
})); }));
it('Dispatching an action should correctly update the store', () => { it('Dispatching an action should correctly update the store', () => {
store.dispatch(nonNestedChunk.actions.example2.replace('bar')); store.dispatch(nonNestedChunk.actions.replace('bar'));
expect(nonNestedChunk.selectors.example2(store.getState())).toEqual('bar'); expect(nonNestedChunk.selectors(store.getState())).toEqual('bar');
store.dispatch(nonNestedChunk.actions.example2.reset()); store.dispatch(nonNestedChunk.actions.reset());
expect(nonNestedChunk.selectors.example2(store.getState())).toEqual('foo'); expect(nonNestedChunk.selectors(store.getState())).toEqual('foo');
}); });
}); });
}); });
}); });
describe('processStructure', () => {
});
}); });

View File

@ -20,7 +20,6 @@ import { PROP_TYPES } from './structure';
// generated will specifically operate on the store chunk generated. Selectors will be // generated will specifically operate on the store chunk generated. Selectors will be
// relative to the baseSelector provided or, if not specified, the root of the store, using // relative to the baseSelector provided or, if not specified, the root of the store, using
// the name of the chunk as the base property. // the name of the chunk as the base property.
export function buildStoreChunk(name: string, structure: any, { export function buildStoreChunk(name: string, structure: any, {
baseSelector = state => state[name], baseSelector = state => state[name],
locationString = name, locationString = name,
@ -39,13 +38,35 @@ export function buildStoreChunk(name: string, structure: any, {
locationString, locationString,
name, name,
}; };
//Build up the reducers, actions, and selectors for this level. Due to recursion, //Build up the reducers, actions, and selectors for this level. Due to recursion,
//these objects will be assigned to a property in the parent object, or simply //these objects will be assigned to a property in the parent object, or simply
//returned to the call site for use in the rest of the application. //returned to the call site for use in the rest of the application.
const processedStructure = determineStructureProcessing(structure, initialMemo, name);
//If the reducer's structure is a function (and, therefore, not nested reducers), we can skip the reduce. //If the location string is equal to the name passed to build store chunk, then we must be
if (isFunction(structure)) return combineStoreChunkReducers(processStructure(initialMemo, structure, name)); //at the top level. If the structure is a function (i.e. not nested reducers) then return
return combineStoreChunkReducers(reduce(structure, processStructure, initialMemo)); //the actions, and selectors as the top level of their respective objects.
if (isFunction(structure)) {
console.log(111, processedStructure, {
reducers: processedStructure.reducers,
actions: processedStructure.actions[name],
selectors: processedStructure.selectors[name],
});
return {
reducers: processedStructure.reducers,
actions: processedStructure.actions[name],
selectors: processedStructure.selectors[name],
};
}
return processedStructure;
}
export function determineStructureProcessing(structure: any, initialMemo: PartialStoreChunk, name) {
if (isFunction(structure)) return combineStoreChunkReducers(processStructure(initialMemo, structure, name));
return combineStoreChunkReducers(reduce(structure, processStructure, initialMemo));
} }