Skip to content

Commit 2fdbca0

Browse files
committed
Test only public API and use better test data
1 parent 6aa4431 commit 2fdbca0

16 files changed

+143
-203
lines changed

test/components/Connector.spec.js renamed to test/Connector.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// import expect from 'expect';
2-
// import { Connector } from '../../src';
2+
// import { Connector } from '../src';
33

44
describe('Components', () => {
55
describe('Connector', () => {

test/components/Provider.spec.js renamed to test/Provider.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// import expect from 'expect';
2-
// import { Provider } from '../../src';
2+
// import { Provider } from '../src';
33

44
describe('Components', () => {
55
describe('Provider', () => {

test/Redux.spec.js

Lines changed: 0 additions & 61 deletions
This file was deleted.

test/_helpers.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const ADD_TODO = 'ADD_TODO';
2+
const ADD_TODO_ASYNC = 'ADD_TODO_ASYNC';
3+
4+
export const initialState = [];
5+
export const defaultText = 'Hello World!';
6+
export const constants = { ADD_TODO, ADD_TODO_ASYNC };
7+
8+
export function todoStore(state = initialState, action) {
9+
const { type } = action;
10+
if (type === ADD_TODO || type === ADD_TODO_ASYNC) {
11+
return [{
12+
id: state[0] ? state[0].id + 1 : 1,
13+
text: action.text
14+
}, ...state];
15+
}
16+
return state;
17+
}
18+
19+
export const todoActions = {
20+
addTodo(text) {
21+
return { type: ADD_TODO, text };
22+
},
23+
24+
addTodoAsync(text, cb/* for testing only */) {
25+
return dispatch => {
26+
setTimeout(() => {
27+
dispatch({ type: ADD_TODO_ASYNC, text });
28+
cb();
29+
}, 500);
30+
};
31+
}
32+
};

test/bindActionCreators.spec.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import expect from 'expect';
2+
import { bindActionCreators, createRedux } from '../src';
3+
import * as helpers from './_helpers';
4+
5+
const { todoActions, todoStore } = helpers;
6+
7+
describe('Utils', () => {
8+
describe('bindActionCreators', () => {
9+
10+
let redux;
11+
12+
beforeEach(() => {
13+
redux = createRedux({ todoStore });
14+
});
15+
16+
it('should bind given actions to the dispatcher', done => {
17+
let expectedCallCount = 2;
18+
// just for monitoring the dispatched actions
19+
redux.subscribe(() => {
20+
expectedCallCount--;
21+
if (expectedCallCount === 0) {
22+
const state = redux.getState();
23+
expect(state.todoStore).toEqual([
24+
{ id: 2, text: 'World' },
25+
{ id: 1, text: 'Hello' }
26+
]);
27+
done();
28+
}
29+
});
30+
const actions = bindActionCreators(todoActions, redux.dispatch);
31+
expect(Object.keys(actions)).toEqual(Object.keys(todoActions));
32+
33+
actions.addTodo('Hello');
34+
actions.addTodoAsync('World');
35+
});
36+
});
37+
});

test/compose.spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// import expect from 'expect';
2+
// import { compose } from '../src';
3+
4+
describe('Utils', () => {
5+
describe('compose', () => {
6+
7+
it('should call map stores');
8+
});
9+
});

test/utils/composeStores.spec.js renamed to test/composeStores.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// import expect from 'expect';
2-
// import { composeStores } from '../../src';
2+
// import { composeStores } from '../src';
33

44
describe('Utils', () => {
55
describe('composeStores', () => {

test/components/connect.spec.js renamed to test/connect.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// import expect from 'expect';
2-
// import { connect } from '../../src';
2+
// import { connect } from '../src';
33

44
describe('Decorators', () => {
55
describe('connect', () => {

test/createDispatcher.spec.js

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,40 @@
11
import expect from 'expect';
22
import { createDispatcher, composeStores } from '../src';
33
import thunkMiddleware from '../src/middleware/thunk';
4+
import * as helpers from './_helpers';
45

5-
const fakeState = { foo: 'bar' };
6-
const fakeAction = { type: 'FOO', foo: 'bar' };
7-
const fakeActionAsync = { type: 'FOO_ASYNC', fooAsync: 'barAsync' };
8-
9-
function fakeStore(state = fakeState, action) {
10-
const { type } = action;
11-
if (type === 'FOO') {
12-
return action.foo;
13-
}
14-
if (type === 'FOO_ASYNC') {
15-
return action.fooAsync;
16-
}
17-
return state;
18-
}
19-
20-
function foo() {
21-
return fakeAction;
22-
}
23-
24-
function fooAsync(cb/* for testing only */) {
25-
return dispatch => {
26-
setTimeout(() => {
27-
dispatch(fakeActionAsync);
28-
cb();
29-
}, 500);
30-
};
31-
}
6+
const { constants, defaultText, todoActions, todoStore } = helpers;
7+
const { addTodo, addTodoAsync } = todoActions;
8+
const { ADD_TODO } = constants;
329

3310
describe('createDispatcher', () => {
3411

3512
it('should handle sync and async dispatches', done => {
3613
const spy = expect.createSpy(() => {});
3714
const dispatcher = createDispatcher(
38-
composeStores({ fakeStore }),
15+
composeStores({ todoStore }),
16+
// we need this middleware to handle async actions
3917
getState => [thunkMiddleware(getState)]);
18+
4019
expect(dispatcher).toBeA('function');
4120

42-
const dispatchFn = dispatcher(fakeState, spy);
43-
expect(spy).toHaveBeenCalledWith({ fakeStore: fakeState });
21+
const dispatchFn = dispatcher(undefined, spy);
22+
expect(spy.calls.length).toBe(1);
23+
expect(spy).toHaveBeenCalledWith({ todoStore: [] });
4424

45-
const fooAction = dispatchFn(foo());
46-
expect(fooAction).toEqual(fakeAction);
25+
const addTodoAction = dispatchFn(addTodo(defaultText));
26+
expect(addTodoAction).toEqual({ type: ADD_TODO, text: defaultText });
4727
expect(spy.calls.length).toBe(2);
48-
expect(spy).toHaveBeenCalledWith({ fakeStore: 'bar' });
28+
expect(spy).toHaveBeenCalledWith({ todoStore: [
29+
{ id: 1, text: defaultText }
30+
] });
4931

50-
dispatchFn(fooAsync(() => {
32+
dispatchFn(addTodoAsync(('Say hi!'), () => {
5133
expect(spy.calls.length).toBe(3);
52-
expect(spy).toHaveBeenCalledWith({ fakeStore: 'barAsync' });
34+
expect(spy).toHaveBeenCalledWith({ todoStore: [
35+
{ id: 2, text: 'Say hi!' },
36+
{ id: 1, text: defaultText }
37+
] });
5338
done();
5439
}));
5540
});

test/createRedux.spec.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import expect from 'expect';
22
import { createRedux } from '../src';
3+
import * as helpers from './_helpers';
34

4-
const fakeState = { foo: 'bar' };
5-
6-
function fakeStore() {
7-
return fakeState;
8-
}
5+
const { defaultText, todoActions, todoStore } = helpers;
6+
const { addTodo } = todoActions;
97

108
describe('createRedux', () => {
119

10+
let redux;
11+
12+
beforeEach(() => {
13+
redux = createRedux({ todoStore });
14+
});
15+
1216
it('should expose Redux public API', () => {
13-
const redux = createRedux({ fakeStore });
1417
const methods = Object.keys(redux);
1518

1619
expect(methods.length).toBe(5);
@@ -20,4 +23,34 @@ describe('createRedux', () => {
2023
expect(methods).toContain('getDispatcher');
2124
expect(methods).toContain('replaceDispatcher');
2225
});
26+
27+
it('should subscribe to changes', done => {
28+
let state = redux.getState();
29+
expect(state.todoStore).toEqual({});
30+
redux.subscribe(() => {
31+
state = redux.getState();
32+
expect(state.todoStore).toEqual([{ id: 1, text: 'Hello World!' }]);
33+
done();
34+
});
35+
redux.dispatch(addTodo(defaultText));
36+
});
37+
38+
it('should unsubscribe a listener', () => {
39+
const changeListenerSpy = expect.createSpy(() => {});
40+
const unsubscribe = redux.subscribe(changeListenerSpy);
41+
42+
expect(changeListenerSpy.calls.length).toBe(0);
43+
44+
redux.dispatch(addTodo('Hello'));
45+
expect(redux.getState().todoStore).toEqual([{ id: 1, text: 'Hello'}]);
46+
expect(changeListenerSpy.calls.length).toBe(1);
47+
48+
unsubscribe();
49+
redux.dispatch(addTodo('World'));
50+
expect(redux.getState().todoStore).toEqual([
51+
{ id: 2, text: 'World'},
52+
{ id: 1, text: 'Hello'}
53+
]);
54+
expect(changeListenerSpy.calls.length).toBe(1);
55+
});
2356
});

test/exports.spec.js

Lines changed: 0 additions & 24 deletions
This file was deleted.

test/utils/getDisplayName.spec.js renamed to test/getDisplayName.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import expect from 'expect';
2-
import getDisplayName from '../../src/utils/getDisplayName';
2+
import getDisplayName from '../src/utils/getDisplayName';
33

44
describe('Utils', () => {
55
describe('getDisplayName', () => {

test/components/provide.spec.js renamed to test/provide.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// import expect from 'expect';
2-
// import { provide } from '../../src';
2+
// import { provide } from '../src';
33

44
describe('Decorators', () => {
55
describe('provide', () => {

0 commit comments

Comments
 (0)