mirror of
				https://github.com/reduxjs/redux-devtools.git
				synced 2025-11-04 01:47:25 +03:00 
			
		
		
		
	merge
This commit is contained in:
		
						commit
						49bb120444
					
				| 
						 | 
					@ -4,6 +4,12 @@ Redux DevTools
 | 
				
			||||||
A live-editing time travel environment for [Redux](https://github.com/rackt/redux).  
 | 
					A live-editing time travel environment for [Redux](https://github.com/rackt/redux).  
 | 
				
			||||||
**[See Dan's React Europe talk demoing it!](http://youtube.com/watch?v=xsSnOQynTHs)**
 | 
					**[See Dan's React Europe talk demoing it!](http://youtube.com/watch?v=xsSnOQynTHs)**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[](https://travis-ci.org/gaearon/redux-devtools)
 | 
				
			||||||
 | 
					[](https://www.npmjs.com/package/redux-devtools)
 | 
				
			||||||
 | 
					[](https://www.npmjs.com/package/redux-devtools)
 | 
				
			||||||
 | 
					[](http://www.reactiflux.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||

 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Features
 | 
					### Features
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ export default function persistState(sessionId, stateDeserializer = null, action
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
          localStorage.setItem(key, JSON.stringify(store.getState()));
 | 
					          localStorage.setItem(key, JSON.stringify(store.getState()));
 | 
				
			||||||
        } catch (e) {
 | 
					        } catch (e) {
 | 
				
			||||||
          console.warn('Could not write debug session from localStorage:', e);
 | 
					          console.warn('Could not write debug session to localStorage:', e);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return action;
 | 
					        return action;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ function counterWithBug(state = 0, action) {
 | 
				
			||||||
  switch (action.type) {
 | 
					  switch (action.type) {
 | 
				
			||||||
    case 'INCREMENT': return state + 1;
 | 
					    case 'INCREMENT': return state + 1;
 | 
				
			||||||
    case 'DECREMENT': return mistake - 1; // eslint-disable-line no-undef
 | 
					    case 'DECREMENT': return mistake - 1; // eslint-disable-line no-undef
 | 
				
			||||||
 | 
					    case 'SET_UNDEFINED': return undefined;
 | 
				
			||||||
    default: return state;
 | 
					    default: return state;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -99,7 +100,7 @@ describe('devTools', () => {
 | 
				
			||||||
    expect(store.getState()).toBe(1);
 | 
					    expect(store.getState()).toBe(1);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('sweep disabled actions', () => {
 | 
					  it('should sweep disabled actions', () => {
 | 
				
			||||||
    // stateIndex 0 = @@INIT
 | 
					    // stateIndex 0 = @@INIT
 | 
				
			||||||
    store.dispatch({ type: 'INCREMENT' });
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
    store.dispatch({ type: 'DECREMENT' });
 | 
					    store.dispatch({ type: 'DECREMENT' });
 | 
				
			||||||
| 
						 | 
					@ -153,13 +154,14 @@ describe('devTools', () => {
 | 
				
			||||||
    store.dispatch({ type: 'INCREMENT' });
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
    expect(store.getState()).toBe(1);
 | 
					    expect(store.getState()).toBe(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let devStoreState = store.devToolsStore.getState();
 | 
					    let stagedActions = [...store.devToolsStore.getState().stagedActions];
 | 
				
			||||||
    devStoreState.committedState = 10;
 | 
					    // replace DECREMENT with INCREMENT (stagedAction[0] is @@INIT)
 | 
				
			||||||
    devStoreState.stagedActions[2] = { type: 'INCREMENT' };
 | 
					    stagedActions[2] = { type: 'INCREMENT' };
 | 
				
			||||||
 | 
					    const committedState = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    devToolsStore.dispatch(ActionCreators.recomputeStates(
 | 
					    devToolsStore.dispatch(ActionCreators.recomputeStates(
 | 
				
			||||||
      devStoreState.committedState,
 | 
					      committedState,
 | 
				
			||||||
      devStoreState.stagedActions
 | 
					      stagedActions
 | 
				
			||||||
    ));
 | 
					    ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(store.getState()).toBe(13);
 | 
					    expect(store.getState()).toBe(13);
 | 
				
			||||||
| 
						 | 
					@ -201,18 +203,13 @@ describe('devTools', () => {
 | 
				
			||||||
    spy.restore();
 | 
					    spy.restore();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('returns the last non-undefined state from getState', () => {
 | 
					  it('should return the last non-undefined state from getState', () => {
 | 
				
			||||||
    let spy = spyOn(console, 'error');
 | 
					    let storeWithBug = devTools()(createStore)(counterWithBug);
 | 
				
			||||||
 | 
					    storeWithBug.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    storeWithBug.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    expect(storeWithBug.getState()).toBe(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    store.dispatch({ type: 'INCREMENT' });
 | 
					    storeWithBug.dispatch({ type: 'SET_UNDEFINED' });
 | 
				
			||||||
    store.dispatch({ type: 'DECREMENT' });
 | 
					    expect(storeWithBug.getState()).toBe(2);
 | 
				
			||||||
    store.dispatch({ type: 'INCREMENT' });
 | 
					 | 
				
			||||||
    store.dispatch({ type: 'INCREMENT' });
 | 
					 | 
				
			||||||
    expect(store.getState()).toBe(2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    store.replaceReducer(counterWithBug);
 | 
					 | 
				
			||||||
    expect(store.getState()).toBe(1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    spy.restore();
 | 
					 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										123
									
								
								test/persistState.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								test/persistState.spec.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,123 @@
 | 
				
			||||||
 | 
					import expect from 'expect';
 | 
				
			||||||
 | 
					import devTools from '../src/devTools';
 | 
				
			||||||
 | 
					import persistState from '../src/persistState';
 | 
				
			||||||
 | 
					import { compose, createStore } from 'redux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('persistState', () => {
 | 
				
			||||||
 | 
					  let savedLocalStorage = global.localStorage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(() => {
 | 
				
			||||||
 | 
					    global.localStorage = {
 | 
				
			||||||
 | 
					      store: {},
 | 
				
			||||||
 | 
					      getItem(key) {
 | 
				
			||||||
 | 
					        return this.store[key] || null;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      setItem(key, value) {
 | 
				
			||||||
 | 
					        this.store[key] = value;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      removeItem(key) {
 | 
				
			||||||
 | 
					        delete this.store[key];
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      clear() {
 | 
				
			||||||
 | 
					        this.store = {};
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  after(() => {
 | 
				
			||||||
 | 
					    global.localStorage = savedLocalStorage;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const reducer = (state = 0, action) => {
 | 
				
			||||||
 | 
					    switch (action.type) {
 | 
				
			||||||
 | 
					    case 'INCREMENT':
 | 
				
			||||||
 | 
					      return state + 1;
 | 
				
			||||||
 | 
					    case 'DECREMENT':
 | 
				
			||||||
 | 
					      return state - 1;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      return state;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should persist state', () => {
 | 
				
			||||||
 | 
					    const finalCreateStore = compose(devTools(), persistState('id'))(createStore);
 | 
				
			||||||
 | 
					    const store = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					    expect(store.getState()).toBe(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    expect(store.getState()).toBe(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const store2 = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					    expect(store2.getState()).toBe(2);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should not persist state if no session id', () => {
 | 
				
			||||||
 | 
					    const finalCreateStore = compose(devTools(), persistState())(createStore);
 | 
				
			||||||
 | 
					    const store = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					    expect(store.getState()).toBe(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    expect(store.getState()).toBe(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const store2 = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					    expect(store2.getState()).toBe(0);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should run with a custom state deserializer', () => {
 | 
				
			||||||
 | 
					    const oneLess = state => state === undefined ? -1 : state - 1;
 | 
				
			||||||
 | 
					    const finalCreateStore = compose(devTools(), persistState('id', oneLess))(createStore);
 | 
				
			||||||
 | 
					    const store = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					    expect(store.getState()).toBe(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    expect(store.getState()).toBe(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const store2 = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					    expect(store2.getState()).toBe(1);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should run with a custom action deserializer', () => {
 | 
				
			||||||
 | 
					    const incToDec = action => action.type === 'INCREMENT' ? { type: 'DECREMENT' } : action;
 | 
				
			||||||
 | 
					    const finalCreateStore = compose(devTools(), persistState('id', null, incToDec))(createStore);
 | 
				
			||||||
 | 
					    const store = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					    expect(store.getState()).toBe(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    expect(store.getState()).toBe(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const store2 = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					    expect(store2.getState()).toBe(-2);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should warn if read from localStorage fails', () => {
 | 
				
			||||||
 | 
					    const spy = expect.spyOn(console, 'warn');
 | 
				
			||||||
 | 
					    const finalCreateStore = compose(devTools(), persistState('id'))(createStore);
 | 
				
			||||||
 | 
					    delete global.localStorage.getItem;
 | 
				
			||||||
 | 
					    finalCreateStore(reducer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(spy.calls).toContain(
 | 
				
			||||||
 | 
					      /Could not read debug session from localStorage/,
 | 
				
			||||||
 | 
					      (call, errMsg) => call.arguments[0].match(errMsg)
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    spy.restore();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  it('should warn if write to localStorage fails', () => {
 | 
				
			||||||
 | 
					    const spy = expect.spyOn(console, 'warn');
 | 
				
			||||||
 | 
					    const finalCreateStore = compose(devTools(), persistState('id'))(createStore);
 | 
				
			||||||
 | 
					    delete global.localStorage.setItem;
 | 
				
			||||||
 | 
					    const store = finalCreateStore(reducer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    store.dispatch({ type: 'INCREMENT' });
 | 
				
			||||||
 | 
					    expect(spy.calls).toContain(
 | 
				
			||||||
 | 
					      /Could not write debug session to localStorage/,
 | 
				
			||||||
 | 
					      (call, errMsg) => call.arguments[0].match(errMsg)
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    spy.restore();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user