diff --git a/package.json b/package.json index 4ec15b2a..f2b10294 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,14 @@ "eslint-plugin-react": "^2.3.0", "expect": "^1.6.0", "isparta": "^3.0.3", + "jsdom": "^6.5.1", "mocha": "^2.2.5", - "rimraf": "^2.3.4" + "mocha-jsdom": "^1.0.0", + "react": "^0.14.0-rc1", + "react-addons-test-utils": "^0.14.0-rc1", + "react-dom": "^0.14.0-rc1", + "rimraf": "^2.3.4", + "webpack": "^1.11.0" }, "peerDependencies": { "redux": "^2.0.0 || ^3.0.0" diff --git a/test/createDevTools.spec.js b/test/createDevTools.spec.js new file mode 100644 index 00000000..1c4f82d1 --- /dev/null +++ b/test/createDevTools.spec.js @@ -0,0 +1,83 @@ +import expect from 'expect'; +import jsdom from 'mocha-jsdom'; +import React, { Component } from 'react'; +import TestUtils from 'react-addons-test-utils'; +import createDevTools from '../src/createDevTools'; +import devTools from '../src/devTools'; +import { createStore } from 'redux'; + +class MockMonitor extends Component { + render() { + return null; + } +} + +describe('createDevTools', () => { + jsdom(); + + it('should pass devToolsStore to monitor', () => { + const store = devTools()(createStore)(() => {}); + const DevTools = createDevTools(React); + const tree = TestUtils.renderIntoDocument( + + ); + const mockMonitor = TestUtils.findRenderedComponentWithType(tree, MockMonitor); + expect(mockMonitor.props.store).toBe(store.devToolsStore); + }); + + it('should pass props to monitor', () => { + const store = devTools()(createStore)(() => {}); + const DevTools = createDevTools(React); + const tree = TestUtils.renderIntoDocument( + + ); + const mockMonitor = TestUtils.findRenderedComponentWithType(tree, MockMonitor); + expect(mockMonitor.props.one).toBe(1); + expect(mockMonitor.props.two).toBe(2); + }); + + it('should subscribe monitor to store updates', () => { + const DevTools = createDevTools(React); + const store = devTools()(createStore)( + (state, action) => { + switch (action.type) { + case 'INC': + return state + 1; + default: + return state; + } + }, + 0 + ); + const tree = TestUtils.renderIntoDocument( + + ); + + store.dispatch({type: 'INC'}); + + const mockMonitor = TestUtils.findRenderedComponentWithType(tree, MockMonitor); + const currentStateIndex = mockMonitor.props.currentStateIndex; + const computedStates = mockMonitor.props.computedStates; + + expect(computedStates[currentStateIndex].state).toBe(1); + }); + + it('should warn if devTools() not in middleware', () => { + const spy = expect.spyOn(console, 'error'); + const store = createStore(() => {}); + const DevTools = createDevTools(React); + + expect( + TestUtils.renderIntoDocument, + ).withArgs( + + ).toThrow(); + + expect(spy.calls).toContain( + /Could not find the devTools store/, + (call, errMsg) => call.arguments[0].match(errMsg) + ); + + spy.restore(); + }); +}); diff --git a/test/devTools.spec.js b/test/devTools.spec.js index b7d2d65c..50cf8923 100644 --- a/test/devTools.spec.js +++ b/test/devTools.spec.js @@ -35,7 +35,7 @@ describe('devTools', () => { devToolsStore = store.devToolsStore; }); - it('performs actions', () => { + it('should perform actions', () => { expect(store.getState()).toBe(0); store.dispatch({ type: 'INCREMENT' }); expect(store.getState()).toBe(1); @@ -43,7 +43,7 @@ describe('devTools', () => { expect(store.getState()).toBe(2); }); - it('rollbacks state to the last committed state', () => { + it('should rollback state to the last committed state', () => { store.dispatch({ type: 'INCREMENT' }); store.dispatch({ type: 'INCREMENT' }); expect(store.getState()).toBe(2); @@ -65,7 +65,7 @@ describe('devTools', () => { expect(store.getState()).toBe(2); }); - it('resets to initial state', () => { + it('should reset to initial state', () => { store.dispatch({ type: 'INCREMENT' }); expect(store.getState()).toBe(1); @@ -85,7 +85,7 @@ describe('devTools', () => { expect(store.getState()).toBe(0); }); - it('toggles an action', () => { + it('should toggle an action', () => { // stateIndex 0 = @@INIT store.dispatch({ type: 'INCREMENT' }); store.dispatch({ type: 'DECREMENT' }); @@ -99,7 +99,7 @@ describe('devTools', () => { expect(store.getState()).toBe(1); }); - it('sweeps disabled actions', () => { + it('sweep disabled actions', () => { // stateIndex 0 = @@INIT store.dispatch({ type: 'INCREMENT' }); store.dispatch({ type: 'DECREMENT' }); @@ -120,7 +120,7 @@ describe('devTools', () => { expect(store.getState()).toBe(2); }); - it('jumps to state', () => { + it('should jump to state', () => { store.dispatch({ type: 'INCREMENT' }); store.dispatch({ type: 'DECREMENT' }); store.dispatch({ type: 'INCREMENT' }); @@ -142,12 +142,12 @@ describe('devTools', () => { expect(store.getState()).toBe(2); }); - it('sets monitor state', () => { + it('should set monitor state', () => { devToolsStore.dispatch(ActionCreators.setMonitorState({test: 'test'})); expect(devToolsStore.getState().monitorState.test).toBe('test'); }); - it('recomputes', () => { + it('should recompute', () => { store.dispatch({ type: 'INCREMENT' }); store.dispatch({ type: 'DECREMENT' }); store.dispatch({ type: 'INCREMENT' }); @@ -165,11 +165,11 @@ describe('devTools', () => { expect(store.getState()).toBe(13); }); - it('gets the reducer', () => { + it('should get the reducer', () => { expect(store.getReducer()).toBe(counter); }); - it('replaces the reducer', () => { + it('should replace the reducer', () => { store.dispatch({ type: 'INCREMENT' }); store.dispatch({ type: 'DECREMENT' }); store.dispatch({ type: 'INCREMENT' }); @@ -179,7 +179,7 @@ describe('devTools', () => { expect(store.getState()).toBe(2); }); - it('catches and records errors', () => { + it('should catch and record errors', () => { let spy = spyOn(console, 'error'); let storeWithBug = devTools()(createStore)(counterWithBug);