Skip to content

Commit 26af4d5

Browse files
langpavelokendoken
authored andcommitted
Introduce Jest (#1347)
* dev-deps: jest, jscodeshift, jest-codemods * jest configuration * Example jest test * Remove mocha and istanbul in favour of jest
1 parent 1d9febb commit 26af4d5

File tree

6 files changed

+1667
-328
lines changed

6 files changed

+1667
-328
lines changed

jest.config.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
module.exports = {
2+
// Modules can be explicitly auto-mocked using jest.mock(moduleName).
3+
// https://facebook.github.io/jest/docs/en/configuration.html#automock-boolean
4+
automock: false, // [boolean]
5+
6+
// Respect Browserify's "browser" field in package.json when resolving modules.
7+
// https://facebook.github.io/jest/docs/en/configuration.html#browser-boolean
8+
browser: false, // [boolean]
9+
10+
// This config option can be used here to have Jest stop running tests after the first failure.
11+
// https://facebook.github.io/jest/docs/en/configuration.html#bail-boolean
12+
bail: false, // [boolean]
13+
14+
// The directory where Jest should store its cached dependency information.
15+
// https://facebook.github.io/jest/docs/en/configuration.html#cachedirectory-string
16+
// cacheDirectory: '/tmp/<path>', // [string]
17+
18+
// Indicates whether the coverage information should be collected while executing the test.
19+
// Because this retrofits all executed files with coverage collection statements,
20+
// it may significantly slow down your tests.
21+
// https://facebook.github.io/jest/docs/en/configuration.html#collectcoverage-boolean
22+
// collectCoverage: false, // [boolean]
23+
24+
// https://facebook.github.io/jest/docs/en/configuration.html#collectcoveragefrom-array
25+
collectCoverageFrom: ['src/**/*.{js,jsx}', '!**/node_modules/**', '!**/vendor/**'],
26+
27+
// https://facebook.github.io/jest/docs/en/configuration.html#coveragedirectory-string
28+
coverageDirectory: '<rootDir>/coverage', // [string]
29+
30+
// coveragePathIgnorePatterns: // [array<string>]
31+
// coverageReporters: [], // [array<string>]
32+
// coverageThreshold: {}, // [object]
33+
34+
globals: {
35+
__DEV__: true,
36+
},
37+
38+
// https://facebook.github.io/jest/docs/en/configuration.html#mapcoverage-boolean
39+
// mapCoverage: false, // [boolean]
40+
41+
// The default extensions Jest will look for.
42+
// https://facebook.github.io/jest/docs/en/configuration.html#modulefileextensions-array-string
43+
moduleFileExtensions: ['js', 'json', 'jsx', 'node'],
44+
45+
// moduleDirectories: // [array<string>]
46+
47+
// A map from regular expressions to module names that allow to stub out resources,
48+
// like images or styles with a single module.
49+
moduleNameMapper: {
50+
'\\.(css|less|scss|sss)$': 'identity-obj-proxy',
51+
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 'GlobalImageStub',
52+
},
53+
54+
// modulePathIgnorePatterns: // [array<string>]
55+
// modulePaths: // [array<string>]
56+
// notify: false, // [boolean]
57+
// preset: // [string]
58+
// projects: // [array<string>]
59+
// clearMocks: // [boolean]
60+
// reporters: // [array<moduleName | [moduleName, options]>]
61+
// resetMocks: // [boolean]
62+
// resetModules: // [boolean]
63+
// resolver: // [string]
64+
// rootDir: // [string]
65+
// roots: // [array<string>]
66+
// setupFiles: // [array]
67+
// setupTestFrameworkScriptFile: // [string]
68+
// snapshotSerializers: // [array<string>]
69+
// testEnvironment: // [string]
70+
// testMatch: // [array<string>]
71+
// testPathIgnorePatterns: // [array<string>]
72+
// testRegex: // [string]
73+
// testResultsProcessor: // [string]
74+
// testRunner: // [string]
75+
// testURL: // [string]
76+
// timers: // [string]
77+
78+
transform: {
79+
'\\.jsx?$': 'babel-jest',
80+
'\\.(jpe?g|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/jest/fileTransformer.js',
81+
},
82+
83+
// transformIgnorePatterns: // [array<string>]
84+
// unmockedModulePathPatterns: // [array<string>]
85+
86+
verbose: true, // [boolean]
87+
};

jest/fileTransformer.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const path = require('path');
2+
3+
module.exports = {
4+
process(src, filename) {
5+
return `module.exports = ${JSON.stringify(path.basename(filename))};`;
6+
},
7+
};

package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@
5959
"babel-cli": "^6.24.1",
6060
"babel-core": "^6.25.0",
6161
"babel-eslint": "^7.2.3",
62+
"babel-jest": "^20.0.3",
6263
"babel-loader": "^7.1.1",
63-
"babel-plugin-istanbul": "^4.1.4",
6464
"babel-plugin-rewire": "^1.1.0",
6565
"babel-preset-env": "^1.5.2",
6666
"babel-preset-react": "^6.24.1",
@@ -70,7 +70,6 @@
7070
"babel-template": "^6.25.0",
7171
"babel-types": "^6.25.0",
7272
"browser-sync": "^2.18.12",
73-
"chai": "^4.0.2",
7473
"chokidar": "^1.7.0",
7574
"cross-env": "^5.0.1",
7675
"css-loader": "^0.28.4",
@@ -88,12 +87,14 @@
8887
"front-matter": "^2.1.2",
8988
"glob": "^7.1.2",
9089
"husky": "^0.14.1",
90+
"identity-obj-proxy": "^3.0.0",
91+
"jest": "^20.0.4",
92+
"jest-codemods": "^0.10.1",
93+
"jscodeshift": "^0.3.32",
9194
"lint-staged": "^4.0.0",
9295
"markdown-it": "^8.3.1",
9396
"mkdirp": "^0.5.1",
94-
"mocha": "^3.4.2",
9597
"null-loader": "^0.1.1",
96-
"nyc": "^11.0.3",
9798
"opn-cli": "^3.1.0",
9899
"node-sass": "4.5.0",
99100
"pixrem": "^3.0.2",
@@ -117,7 +118,7 @@
117118
"react-deep-force-update": "^2.0.1",
118119
"react-error-overlay": "^1.0.9",
119120
"react-hot-loader": "^3.0.0-beta.7",
120-
"react-test-renderer": "^15.5.4",
121+
"react-test-renderer": "^15.6.1",
121122
"redux-mock-store": "^1.2.3",
122123
"rimraf": "^2.6.1",
123124
"sass-loader": "6.0.3",
@@ -149,7 +150,6 @@
149150
"env": {
150151
"test": {
151152
"plugins": [
152-
"istanbul",
153153
"rewire"
154154
]
155155
}
@@ -180,10 +180,10 @@
180180
"fix-js": "yarn run lint-js -- --fix",
181181
"fix-css": "yarn run lint-css -- --fix",
182182
"fix": "yarn run fix-js && yarn run fix-css",
183-
"test": "mocha",
184-
"test-watch": "yarn run test -- --reporter min --watch",
185-
"test-cover": "cross-env NODE_ENV=test nyc npm run test",
186-
"coverage": "yarn run test-cover && nyc report --reporter=html && opn coverage/index.html",
183+
"test": "jest",
184+
"test-watch": "yarn run test -- --watch --notify",
185+
"test-cover": "yarn run test -- --coverage",
186+
"coverage": "yarn run test-cover && opn coverage/lcov-report/index.html",
187187
"clean": "babel-node tools/run clean",
188188
"copy": "babel-node tools/run copy",
189189
"bundle": "babel-node tools/run bundle",

src/components/Layout/Layout.test.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
* LICENSE.txt file in the root directory of this source tree.
88
*/
99

10-
/* eslint-env mocha */
10+
/* eslint-env jest */
1111
/* eslint-disable padded-blocks, no-unused-expressions */
1212

1313
import React from 'react';
14-
import { expect } from 'chai';
15-
import { render } from 'enzyme';
14+
import renderer from 'react-test-renderer';
1615
import configureStore from 'redux-mock-store';
1716
import thunk from 'redux-thunk';
1817
import App from '../App';
@@ -23,17 +22,19 @@ const mockStore = configureStore(middlewares);
2322
const initialState = {};
2423

2524
describe('Layout', () => {
25+
2626
it('renders children correctly', () => {
2727
const store = mockStore(initialState);
2828

29-
const wrapper = render(
29+
const wrapper = renderer.create(
3030
<App context={{ insertCss: () => {}, store }}>
3131
<Layout>
3232
<div className="child" />
3333
</Layout>
3434
</App>,
35-
);
36-
expect(wrapper.find('div.child').length).to.eq(1);
35+
).toJSON();
36+
37+
expect(wrapper).toMatchSnapshot();
3738
});
3839

3940
});
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Layout renders children correctly 1`] = `
4+
<div>
5+
<div
6+
className="root"
7+
>
8+
<div
9+
className="container"
10+
>
11+
<div
12+
className="root"
13+
role="navigation"
14+
>
15+
<a
16+
className="link"
17+
href="/about"
18+
onClick={[Function]}
19+
>
20+
About
21+
</a>
22+
<a
23+
className="link"
24+
href="/contact"
25+
onClick={[Function]}
26+
>
27+
Contact
28+
</a>
29+
<span
30+
className="spacer"
31+
>
32+
|
33+
</span>
34+
<a
35+
className="link"
36+
href="/login"
37+
onClick={[Function]}
38+
>
39+
Log in
40+
</a>
41+
<span
42+
className="spacer"
43+
>
44+
or
45+
</span>
46+
<a
47+
className="link highlight"
48+
href="/register"
49+
onClick={[Function]}
50+
>
51+
Sign up
52+
</a>
53+
</div>
54+
<a
55+
className="brand"
56+
href="/"
57+
onClick={[Function]}
58+
>
59+
<img
60+
alt="React"
61+
height="38"
62+
src="logo-small.png"
63+
srcSet="[email protected] 2x"
64+
width="38"
65+
/>
66+
<span
67+
className="brandTxt"
68+
>
69+
Your Company
70+
</span>
71+
</a>
72+
<div
73+
className="banner"
74+
>
75+
<h1
76+
className="bannerTitle"
77+
>
78+
React
79+
</h1>
80+
<p
81+
className="bannerDesc"
82+
>
83+
Complex web apps made easy
84+
</p>
85+
</div>
86+
</div>
87+
</div>
88+
<div
89+
className="child"
90+
/>
91+
<div
92+
className="root"
93+
>
94+
<div
95+
className="container"
96+
>
97+
<a
98+
className="link"
99+
href="https://gitter.im/kriasoft/react-starter-kit"
100+
>
101+
Ask a question
102+
</a>
103+
<span
104+
className="spacer"
105+
>
106+
|
107+
</span>
108+
<a
109+
className="link"
110+
href="https://github.com/kriasoft/react-starter-kit/issues/new"
111+
>
112+
Report an issue
113+
</a>
114+
</div>
115+
</div>
116+
<div
117+
className="root"
118+
>
119+
<div
120+
className="container"
121+
>
122+
<span
123+
className="text"
124+
>
125+
© Your Company
126+
</span>
127+
<span
128+
className="spacer"
129+
>
130+
·
131+
</span>
132+
<a
133+
className="link"
134+
href="/"
135+
onClick={[Function]}
136+
>
137+
Home
138+
</a>
139+
<span
140+
className="spacer"
141+
>
142+
·
143+
</span>
144+
<a
145+
className="link"
146+
href="/admin"
147+
onClick={[Function]}
148+
>
149+
Admin
150+
</a>
151+
<span
152+
className="spacer"
153+
>
154+
·
155+
</span>
156+
<a
157+
className="link"
158+
href="/privacy"
159+
onClick={[Function]}
160+
>
161+
Privacy
162+
</a>
163+
<span
164+
className="spacer"
165+
>
166+
·
167+
</span>
168+
<a
169+
className="link"
170+
href="/not-found"
171+
onClick={[Function]}
172+
>
173+
Not Found
174+
</a>
175+
</div>
176+
</div>
177+
</div>
178+
`;

0 commit comments

Comments
 (0)