Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
robbymurphy authored and Robert Murphy committed Oct 19, 2017
1 parent a1dadc9 commit c16063a
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 18 deletions.
11 changes: 6 additions & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
module.exports = {
extends: 'airbnb-base',
plugins: ['import'],
extends: "airbnb-base",
plugins: ["import"],
env: {
jest: true,
jest: true
},
rules: {
'no-underscore-dangle': 'off',
},
"no-underscore-dangle": "off",
"linebreak-style": 0
}
};
2 changes: 1 addition & 1 deletion src/Actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function wrapAction(obj, actionName) {
type: actionId,
payload: null,
});
actionResult
return actionResult
.then(data =>
dispatch({
type: `${actionId}_SUCCESS`,
Expand Down
54 changes: 53 additions & 1 deletion src/Actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class TestActions extends Actions {
action2() {
return 'test2';
}
asyncAction(promise) {
return promise;
}
}
/* eslint-enable class-methods-use-this */

Expand Down Expand Up @@ -41,8 +44,57 @@ describe('Actions', () => {
const actionFunctions = Actions.getAllActionFunctions(testActions);

// Assert
expect(actionFunctions.length).toEqual(2);
expect(actionFunctions.length).toEqual(3);
expect(actionFunctions[0]).toEqual('action1');
expect(actionFunctions[1]).toEqual('action2');
expect(actionFunctions[2]).toEqual('asyncAction');
});
it('dispatches async method events on success', (done) => {
// Arrange
const testActions = new TestActions();
const dispatch = jest.fn();
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve('asyncTest');
}, 0);
});
const asyncAction = testActions.asyncAction(promise);

// Act
asyncAction(dispatch).then(() => {
// Assert
expect(dispatch.mock.calls.length).toBe(2);
expect(dispatch.mock.calls[0][0]).toEqual({ type: 'TestActions.asyncAction', payload: null });
expect(dispatch.mock.calls[1][0]).toEqual({
type: 'TestActions.asyncAction_SUCCESS',
payload: 'asyncTest',
});
done();
});
});
it('dispatches async method events on error', (done) => {
// Arrange
const testActions = new TestActions();
const dispatch = jest.fn();
const error = new Error('asyncTest');
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(error);
}, 0);
});
const asyncAction = testActions.asyncAction(promise);

// Act
asyncAction(dispatch).then(() => {
// Assert
expect(dispatch.mock.calls.length).toBe(2);
expect(dispatch.mock.calls[0][0]).toEqual({ type: 'TestActions.asyncAction', payload: null });
expect(dispatch.mock.calls[1][0]).toEqual({
type: 'TestActions.asyncAction_ERROR',
payload: error,
error: true,
});
done();
});
});
});
21 changes: 12 additions & 9 deletions src/Reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,23 @@ class Reducer {
}

reduceAsync(asyncActionFn, reduceBeforeFn, reduceSuccessFn, reduceErrorFn) {
this.reducers.push(
{
/* eslint-disable no-unused-expressions */
reduceBeforeFn &&
this.reducers.push({
actionType: asyncActionFn.__jiveId,
reducerFn: reduceBeforeFn,
},
{
});
reduceSuccessFn &&
this.reducers.push({
actionType: `${asyncActionFn.__jiveId}_SUCCESS`,
reducerFn: reduceSuccessFn,
},
{
});
reduceErrorFn &&
this.reducers.push({
actionType: `${asyncActionFn.__jiveId}_ERROR`,
reducerFn: reduceErrorFn,
},
);
});
/* eslint-enable no-unused-expressions */
}

build() {
Expand All @@ -37,7 +40,7 @@ class Reducer {
let newState = state;
for (let i = 0; i < reducers.length; i += 1) {
const reducer = reducers[i];
if (reducer.reducerFn && action.type === reducer.actionType) {
if (action.type === reducer.actionType) {
newState = reducer.reducerFn(newState, action.payload);
} else if (state === undefined) {
newState = defaultValue;
Expand Down
30 changes: 29 additions & 1 deletion src/Reducer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class TestActions extends Actions {
action3() {
return 'test3';
}
asyncAction() {}
}

const testActions = new TestActions();
Expand All @@ -22,6 +23,12 @@ class TestReducer extends Reducer {

this.reduce(testActions.action1, this.handleAction1);
this.reduce(testActions.action2, this.handleAction2);
this.reduceAsync(
testActions.asyncAction,
this.handleBeforeAsync,
this.handleAsyncSuccess,
this.handleAsyncFailure,
);
}

handleAction1(state, payload) {
Expand All @@ -30,6 +37,15 @@ class TestReducer extends Reducer {
handleAction2(state, payload) {
return `${payload}_new2`;
}
handleBeforeAsync() {
this.beforeCalled = true;
}
handleAsyncSuccess(data) {
this.successData = data;
}
handleAsyncFailure(err) {
this.asyncError = err;
}
}
/* eslint-enable class-methods-use-this, no-useless-constructor */

Expand All @@ -43,7 +59,7 @@ describe('Reducer', () => {
const testReducer = new TestReducer('test');

// Assert
expect(testReducer.reducers.length).toEqual(2);
expect(testReducer.reducers.length).toEqual(5);
expect(testReducer.reducers[0]).toEqual({
actionType: 'TestActions.action1',
reducerFn: testReducer.handleAction1,
Expand All @@ -52,6 +68,18 @@ describe('Reducer', () => {
actionType: 'TestActions.action2',
reducerFn: testReducer.handleAction2,
});
expect(testReducer.reducers[2]).toEqual({
actionType: 'TestActions.asyncAction',
reducerFn: testReducer.handleBeforeAsync,
});
expect(testReducer.reducers[3]).toEqual({
actionType: 'TestActions.asyncAction_SUCCESS',
reducerFn: testReducer.handleAsyncSuccess,
});
expect(testReducer.reducers[4]).toEqual({
actionType: 'TestActions.asyncAction_ERROR',
reducerFn: testReducer.handleAsyncFailure,
});
});
describe('Built Reducer', () => {
it('returns default value when state null', () => {
Expand Down
34 changes: 34 additions & 0 deletions src/asyncMiddleware.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import asyncMiddleware from './asyncMiddleware';

describe('asyncMiddleware', () => {
it('should call the action result when action is a function', () => {
// Arrange
const middleWare = asyncMiddleware({ dispatch: {}, getState: {} });
const next = () => {};
let actionWasCalled = false;
const action = () => {
actionWasCalled = true;
};

// Act
middleWare(next)(action);

// Assert
expect(actionWasCalled).toBe(true);
});
it('should call next when action is not a function', () => {
// Arrange
const middleWare = asyncMiddleware({ dispatch: {}, getState: {} });
let nextWasCalled = false;
const next = () => {
nextWasCalled = true;
};
const action = {};

// Act
middleWare(next)(action);

// Assert
expect(nextWasCalled).toBe(true);
});
});
2 changes: 1 addition & 1 deletion webpack.prod.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ config.plugins.push(
}),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: '"production"' },
}),
})
);

module.exports = config;

0 comments on commit c16063a

Please sign in to comment.