Commit 96cc2de8 authored by Robert Knight's avatar Robert Knight

Freeze store state with `immutable` in development builds

Deep-freeze the store state after each action in development builds to
catch accidental mutation bugs such as #1879.

We couldn't do this in the past because the `annotation` component used
to mutate newly created annotations. As a result of recent refactoring,
this no longer happens.
parent 0c9eb7f7
/* global process */
import * as redux from 'redux';
import thunk from 'redux-thunk';
import immutable from '../util/immutable';
import { createReducer, bindSelectors } from './util';
/**
......@@ -56,14 +60,21 @@ export default function createStore(modules, initArgs = [], middleware = []) {
// asynchronous (see https://github.com/gaearon/redux-thunk#motivation)
thunk,
];
const enhancer = redux.applyMiddleware(...defaultMiddleware, ...middleware);
// Create the combined reducer from the reducers for each module.
let reducer = redux.combineReducers(allReducers);
// In debug builds, freeze the new state after each action to catch any attempts
// to mutate it, which indicates a bug since it is supposed to be immutable.
if (process.env.NODE_ENV !== 'production') {
const originalReducer = reducer;
reducer = (state, action) => immutable(originalReducer(state, action));
}
// Create the store.
const store = redux.createStore(
redux.combineReducers(allReducers),
initialState,
enhancer
);
const store = redux.createStore(reducer, initialState, enhancer);
// Add actions and selectors as methods to the store.
const actions = Object.assign({}, ...modules.map(m => m.actions));
......
/* global process */
import createStore from '../create-store';
const A = 0;
......@@ -159,4 +161,13 @@ describe('sidebar/store/create-store', () => {
assert.equal(store.getState().a.count, 0);
assert.equal(store.getState().b.count, 0);
});
if (process.env.NODE_ENV !== 'production') {
it('freezes store state in development builds', () => {
const store = counterStore();
assert.throws(() => {
store.getState().a.count = 1;
}, /Cannot assign to read only property/);
});
}
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment