Skip to content

Commit d12d7e5

Browse files
committed
add tools for testing
1 parent cefed38 commit d12d7e5

File tree

6 files changed

+1312
-28
lines changed

6 files changed

+1312
-28
lines changed

README.md

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,39 +46,46 @@ The `./dist/` folder is the root of the site. It is created by Webpack and conta
4646
npm run dev
4747
```
4848

49+
### Server-Side Rendering
50+
4951
`./src` contains `App.tsx`, which is the entry point of the React app. It imports components from `./src/shared` and global styles from `./assets/styles/`. `App.tsx` is in turn imported by server (`server.tsx`) and client (`index.tsx`) files in `./src/server/` and `./src/client/`, respectively.
5052

5153
The `app.get()` method in server code (`./src/server/server.tsx`) specifies a callback function that will render to string React component from `App.tsx` and past it in a HTML template (`./src/server/indexTemplate.ts`), whenever there is an HTTP GET request with a path (`/`) relative to the site root.
5254

53-
After the `load` event is fired, the client code `hydrate` obtained React root.
55+
After the `load` event is fired, the client code `hydrate` obtained React root. The `hydrate` method is used to render React components on the client side. It is similar to `render`, but it will attach event listeners to the existing markup instead of replacing it.
56+
57+
### Hot Module Replacement
58+
59+
Hot Module Replacement is one of the most useful features offered by webpack. It allows all kinds of modules or files to be updated at runtime without the need for a full refresh. This includes CSS and JS files, as well as static assets that are part of the dependency graph. When a file is changed, the module is replaced, and the application code is re-executed. During such module replacement a component's state is preserved.
60+
61+
### Typescript checking
62+
63+
After each re-building webpack plugin `fork-ts-checker-webpack-plugin` checks the typescript code for errors.
64+
65+
### Static files
5466

5567
All files in `./src/static/` are copied to the `./dist/client` folder without changes. For example, the `./src/static/images` folder will be copied to `./dist/client/images`. All files in `./src/static` are accessible through the virtual prefix `/static`. For example, the `./src/static/images/raster/favicon/favicon.png` file will be available at the address `http://localhost:3000/static/images/raster/favicon/favicon.png` === `/static/images/raster/favicon/favicon.png`.
5668

69+
### Image optimization
70+
5771
Images in `./src/static/images` are optimized by Webpack. For images with `jpeg` or `jpg` or `png` extentions, the `image-minimizer-webpack-plugin` and `sharp` generate a WebP version of the images.
5872

59-
After each re-building webpack plugin `fork-ts-checker-webpack-plugin` checks the typescript code for errors.
73+
### Browserslist
6074

6175
The `browserslist` is used by babel and postcss to compile code for the specified browsers. The list of browsers is specified in the `package.json` file.
6276

63-
## What is used in the template?
64-
65-
### Code
77+
### Testing
6678

67-
- Webpack loader (babel-loader)
68-
- Webpack plugin (fork-ts-checker-webpack-plugin)
69-
- browserslist
79+
It is possible to write snapshot tests (using `jest` and `react-test-renderer`) and tests for React components (using the `react-testing-library` library).
7080

71-
### Styles
81+
The template contains a simple tests for the `Header` component. The test is located in the `./src/__tests__/Header.test.tsx` file.
7282

73-
- Stylus
74-
- postcss
75-
- Webpack loaders (stylus-loader, css-loader, postcss-loader, style-loader)
76-
- browserslist
83+
## What is used in the template?
7784

78-
### Prettier && Linter
85+
### Server-Side Rendering
7986

80-
- Prettier
81-
- ESLint
87+
- Express server
88+
- Nodemon
8289

8390
### Hot Module Replacement
8491

@@ -88,12 +95,31 @@ The `browserslist` is used by babel and postcss to compile code for the specifie
8895
- Webpack modules and plugins (webpack-dev-middleware, webpack-hot-middleware)
8996
- Webpack plugins (webpack.HotModuleReplacementPlugin)
9097

91-
### Server-Side Rendering
98+
### Code compilation
9299

93-
- Express server
94-
- Nodemon
100+
- Webpack loader (babel-loader)
101+
- Webpack plugin (fork-ts-checker-webpack-plugin)
102+
- browserslist
103+
104+
### Styles
105+
106+
- Stylus
107+
- postcss
108+
- Webpack loaders (stylus-loader, css-loader, postcss-loader, style-loader)
109+
- browserslist
95110

96111
### Image Optimization
97112

98113
- Webpack plugin (image-minimizer-webpack-plugin)
99114
- Sharp
115+
116+
### Prettier && Linter
117+
118+
- Prettier
119+
- ESLint
120+
121+
### Testing
122+
123+
- Jest
124+
- React Test Renderer
125+
- React Testing Library
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Header renders correctly 1`] = `
4+
<header>
5+
<h1
6+
className="example"
7+
>
8+
Hello React
9+
</h1>
10+
<button
11+
className="example"
12+
onClick={[Function]}
13+
>
14+
Clicked
15+
0
16+
times
17+
</button>
18+
<picture>
19+
<source
20+
height="118"
21+
srcSet="/static/images/raster/test-image/test-image.webp"
22+
type="image/webp"
23+
width="637"
24+
/>
25+
<img
26+
alt="Test image"
27+
className="preview__image"
28+
height="118"
29+
src="/static/images/raster/test-image/test-image.jpg"
30+
width="637"
31+
/>
32+
</picture>
33+
</header>
34+
`;

__test__/header.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* @jest-environment jsdom
3+
*/
4+
5+
import React from 'react';
6+
import renderer from 'react-test-renderer';
7+
import { render, screen } from '@testing-library/react';
8+
import userEvent from '@testing-library/user-event';
9+
import '@testing-library/jest-dom';
10+
import { Header } from '../src/shared/Header';
11+
12+
describe('Header', () => {
13+
it('renders correctly', () => {
14+
const tree = renderer.create(<Header />).toJSON();
15+
expect(tree).toMatchSnapshot();
16+
});
17+
18+
test('should increment counter', async () => {
19+
render(<Header />);
20+
21+
const button = screen.getByRole('button', { name: /clicked/i });
22+
expect(button).toHaveTextContent('Clicked 0 times');
23+
24+
await userEvent.click(button);
25+
expect(button).toHaveTextContent('Clicked 1 times');
26+
});
27+
});

jest.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@
33
module.exports = {
44
preset: 'ts-jest',
55
testEnvironment: 'node',
6+
verbose: true,
7+
moduleNameMapper: {
8+
'\\.(css|styl|scss|sass|less)$': 'identity-obj-proxy',
9+
},
610
};

0 commit comments

Comments
 (0)