Skip to content

Commit

Permalink
Throw error on undefined value from reducer function
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorhakes committed Jul 8, 2015
1 parent 069d641 commit b8e7e1e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/utils/composeReducers.js
Original file line number Diff line number Diff line change
@@ -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;
});
};
}
25 changes: 25 additions & 0 deletions test/composeReducers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,30 @@ 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();
});
});
});

0 comments on commit b8e7e1e

Please sign in to comment.