diff --git a/src/devTools.js b/src/devTools.js index f57e9bc1..aa331836 100644 --- a/src/devTools.js +++ b/src/devTools.js @@ -152,8 +152,11 @@ function liftReducer(reducer, initialState) { stagedActions = liftedAction.stagedActions; timestamps = liftedAction.timestamps; committedState = liftedAction.committedState; - currentStateIndex = stagedActions.length - 1; - skippedActions = {}; + currentStateIndex = liftedAction.currentStateIndex; + if (currentStateIndex === -1) { + currentStateIndex = stagedActions.length - 1; + } + skippedActions = liftedAction.skippedActions; break; default: break; @@ -247,11 +250,14 @@ export const ActionCreators = { setMonitorState(monitorState) { return { type: ActionTypes.SET_MONITOR_STATE, monitorState }; }, - recomputeStates(committedState, stagedActions) { + recomputeStates(committedState, stagedActions, timestamps, currentStateIndex=-1, skippedActions={}) { return { type: ActionTypes.RECOMPUTE_STATES, committedState, - stagedActions + stagedActions, + skippedActions, + timestamps, + currentStateIndex }; } }; diff --git a/test/index.spec.js b/test/index.spec.js index e69de29b..02a703a1 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -0,0 +1,87 @@ +import expect from 'expect'; +import devTools, {ActionCreators as DAC} from '../src/devTools'; +import { createStore, compose } from 'redux'; + +const reducer = function counter(state = 0, action) { + switch (action.type) { + case 'INC': + return state + 1; + case 'DEC': + return state - 1; + default: + return state; + } +}; + + +const createDevStore = () => compose(devTools(), createStore)(reducer); + +describe('Recompute state', () => { + + describe('export/import', () => { + let store; + + // helpters + const getDevState = () => store.devToolsStore.getState(); + const dispatch = (action) => store.devToolsStore.dispatch(action); + const recomputeExpectedState = (expState) => { + dispatch(DAC.recomputeStates( + expState.commitedState, + expState.stagedActions, + expState.timestamps, + expState.currentStateIndex, + expState.skippedActions + )); + return getDevState(); + }; + + // create some timestamps + beforeEach((done) => { + store = createDevStore(); + setTimeout(() => store.dispatch({type: 'INC'}), 3); + setTimeout(() => store.dispatch({type: 'INC'}), 6); + setTimeout(() => { + store.dispatch({type: 'INC'}); + done(); + }, 9); + }); + + it('should be possible to set the current index', () => { + dispatch(DAC.jumpToState(1)); + const expState = getDevState(); + dispatch(DAC.jumpToState(2)); + const rcState = recomputeExpectedState(expState); + + expect(rcState.currentStateIndex).toBe(expState.currentStateIndex); + }); + + it('currentStateIndex should be optional', () => { + const expState = getDevState(); + dispatch(DAC.jumpToState(1)); + const rcState = recomputeExpectedState({ + ...expState, + currentStateIndex: undefined + }); + + expect(rcState.currentStateIndex).toBe(3); + }); + + it('should be possible to preserve skipped actions', () => { + dispatch(DAC.toggleAction(1)); + const expState = getDevState(); + dispatch(DAC.toggleAction(2)); + const rcState = recomputeExpectedState(expState); + + expect(rcState.skippedActions).toBe(expState.skippedActions); + }); + + it('should preserve timestamps', () => { + const expState = getDevState(); + const rcState = recomputeExpectedState(expState); + + expect(rcState.timestamps).toBe(expState.timestamps); + }); + + }); + +});