From 6c2475679e379b69570b36d3723b7b4a6b358cc5 Mon Sep 17 00:00:00 2001 From: Sander Mets Date: Sat, 10 Feb 2018 17:37:29 +0200 Subject: [PATCH 1/3] store test done --- README.md | 3 +- index.js | 1 + src/create.js | 14 ++++++ src/templates/store | 62 +++++++++++++++---------- src/templates/store.test | 98 +++++++++++++++++++++++++++++++--------- 5 files changed, 132 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 44ac102..e9f212b 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,6 @@ Add the following lines to `package.json` for code coverage "collectCoverageFrom": [ "src/**/*.{js,jsx,mjs}", "!src/index.js", - "!src/store.js", "!src/registerServiceWorker.js" ], "coverageThreshold": { @@ -118,7 +117,7 @@ Add the following lines to `package.json` for code coverage Run unit tests ```sh -yarn test +yarn test --coverage ``` Run diff --git a/index.js b/index.js index e0c821d..e58cdf4 100644 --- a/index.js +++ b/index.js @@ -34,6 +34,7 @@ if (taskArg === 'create' && typeArg === 'firstcontainer') { create.rootSagaJs(nameArg); create.rootSagaTestJs(nameArg); create.storeJs(nameArg); + create.storeTestJs(nameArg); create.navigatorJs(nameArg); create.navigatorTestJs(nameArg); create.appJs(nameArg); diff --git a/src/create.js b/src/create.js index 47f8f9f..5367545 100644 --- a/src/create.js +++ b/src/create.js @@ -252,6 +252,20 @@ async function storeJs(name) { } module.exports.storeJs = storeJs; +async function storeTestJs(name) { + try { + const filePath = path.join(pwd, 'src', '__tests__', 'store.test.js'); + await fs.copy( + path.join(cliDir, 'templates', 'store.test'), + filePath, + ); + await replacePlaceHolders(filePath, name); + } catch (error) { + console.error(error); + } +} +module.exports.storeTestJs = storeTestJs; + async function navigatorJs(name) { try { const filePath = path.join(pwd, 'src', 'Navigator.js'); diff --git a/src/templates/store b/src/templates/store index c5e972e..6849b43 100644 --- a/src/templates/store +++ b/src/templates/store @@ -5,50 +5,66 @@ import createHistory from 'history/createBrowserHistory'; // eslint-disable-line import rootReducer from './rootReducer'; import rootSaga from './rootSaga'; -export const storeElements = { +export const rdx = { + initialState: {}, + enhancers: [], history: undefined, store: undefined, -}; + createHistory, + sagaMiddleware: undefined, + createSagaMiddleware, + middleware: undefined, + routerMiddleware, + appliedMiddleware: undefined, + compose, + composedEnhancers: undefined, + applyMiddleware, + createStore, + rootReducer, + rootSaga, +} export default function configureStore() { - storeElements.history = createHistory(); - - const initialState = {}; - const enhancers = []; - const sagaMiddleware = createSagaMiddleware(); - const middleware = [ - sagaMiddleware, - routerMiddleware(storeElements.history), + rdx.history = rdx.createHistory(); + + rdx.sagaMiddleware = rdx.createSagaMiddleware(); + rdx.middleware = [ + rdx.sagaMiddleware, + rdx.routerMiddleware(rdx.history), ]; if (process.env.NODE_ENV === 'development') { const { devToolsExtension } = window; if (typeof devToolsExtension === 'function') { - enhancers.push(devToolsExtension()); + rdx.enhancers.push(devToolsExtension()); } } - const composedEnhancers = compose( - applyMiddleware(...middleware), - ...enhancers, + rdx.appliedMiddleware = rdx.applyMiddleware(...rdx.middleware); + rdx.composedEnhancers = rdx.compose( + rdx.appliedMiddleware, + ...rdx.enhancers, ); - storeElements.store = createStore( - rootReducer(), - initialState, - composedEnhancers, + rdx.store = rdx.createStore( + rdx.rootReducer(), + rdx.initialState, + rdx.composedEnhancers, ); - sagaMiddleware.run(rootSaga); + rdx.sagaMiddleware.run(rdx.rootSaga); } +rdx.configureStore = configureStore; export function getStore() { - if(!storeElements.store) { - configureStore(); + if (!rdx.store) { + rdx.configureStore(); } - return storeElements.store; + return rdx.store; } +rdx.getStore = getStore; export function getHistory() { - return storeElements.history; + return rdx.history; } +rdx.getHistory = getHistory; diff --git a/src/templates/store.test b/src/templates/store.test index e5daf22..317f54d 100644 --- a/src/templates/store.test +++ b/src/templates/store.test @@ -1,30 +1,86 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import config from '../config'; -import configureStore, { getStore } from '../store'; +import { rdx, getStore, getHistory } from '../store'; // yarn test ./src/__tests__/store.test.js --coverage describe('getStore', () => { - it('returns store', () => { - configureStore(); - const store = getStore(); - expect(typeof store.dispatch).toEqual('function'); - expect(typeof store.subscribe).toEqual('function'); - expect(typeof store.getState).toEqual('function'); + it('creates store', () => { + rdx.configureStore(); + rdx.getStore(); + expect(typeof rdx.store.dispatch).toEqual('function'); + expect(typeof rdx.store.subscribe).toEqual('function'); + expect(typeof rdx.store.getState).toEqual('function'); }); - it('adds devToolsExtension to enhanchers if NODE_ENV is development', () => { - // process.env.NODE_ENV = 'development'; - // Object.defineProperty(window, 'devToolsExtension', { - // writable: true, - // value: jest.fn(), - // }); - // configureStore(); - // const devToolsExtension = jest.fn() - // window.devToolsExtension = devToolsExtension; - // getStore(); - - // expect(window.devToolsExtension).toHaveBeenCalled(); - // process.env.NODE_ENV = env; + it('calls all required methods to create store in "development" environment', () => { + const prevEnv = process.env.NODE_ENV; + process.env.NODE_ENV = 'development'; + Object.defineProperty(window, 'devToolsExtension', { + writable: true, + value: jest.fn(), + }); + const historyMock = 'history'; + rdx.createHistory = jest.fn().mockReturnValue(historyMock); + rdx.createSagaMiddleware = jest.fn().mockReturnValue({ run: jest.fn() }); + rdx.routerMiddleware = jest.fn(); + rdx.applyMiddleware = jest.fn(); + rdx.compose = jest.fn(); + rdx.createStore = jest.fn(); + rdx.rootReducer = jest.fn(); + rdx.rootSaga = jest.fn(); + + rdx.configureStore(); + expect(rdx.createHistory).toHaveBeenCalled(); + expect(rdx.history).toEqual(historyMock); + expect(rdx.createSagaMiddleware).toHaveBeenCalled(); + expect(rdx.routerMiddleware).toHaveBeenCalled(); + + expect(window.devToolsExtension).toHaveBeenCalled(); + + expect(rdx.applyMiddleware).toHaveBeenCalled(); + expect(rdx.compose).toHaveBeenCalled(); + expect(rdx.createStore).toHaveBeenCalled(); + expect(rdx.sagaMiddleware.run).toHaveBeenCalled(); + process.env.NODE_ENV = prevEnv; + }); + + it('does not add devToolsExtension if it is not function', () => { + const prevEnv = process.env.NODE_ENV; + process.env.NODE_ENV = 'development'; + Object.defineProperty(window, 'devToolsExtension', { + writable: true, + value: 'foo', + }); + const historyMock = 'history'; + rdx.createHistory = jest.fn().mockReturnValue(historyMock); + rdx.createSagaMiddleware = jest.fn().mockReturnValue({ run: jest.fn() }); + rdx.routerMiddleware = jest.fn(); + rdx.applyMiddleware = jest.fn(); + rdx.compose = jest.fn(); + rdx.createStore = jest.fn(); + rdx.rootReducer = jest.fn(); + rdx.rootSaga = jest.fn(); + rdx.enhancers.push = jest.fn(); + rdx.configureStore(); + expect(rdx.enhancers.push).not.toHaveBeenCalled(); + process.env.NODE_ENV = prevEnv; + }); + + it('creates store if getStore being called and no store exists', () => { + rdx.configureStore = jest.fn(); + getStore(); + expect(rdx.configureStore).toHaveBeenCalled(); + }); + + it('does not create store if getStore being called and store exists', () => { + rdx.store = 'foo'; + rdx.configureStore = jest.fn(); + getStore(); + expect(rdx.configureStore).not.toHaveBeenCalled(); + }); + + it('returns history if getHistory is called', () => { + rdx.history = 'foo'; + expect(getHistory()).toEqual(rdx.history); }); }); From 68dd397cc7954dac2b19b68f89fb2160bbdbbc61 Mon Sep 17 00:00:00 2001 From: Sander Mets Date: Sat, 10 Feb 2018 17:47:04 +0200 Subject: [PATCH 2/3] change single test task --- src/templates/App.test | 2 +- src/templates/IndexComponent.test | 2 +- src/templates/index.test | 2 +- src/templates/navigator.test | 2 +- src/templates/reducer.test | 2 +- src/templates/rootReducer.test | 2 +- src/templates/rootSaga.test | 2 +- src/templates/sagas.test | 2 +- src/templates/selectors.test | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/templates/App.test b/src/templates/App.test index 5a7fd6c..3e9a993 100644 --- a/src/templates/App.test +++ b/src/templates/App.test @@ -2,7 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from '../App'; -// ./node_modules/.bin/jest ./src/__tests__/App.test.js --env=jsdom +// yarn test ./src/__tests__/App.test.js --coverage describe('', () => { it('renders without crashing', () => { const div = document.createElement('div'); diff --git a/src/templates/IndexComponent.test b/src/templates/IndexComponent.test index 915df2d..ca3cec3 100644 --- a/src/templates/IndexComponent.test +++ b/src/templates/IndexComponent.test @@ -5,7 +5,7 @@ import renderer from 'react-test-renderer'; import { mount } from 'enzyme'; import '' from '../'''; -// ./node_modules/.bin/jest ./src/containers/''/__tests__/''.test.js --env=jsdom +// yarn test ./src/containers/''/__tests__/''.test.js --coverage describe('<'' />', () => { const propsMock = { data: { foo: 'bar' }, diff --git a/src/templates/index.test b/src/templates/index.test index 60170ed..35e4aba 100644 --- a/src/templates/index.test +++ b/src/templates/index.test @@ -2,7 +2,7 @@ import * as actionType from '../actionTypes'; import '', { mapStateToProps, mapDispatchToProps } from '../index'; -// ./node_modules/.bin/jest ./src/containers/''/__tests__/index.test.js --env=jsdom +// yarn test ./src/containers/''/__tests__/index.test.js --coverage describe('<'' /> Connected', () => { it('should export default connected <'' />', () => { expect(''.displayName) diff --git a/src/templates/navigator.test b/src/templates/navigator.test index 331deb4..012eba9 100644 --- a/src/templates/navigator.test +++ b/src/templates/navigator.test @@ -4,7 +4,7 @@ import { shallow } from 'enzyme'; import Navigator from '../Navigator'; -// ./node_modules/.bin/jest ./src/__tests__/Navigator.test.js --env=jsdom +// yarn test ./src/__tests__/Navigator.test.js --coverage describe('', () => { it('has at least one route defined', () => { expect(shallow().find(Route).length) diff --git a/src/templates/reducer.test b/src/templates/reducer.test index 90be72d..4ecbb20 100644 --- a/src/templates/reducer.test +++ b/src/templates/reducer.test @@ -1,7 +1,7 @@ import ''Reducer from '../reducer'; import * as actionType from '../actionTypes'; -// ./node_modules/.bin/jest ./src/containers/''/__tests__/reducer.test.js --env=jsdom +// yarn test ./src/containers/''/__tests__/reducer.test.js --coverage describe('<'' /> reducer', () => { let state; beforeEach(() => { diff --git a/src/templates/rootReducer.test b/src/templates/rootReducer.test index aa654ce..071672b 100644 --- a/src/templates/rootReducer.test +++ b/src/templates/rootReducer.test @@ -1,6 +1,6 @@ import rootReducer from '../rootReducer'; -// ./node_modules/.bin/jest ./src/__tests__/rootReducer.test.js --env=jsdom +// yarn test ./src/__tests__/rootReducer.test.js --coverage describe('rootReducer', () => { it('exists', () => { expect(typeof rootReducer).toEqual('function'); diff --git a/src/templates/rootSaga.test b/src/templates/rootSaga.test index f20f905..d1abdd8 100644 --- a/src/templates/rootSaga.test +++ b/src/templates/rootSaga.test @@ -3,7 +3,7 @@ import { all } from 'redux-saga/effects'; import { watch''Sagas } from '../containers/''/sagas'; import rootSaga from '../rootSaga'; -// ./node_modules/.bin/jest ./src/__tests__/rootSaga.test.js --env=jsdom +// yarn test ./src/__tests__/rootSaga.test.js --coverage describe('rootSaga', () => { it('starts to watch Sagas', () => { const generator = rootSaga(); diff --git a/src/templates/sagas.test b/src/templates/sagas.test index 71bf2e9..50968bb 100644 --- a/src/templates/sagas.test +++ b/src/templates/sagas.test @@ -3,7 +3,7 @@ import axios from 'axios'; import { fetchDataAsync, watch''Sagas } from '../sagas'; import * as actionType from '../actionTypes'; -// ./node_modules/.bin/jest ./src/containers/''/__tests__/sagas.test.js --env=jsdom +// yarn test ./src/containers/''/__tests__/sagas.test.js --coverage describe('<'' /> sagas', () => { describe('fetchDataAsync', () => { it('ends with fetchDataSuccess if successful API call', () => { diff --git a/src/templates/selectors.test b/src/templates/selectors.test index bbc1a9c..ded7921 100644 --- a/src/templates/selectors.test +++ b/src/templates/selectors.test @@ -1,6 +1,6 @@ import { select'', makeSelectData } from '../selectors'; -// ./node_modules/.bin/jest ./src/containers/''/__tests__/selectors.test.js --env=jsdom +// yarn test ./src/containers/''/__tests__/selectors.test.js --coverage describe('<'' /> selectors', () => { describe('select''', () => { it('should select the '' state', () => { From 0928af652f8785e12272d28331c055d1f11a47d9 Mon Sep 17 00:00:00 2001 From: Sander Mets Date: Sat, 10 Feb 2018 17:50:35 +0200 Subject: [PATCH 3/3] 1.3.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a45eca3..ef87460 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cli-react-redux", - "version": "1.2.1", + "version": "1.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 30f13bb..74f9d8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cli-react-redux", - "version": "1.2.1", + "version": "1.3.0", "description": "React Redux CLI", "main": "index.js", "scripts": {