From a899de71441e02dcedbd237dbbf33a5cf1fe2d27 Mon Sep 17 00:00:00 2001 From: Kai Moseley Date: Sun, 7 May 2017 18:25:26 +0100 Subject: [PATCH] fix(non-nested): Address issue where non-nested actions and selectors required nesting in return object --- src/__tests__/buildStoreChunk.test.js | 20 ++++++++---------- src/buildStoreChunk.js | 29 +++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/__tests__/buildStoreChunk.test.js b/src/__tests__/buildStoreChunk.test.js index f56259a..eda70ac 100644 --- a/src/__tests__/buildStoreChunk.test.js +++ b/src/__tests__/buildStoreChunk.test.js @@ -1,6 +1,5 @@ import { buildStoreChunk, - processStructure, } from '../buildStoreChunk'; import { Types, @@ -9,6 +8,7 @@ import { createStore, combineReducers, } from 'redux'; +import isFunction from 'lodash/isFunction'; describe('buildStoreChunk', () => { describe('buildStoreChunk', () => { @@ -50,8 +50,8 @@ describe('buildStoreChunk', () => { it('Selectors object has the correct top level structure for a nested chunk', () => { expect(Object.keys(chunk.selectors)).toEqual(['nested1', 'nested2', 'nested3', 'nested4']); }); - it('Selectors object has the correct top level structure for a non nested chunk', () => { - expect(Object.keys(nonNestedChunk.selectors)).toEqual(['example2']); + it('Selectors object is a function for a non-nested chunk', () => { + expect(isFunction(nonNestedChunk.selectors)).toBe(true); }); it('Nested selectors object has the correct structure for a defined reducer', () => { 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']); }); 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', () => { expect(Object.keys(chunk.actions.nested4)).toEqual(['innerNested1', 'innerNested2']); @@ -103,19 +103,15 @@ describe('buildStoreChunk', () => { })); it('Dispatching an action should correctly update the store', () => { - store.dispatch(nonNestedChunk.actions.example2.replace('bar')); - expect(nonNestedChunk.selectors.example2(store.getState())).toEqual('bar'); + store.dispatch(nonNestedChunk.actions.replace('bar')); + expect(nonNestedChunk.selectors(store.getState())).toEqual('bar'); - store.dispatch(nonNestedChunk.actions.example2.reset()); - expect(nonNestedChunk.selectors.example2(store.getState())).toEqual('foo'); + store.dispatch(nonNestedChunk.actions.reset()); + expect(nonNestedChunk.selectors(store.getState())).toEqual('foo'); }); }); }); }); - - describe('processStructure', () => { - - }); }); diff --git a/src/buildStoreChunk.js b/src/buildStoreChunk.js index e5b48e4..d7eba52 100644 --- a/src/buildStoreChunk.js +++ b/src/buildStoreChunk.js @@ -20,7 +20,6 @@ import { PROP_TYPES } from './structure'; // 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 // the name of the chunk as the base property. - export function buildStoreChunk(name: string, structure: any, { baseSelector = state => state[name], locationString = name, @@ -39,13 +38,35 @@ export function buildStoreChunk(name: string, structure: any, { locationString, name, }; + //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 //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 (isFunction(structure)) return combineStoreChunkReducers(processStructure(initialMemo, structure, name)); - return combineStoreChunkReducers(reduce(structure, processStructure, initialMemo)); + //If the location string is equal to the name passed to build store chunk, then we must be + //at the top level. If the structure is a function (i.e. not nested reducers) then return + //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)); }