Skip to content

Commit

Permalink
Merge pull request #3 from colebillys19/rithm-testing
Browse files Browse the repository at this point in the history
Async Action Creators Testing (#6)
  • Loading branch information
misscoded authored Jun 20, 2019
2 parents 0604522 + c012db2 commit 350dd64
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 11 deletions.
132 changes: 131 additions & 1 deletion src/actions/action-creators.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,58 @@ import * as types from '../constants/action-types';
import thunkMiddleware from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import panes from '../constants/pane-types';
import { initializeCalculator } from '../lib/calculator';

const middlewares = [thunkMiddleware];
const mockStore = configureMockStore(middlewares);

const initialState = {
images: {
frames: {},
frameIDs: [],
gifProgress: 0,
gifData: '',
caption: '',
fontColor: '#000000',
gifFileName: ''
},
settings: {
image: {
width: 300,
height: 300,
interval: 100,
oversample: false
},
bounds: {
left: -10,
right: 10,
bottom: -10,
top: 10
},
strategy: 'contain'
},
ui: {
expandedPane: panes.NONE,
previewIdx: 0,
playing: false,
error: ''
}
};

const desmosMock = {
GraphingCalculator: jest.fn(() => {
return {
asyncScreenshot: (opts, cb) => cb(''),
getExpressions: () => [{ id: 1, latex: 'x = 3' }, { id: 2, latex: '' }],
setExpression: () => null
};
})
};

const calcContainerMock = { current: undefined };

// Tests

describe('Action creators', () => {
describe('synchronous action creators', () => {
it('return an action to add a frame', () => {
Expand Down Expand Up @@ -127,6 +175,88 @@ describe('Action creators', () => {
});

describe('async action creators', () => {
// TODO
let store;

beforeEach(() => {
store = mockStore(initialState);
});

it('return an action to temporarily display error message', () => {
jest.useFakeTimers();
const expectedActions = [
{ type: types.SET_ERROR, payload: { message: 'error' } },
{ type: types.CLEAR_ERROR }
];
store.dispatch(actions.flashError('error'));
jest.runAllTimers();
expect(store.getActions()).toEqual(expectedActions);
});

it('return an action to request a frame from the calculator', () => {
const expectedActions = [
{
type: types.ADD_FRAME,
payload: { id: 2, imageData: expect.any(String) }
}
];
const opts = {
height: 300,
targetPixelRatio: 1,
width: 300
};
initializeCalculator(desmosMock, calcContainerMock);
return store.dispatch(actions.requestFrame(opts)).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});

it('return an action to request a burst of frames from the calculator', () => {
const opts = {
height: 300,
idx: 1,
max: 3,
min: -3,
oversample: false,
step: 1,
width: 300
};
initializeCalculator(desmosMock, calcContainerMock);
return store.dispatch(actions.requestBurst(opts)).then(() => {
// slide with min/max of -3/3 should dispatch addFrame 7 times
expect(store.getActions().length).toEqual(7);
});
});

it('return actions to play animation via frames in state', () => {
const expectedActions = [
{ type: types.PLAY_PREVIEW },
{ type: types.UPDATE_PREVIEW_IDX, payload: { idx: 1 } }
];
store.dispatch(actions.startAnimation());
expect(store.getActions()).toEqual(expectedActions);
});

it('return action to generate a GIF via frames in state', () => {
const expectedActions = [
{ type: types.UPDATE_GIF_PROGRESS, payload: { progress: 100 } },
{ type: types.ADD_GIF, payload: { imageData: expect.any(String) } }
];
const opts = {
gifHeight: 300,
gifWidth: 300,
images: ['img1', 'img2', 'img3'],
interval: 0.1,
progressCallback: jest.fn()
};
// gifshot mock
const gifshot = {
createGIF: (args, cb) => {
args.progressCallback(100);
return cb({ image: 'test' });
}
};
store.dispatch(actions.generateGIF([], opts, gifshot));
expect(store.getActions()).toEqual(expectedActions);
});
});
});
7 changes: 5 additions & 2 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,10 @@ export const startAnimation = () => (dispatch, getState) => {

// The gifshot library is loaded in index.html
const gifshot = window.gifshot;
export const generateGIF = (images, opts) => (dispatch, getState) => {
export const generateGIF = (images, opts, gifMaker = gifshot) => (
dispatch,
getState
) => {
// Have to check state interval and not opts because opts is in seconds
const { interval } = getState().settings.image;
const settingsErrors = getSettingsErrors({ interval });
Expand All @@ -245,7 +248,7 @@ export const generateGIF = (images, opts) => (dispatch, getState) => {
...opts,
progressCallback: progress => dispatch(updateGIFProgress(progress))
};
gifshot.createGIF(gifshotArgs, data => {
gifMaker.createGIF(gifshotArgs, data => {
if (data.error) {
dispatch(flashError(gifCreationProblem()));
} else {
Expand Down
8 changes: 2 additions & 6 deletions src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import SettingsContainer from '../containers/SettingsContainer';
import FolderContainer from '../containers/FolderContainer';
import ErrorToastContainer from '../containers/ErrorToastContainer';
import CALCULATOR_OPTIONS from '../constants/calculator-options';
import { initializeCalculator } from '../lib/calculator';
import './App.css';

// The Desmos API is loaded in index.html
const Desmos = window.Desmos;
const calcContainer = React.createRef();
export let calculator;

class App extends Component {
constructor(props) {
Expand All @@ -26,11 +26,7 @@ class App extends Component {
}

componentDidMount() {
calculator = Desmos.GraphingCalculator(
calcContainer.current,
CALCULATOR_OPTIONS
);

initializeCalculator(Desmos, calcContainer, CALCULATOR_OPTIONS);
window.addEventListener('keydown', this.handleKeyDown);
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/calc-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* and concise.
*/

import { calculator } from '../components/App';
import { calculator } from './calculator';
import { noSuchExpression, notASlider } from './error-messages';
import { saveGraphToLocal, getGraphFromLocal } from './local-storage-helpers';

Expand Down
9 changes: 9 additions & 0 deletions src/lib/calculator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let calculator;

function initializeCalculator(desmos, calcContainer, calcOptions) {
calculator = desmos.GraphingCalculator(calcContainer.current, calcOptions);
window.calculator = calculator;
return calculator;
}

export { calculator, initializeCalculator };
5 changes: 4 additions & 1 deletion src/reducers/images.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ const initialState = {
frames: {},
frameIDs: [],
gifProgress: 0,
gifData: ''
gifData: '',
caption: '',
fontColor: '#000000',
gifFileName: ''
};

describe('reducers', () => {
Expand Down
Empty file added src/setupFiles.js
Empty file.

0 comments on commit 350dd64

Please sign in to comment.