Skip to content

WIP: tests for the examples #278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
4 changes: 2 additions & 2 deletions examples/counter/actions/CounterActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ export function incrementIfOdd() {
};
}

export function incrementAsync() {
export function incrementAsync(delay=1000) {
return dispatch => {
setTimeout(() => {
dispatch(increment());
}, 1000);
}, delay);
};
}
5 changes: 4 additions & 1 deletion examples/counter/components/Counter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ export default class Counter extends Component {
static propTypes = {
increment: PropTypes.func.isRequired,
incrementIfOdd: PropTypes.func.isRequired,
incrementAsync: PropTypes.func.isRequired,
decrement: PropTypes.func.isRequired,
counter: PropTypes.number.isRequired
};

render() {
const { increment, incrementIfOdd, decrement, counter } = this.props;
const { increment, incrementIfOdd, incrementAsync, decrement, counter } = this.props;
return (
<p>
Clicked: {counter} times
Expand All @@ -19,6 +20,8 @@ export default class Counter extends Component {
<button onClick={decrement}>-</button>
{' '}
<button onClick={incrementIfOdd}>Increment if odd</button>
{' '}
<button onClick={() => incrementAsync()}>Increment async</button>
</p>
);
}
Expand Down
10 changes: 3 additions & 7 deletions examples/counter/containers/App.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import React, { Component } from 'react';
import CounterApp from './CounterApp';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import * as reducers from '../reducers';
import CounterApp from './CounterApp';
import createCounterStore from '../store/createCounterStore';

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const reducer = combineReducers(reducers);
const store = createStoreWithMiddleware(reducer);
const store = createCounterStore();

export default class App extends Component {
render() {
Expand Down
7 changes: 6 additions & 1 deletion examples/counter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "Counter example for redux",
"main": "server.js",
"scripts": {
"start": "node server.js"
"start": "node server.js",
"test": "mocha --recursive --compilers js:babel/register"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -35,6 +36,10 @@
"devDependencies": {
"babel-core": "^5.6.18",
"babel-loader": "^5.1.4",
"expect": "^1.6.0",
"jsdom": "^5.6.1",
"mocha": "^2.2.5",
"mocha-jsdom": "^1.0.0",
"node-libs-browser": "^0.5.2",
"react-hot-loader": "^1.2.7",
"webpack": "^1.9.11",
Expand Down
10 changes: 10 additions & 0 deletions examples/counter/store/createCounterStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createStore, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import * as reducers from '../reducers';

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const reducer = combineReducers(reducers);

export default function createCounterStore(initialState) {
return createStoreWithMiddleware(reducer, initialState);
}
44 changes: 44 additions & 0 deletions examples/counter/test/actions/CounterActions.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import expect from 'expect';
import * as actions from '../../actions/CounterActions';
import * as types from '../../constants/ActionTypes';

describe('actions', () => {

it('increment should create increment action', () => {
expect(actions.increment()).toEqual({ type: types.INCREMENT_COUNTER });
});

it('decrement should create decrement action', () => {
expect(actions.decrement()).toEqual({ type: types.DECREMENT_COUNTER });
});

it('incrementIfOdd should create increment action', () => {
let fn = actions.incrementIfOdd();
expect(fn).toBeA('function');
let dispatch = expect.createSpy();
let getState = () => ({ counter: 1 });
fn(dispatch, getState);
expect(dispatch).toHaveBeenCalledWith({ type: types.INCREMENT_COUNTER });
});

it('incrementIfOdd shouldnt create increment action if counter is even', () => {
let fn = actions.incrementIfOdd();
let dispatch = expect.createSpy();
let getState = () => ({ counter: 2 });
fn(dispatch, getState);
expect(dispatch.calls.length).toBe(0);
});

// There's no nice way to test this at the moment...
it('incrementAsync', (done) => {
let fn = actions.incrementAsync(1);
expect(fn).toBeA('function');
let dispatch = expect.createSpy();
fn(dispatch);
setTimeout(() => {
expect(dispatch).toHaveBeenCalledWith({ type: types.INCREMENT_COUNTER });
done();
}, 5);
});
});

57 changes: 57 additions & 0 deletions examples/counter/test/components/Counter.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import expect from 'expect';
import jsdomReact from '../jsdomReact';
import React from 'react/addons';
import Counter from '../../components/Counter';

const { TestUtils } = React.addons;

function setup() {
const actions = {
increment: expect.createSpy(),
incrementIfOdd: expect.createSpy(),
incrementAsync: expect.createSpy(),
decrement: expect.createSpy()
};
const component = TestUtils.renderIntoDocument(<Counter counter={1} {...actions} />);
return {
component: component,
actions: actions,
buttons: TestUtils.scryRenderedDOMComponentsWithTag(component, 'button').map(button => {
return button.getDOMNode();
}),
p: TestUtils.findRenderedDOMComponentWithTag(component, 'p').getDOMNode()
};
}

describe('Counter component', () => {
jsdomReact();

it('should display count', () => {
const { p } = setup();
expect(p.textContent).toMatch(/^Clicked: 1 times/);
});

it('first button should call increment', () => {
const { buttons, actions } = setup();
TestUtils.Simulate.click(buttons[0]);
expect(actions.increment).toHaveBeenCalled();
});

it('second button should call decrement', () => {
const { buttons, actions } = setup();
TestUtils.Simulate.click(buttons[1]);
expect(actions.decrement).toHaveBeenCalled();
});

it('third button should call incrementIfOdd', () => {
const { buttons, actions } = setup();
TestUtils.Simulate.click(buttons[2]);
expect(actions.incrementIfOdd).toHaveBeenCalled();
});

it('fourth button should call incrementAsync', () => {
const { buttons, actions } = setup();
TestUtils.Simulate.click(buttons[3]);
expect(actions.incrementAsync).toHaveBeenCalled();
});
});
60 changes: 60 additions & 0 deletions examples/counter/test/containers/CounterApp.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import expect from 'expect';
import jsdomReact from '../jsdomReact';
import React from 'react/addons';
import { Provider } from 'react-redux';
import CounterApp from '../../containers/CounterApp';
import createCounterStore from '../../store/createCounterStore';

const { TestUtils } = React.addons;

function setup(initialState) {
const store = createCounterStore(initialState);
const app = TestUtils.renderIntoDocument(
<Provider store={store}>
{() => <CounterApp />}
</Provider>
);
return {
app: app,
buttons: TestUtils.scryRenderedDOMComponentsWithTag(app, 'button').map(button => {
return button.getDOMNode();
}),
p: TestUtils.findRenderedDOMComponentWithTag(app, 'p').getDOMNode()
};
}

describe('containers', () => {
jsdomReact();

describe('App', () => {

it('should display initial count', () => {
const { p } = setup();
expect(p.textContent).toMatch(/^Clicked: 0 times/);
});

it('should display updated count after increment button click', () => {
const { buttons, p } = setup();
TestUtils.Simulate.click(buttons[0]);
expect(p.textContent).toMatch(/^Clicked: 1 times/);
});

it('should display updated count after descrement button click', () => {
const { buttons, p } = setup();
TestUtils.Simulate.click(buttons[1]);
expect(p.textContent).toMatch(/^Clicked: -1 times/);
});

it('shouldnt change if even and if odd button clicked', () => {
const { buttons, p } = setup();
TestUtils.Simulate.click(buttons[2]);
expect(p.textContent).toMatch(/^Clicked: 0 times/);
});

it('should change if odd and if odd button clicked', () => {
const { buttons, p } = setup({ counter: 1 });
TestUtils.Simulate.click(buttons[2]);
expect(p.textContent).toMatch(/^Clicked: 2 times/);
});
});
});
7 changes: 7 additions & 0 deletions examples/counter/test/jsdomReact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ExecutionEnvironment from 'react/lib/ExecutionEnvironment';
import jsdom from 'mocha-jsdom';

export default function jsdomReact() {
jsdom();
ExecutionEnvironment.canUseDOM = true;
}
24 changes: 24 additions & 0 deletions examples/counter/test/reducers/counter.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import expect from 'expect';
import counter from '../../reducers/counter';
import { INCREMENT_COUNTER, DECREMENT_COUNTER } from '../../constants/ActionTypes';

describe('reducers', () => {
describe('counter', () => {

it('should handle initial state', () => {
expect(counter(undefined, {})).toBe(0);
});

it('should handle INCREMENT_COUNTER', () => {
expect(counter(1, { type: INCREMENT_COUNTER })).toBe(2);
});

it('should handle DECREMENT_COUNTER', () => {
expect(counter(1, { type: DECREMENT_COUNTER })).toBe(0);
});

it('should handle unknown action type', () => {
expect(counter(1, { type: 'unknown' })).toBe(1);
});
});
});
7 changes: 6 additions & 1 deletion examples/todomvc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "TodoMVC example for redux",
"main": "server.js",
"scripts": {
"start": "node server.js"
"start": "node server.js",
"test": "mocha --recursive --compilers js:babel/register"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -36,6 +37,10 @@
"devDependencies": {
"babel-core": "^5.6.18",
"babel-loader": "^5.1.4",
"expect": "^1.8.0",
"jsdom": "^5.6.1",
"mocha": "^2.2.5",
"mocha-jsdom": "^1.0.0",
"node-libs-browser": "^0.5.2",
"raw-loader": "^0.5.1",
"react-hot-loader": "^1.2.7",
Expand Down
48 changes: 48 additions & 0 deletions examples/todomvc/test/actions/TodoActions.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import expect from 'expect';
import * as types from '../../constants/ActionTypes';
import * as actions from '../../actions/TodoActions';

describe('todo actions', () => {

it('addTodo should create ADD_TODO action', () => {
expect(actions.addTodo('Use Redux')).toEqual({
type: types.ADD_TODO,
text: 'Use Redux'
});
});

it('deleteTodo should create DELETE_TODO action', () => {
expect(actions.deleteTodo(1)).toEqual({
type: types.DELETE_TODO,
id: 1
});
});

it('editTodo should create EDIT_TODO action', () => {
expect(actions.editTodo(1, 'Use Redux everywhere')).toEqual({
type: types.EDIT_TODO,
id: 1,
text: 'Use Redux everywhere'
});
});

it('markTodo should create MARK_TODO action', () => {
expect(actions.markTodo(1)).toEqual({
type: types.MARK_TODO,
id: 1
});
});

it('markAll should create MARK_ALL action', () => {
expect(actions.markAll()).toEqual({
type: types.MARK_ALL
});
});

it('clearMarked should create CLEAR_MARKED action', () => {
expect(actions.clearMarked('Use Redux')).toEqual({
type: types.CLEAR_MARKED
});
});
});

Loading