From 411da5469f75dd4df833fd17013444ce6915ab14 Mon Sep 17 00:00:00 2001 From: Itayod Date: Fri, 4 Jan 2019 16:55:27 +0200 Subject: [PATCH] fix(store): call metareducer with the user's config initial state --- modules/store/spec/store.spec.ts | 52 ++++++++++++++++++++++++++------ modules/store/src/utils.ts | 11 +++++-- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/modules/store/spec/store.spec.ts b/modules/store/spec/store.spec.ts index eb9dd4a759..18d91df57b 100644 --- a/modules/store/spec/store.spec.ts +++ b/modules/store/spec/store.spec.ts @@ -14,6 +14,7 @@ import { Action, } from '../'; import { StoreConfig } from '../src/store_module'; +import { combineReducers } from '../src/utils'; import { counterReducer, INCREMENT, @@ -373,11 +374,11 @@ describe('ngRx Store', () => { }); it('should dispatch an update reducers action when a feature is added', () => { - reducerManager.addFeature( - createFeature({ - key: 'feature1', - }) - ); + reducerManager.addFeature({ + key: 'feature1', + reducers: {}, + reducerFactory: combineReducers, + }); expect(reducerManagerDispatcherSpy).toHaveBeenCalledWith({ type: UPDATE, @@ -387,12 +388,16 @@ describe('ngRx Store', () => { it('should dispatch an update reducers action when multiple features are added', () => { reducerManager.addFeatures([ - createFeature({ + { key: 'feature1', - }), - createFeature({ + reducers: {}, + reducerFactory: combineReducers, + }, + { key: 'feature2', - }), + reducers: {}, + reducerFactory: combineReducers, + }, ]); expect(reducerManagerDispatcherSpy).toHaveBeenCalledTimes(1); @@ -546,13 +551,42 @@ describe('ngRx Store', () => { }), ], }); + const mockStore = TestBed.get(Store); const action = { type: INCREMENT }; + mockStore.dispatch(action); expect(metaReducerSpy1).toHaveBeenCalledWith(counterReducer); expect(metaReducerSpy2).toHaveBeenCalledWith(counterReducer2); }); + + it('should initial state with value', (done: DoneFn) => { + const counterInitialState = 2; + TestBed.configureTestingModule({ + imports: [ + StoreModule.forRoot({}), + StoreModule.forFeature( + 'counterState', + { counter: counterReducer }, + { + initialState: { counter: counterInitialState }, + metaReducers: [metaReducerContainer.metaReducer1], + } + ), + ], + }); + + const mockStore = TestBed.get(Store); + + mockStore.pipe(take(1)).subscribe({ + next(val: any) { + expect(val['counterState'].counter).toEqual(counterInitialState); + }, + error: done, + complete: done, + }); + }); }); describe('Feature config token', () => { diff --git a/modules/store/src/utils.ts b/modules/store/src/utils.ts index 7ded8a3810..5aa6cfbbb2 100644 --- a/modules/store/src/utils.ts +++ b/modules/store/src/utils.ts @@ -4,6 +4,7 @@ import { ActionReducerFactory, ActionReducerMap, MetaReducer, + InitialState, } from './models'; export function combineReducers( @@ -92,10 +93,16 @@ export function createReducerFactory( metaReducers?: MetaReducer[] ): ActionReducerFactory { if (Array.isArray(metaReducers) && metaReducers.length > 0) { - return compose.apply(null, [...metaReducers, reducerFactory]); + reducerFactory = compose.apply(null, [...metaReducers, reducerFactory]); } - return reducerFactory; + return (reducers: ActionReducerMap, initialState?: InitialState) => { + const reducer = reducerFactory(reducers, initialState); + return (state: T | undefined, action: V) => { + state = state === undefined ? (initialState as T) : state; + return reducer(state, action); + }; + }; } export function createFeatureReducerFactory(