Skip to content

Commit d1ba407

Browse files
committed
Update template
1 parent f7a9d51 commit d1ba407

File tree

4 files changed

+128
-10
lines changed

4 files changed

+128
-10
lines changed

template/README.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
1-
# A quick start Redux Create React App template
1+
# A quick start Redux + TypeScript Create React App template
22

3-
An opinionated quick start [Create React App](https://github.com/facebook/create-react-app) (CRA) template with **Redux**, **TypeScript**, **React Router**, **Enzyme** and custom ESlint configuration.
3+
An opinionated quick start [Create React App](https://github.com/facebook/create-react-app) (CRA) _template_ with configured **Redux**, **TypeScript**, **React Router**, **Enzyme** and custom **ESlint** configuration.
44

55
Original Create React App README available [here](./README_CRA.md)
66

77
## Usage
88

9-
`npx create-react-app <your-project_name> --template typescript-redux`
9+
```bash
10+
npx create-react-app your-project-name --template typescript-redux
11+
```
1012

1113
Or
1214

13-
`yarn create react-app <your-project_name> --template typescript-redux`
15+
```bash
16+
yarn create react-app your-project-name --template typescript-redux
17+
```
1418

15-
`npx` command installs most recent stable version of CRA from npm. `--template` parameter points to this template, note that `cra-template-` prefix is omitted.
19+
`npx` command installs the most recent stable version of CRA from npm.
20+
21+
`--template` parameter points to this template, note that `cra-template-` prefix is omitted.
1622

1723
## Motivation
1824

19-
You know the pain. You start a new project and need to configure it again and again. It needs routing, ok you setup Router, then you need Redux - ok, oh. Wait... All of these tools you get used to. Redux boilerplate is taking some much to type. I want just to focus on building amazing projects and not spending hours configuring tools. That's why I've created this template. It's for you to use.
25+
You know the pain. You start a new project from scratch and need to configure it again and again. It needs routing, ok you setup Router, then you need Redux - ok, oh 😩Redux boilerplate is taking so much time to type. Wait... what if you could have all the tools you want just from the beginning? I want to focus on building amazing projects and not spending hours configuring. That's why I've created this template. It's here for you to use.
2026

2127
## Available Scripts
2228

@@ -38,21 +44,21 @@ Due to CRA template limitations (we can change only `scripts` and `dependencies`
3844

3945
## Redux configuration
4046

41-
Template provides basic Redux configuration with [feature based](https://redux.js.org/style-guide/style-guide/#structure-files-as-feature-folders-or-ducks) folder structure. You can use [Redux devtools browser extension](http://extension.remotedev.io/). Sample feature included in `src/features` folder, note technology agnostic `features` folder name. Based on Redux maintainers recommendation.
47+
The template provides basic Redux configuration with [feature based](https://redux.js.org/style-guide/style-guide/#structure-files-as-feature-folders-or-ducks) folder structure. You can use [Redux devtools browser extension](http://extension.remotedev.io/). Sample feature included in `src/features` folder, note technology agnostic `features` folder name. Based on Redux maintainers recommendation.
4248

4349
## Testing
4450

45-
Snapshot testing done with [Enzyme](https://airbnb.io/enzyme/).
51+
Testing is done with [Enzyme](https://airbnb.io/enzyme/).
4652

4753
## [Prettier](https://prettier.io/)
4854

4955
I added `prettier` to force consistent formatting. Don't like trailing semicolons? Feel free to [tweak prettier rules](https://prettier.io/docs/en/configuration.html) inside `.prettierrc` file to match your code style.
5056

5157
## Eslint configurations
5258

53-
Template extends CRA eslint rules with custom set, tailored for reasonable and clean development process.
59+
The template extends CRA ESLint rules with a custom set, tailored for the reasonable and clean development process.
5460

55-
Eslint rules are commented for your convenience feel free to tweak or remove them inside `.eslintrc`. No judgement.
61+
Eslint rules are commented for your convenience feel free to tweak or remove them inside `.eslintrc`. No judgment.
5662

5763
## Thank you
5864

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React from 'react'
2+
import { Provider } from 'react-redux'
3+
import { mount } from 'enzyme'
4+
import configureStore from 'redux-mock-store'
5+
6+
import { actionTypes } from '../../features/counter'
7+
import Counter from './Counter'
8+
9+
describe('Counter', () => {
10+
const mockStore = configureStore([])
11+
const store = mockStore({
12+
count: {
13+
value: 42,
14+
},
15+
})
16+
17+
// Add jest mock spy to watch for store.dispatch method. See https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname for more info
18+
jest.spyOn(store, 'dispatch')
19+
20+
beforeEach(() => {
21+
// Clear any saved mock data from previous tests, because jest saves calls data for spies and mocks, https://jestjs.io/docs/en/mock-function-api#mockfnmockclear
22+
store.dispatch.mockClear()
23+
})
24+
25+
it('renders without crashing.', () => {
26+
const wrapper = mount(
27+
<Provider store={store}>
28+
<Counter />
29+
</Provider>
30+
)
31+
32+
const countValue = wrapper.find('strong').text()
33+
expect(countValue).toBe('42')
34+
})
35+
36+
it('should be possible to increment counter.', () => {
37+
const wrapper = mount(
38+
<Provider store={store}>
39+
<Counter />
40+
</Provider>
41+
)
42+
43+
wrapper
44+
.find('button')
45+
.filter({ 'data-qa': 'increment-counter' })
46+
.simulate('click')
47+
48+
expect(store.dispatch).toBeCalledTimes(1)
49+
50+
expect(store.dispatch).toBeCalledWith({
51+
type: actionTypes.INCREMENT_COUNTER,
52+
})
53+
})
54+
55+
it('should be possible to decrement counter.', () => {
56+
const wrapper = mount(
57+
<Provider store={store}>
58+
<Counter />
59+
</Provider>
60+
)
61+
62+
wrapper
63+
.find('button')
64+
.filter({ 'data-qa': 'decrement-counter' })
65+
.simulate('click')
66+
67+
expect(store.dispatch).toHaveBeenCalledTimes(1)
68+
69+
expect(store.dispatch).toHaveBeenCalledWith({
70+
type: actionTypes.DECREMENT_COUNTER,
71+
})
72+
})
73+
})

template/src/components/counter/Counter.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const Counter: React.FC = () => {
2626
<button
2727
className="waves-effect waves-teal btn-flat blue"
2828
type="button"
29+
data-qa="decrement-counter"
2930
onClick={() =>
3031
dispatch({ type: actionTypes.DECREMENT_COUNTER })
3132
}
@@ -35,6 +36,7 @@ const Counter: React.FC = () => {
3536
<button
3637
className="waves-effect waves-teal btn-flat red"
3738
type="button"
39+
data-qa="increment-counter"
3840
onClick={() =>
3941
dispatch({ type: actionTypes.INCREMENT_COUNTER })
4042
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { INCREMENT_COUNTER, DECREMENT_COUNTER } from './actionTypes'
2+
import counterReducer from './counterReducer'
3+
import { CounterActionTypes } from './types'
4+
5+
describe('features > counter > counterReducer', () => {
6+
it(`increments value, if ${INCREMENT_COUNTER} action is provided`, () => {
7+
const initialState = {
8+
value: 0,
9+
}
10+
11+
const expectedState = {
12+
value: 1,
13+
}
14+
15+
const action: CounterActionTypes = {
16+
type: INCREMENT_COUNTER,
17+
}
18+
19+
expect(counterReducer(initialState, action)).toEqual(expectedState)
20+
})
21+
22+
it(`increments value, if ${DECREMENT_COUNTER} action is provided`, () => {
23+
const initialState = {
24+
value: 0,
25+
}
26+
27+
const expectedState = {
28+
value: -1,
29+
}
30+
31+
const action: CounterActionTypes = {
32+
type: DECREMENT_COUNTER,
33+
}
34+
35+
expect(counterReducer(initialState, action)).toEqual(expectedState)
36+
})
37+
})

0 commit comments

Comments
 (0)