From 283c439772b20bbc0a0eebaf82580083e1e73b35 Mon Sep 17 00:00:00 2001 From: taylorhakes Date: Tue, 30 Jun 2015 21:26:59 -0400 Subject: [PATCH] Throw error on undefined value from reducer function --- src/utils/composeReducers.js | 12 +++++++++--- test/composeReducers.spec.js | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/utils/composeReducers.js b/src/utils/composeReducers.js index 4d654ecfbed..e1f42499339 100644 --- a/src/utils/composeReducers.js +++ b/src/utils/composeReducers.js @@ -1,12 +1,18 @@ import mapValues from '../utils/mapValues'; import pick from '../utils/pick'; +import invariant from 'invariant'; export default function composeReducers(reducers) { const finalReducers = pick(reducers, (val) => typeof val === 'function'); return function composition(state = {}, action) { - return mapValues(finalReducers, (store, key) => - store(state[key], action) - ); + return mapValues(finalReducers, (reducer, key) => { + const newState = reducer(state[key], action); + invariant( + typeof newState !== 'undefined', + `Reducer ${key} returns undefined. By default reducer should return original state.` + ); + return newState; + }); }; } diff --git a/test/composeReducers.spec.js b/test/composeReducers.spec.js index c0ce3c919ed..37af766a429 100644 --- a/test/composeReducers.spec.js +++ b/test/composeReducers.spec.js @@ -29,5 +29,28 @@ describe('Utils', () => { Object.keys(reducer({}, { type: 'push' })) ).toEqual(['stack']); }); + it('should throw an error if undefined return from reducer', () => { + const reducer = composeReducers({ + stack: (state = []) => state, + bad: (state = [], action) => { + if (action.type === 'something') { + return state; + } + } + }); + expect(() => reducer({}, {type: '@@testType'})).toThrow(); + }); + it('should throw an error if undefined return not by default', () => { + const reducer = composeReducers({ + stack: (state = []) => state, + bad: (state = 1, action) => { + if (action.type !== 'something') { + return state; + } + } + }); + expect(reducer({}, {type: '@@testType'})).toEqual({stack: [], bad: 1}); + expect(() => reducer({}, {type: 'something'})).toThrow(); + }); }); });