Skip to content

Commit 384654c

Browse files
aaron012G-Rath
andauthored
feat: create prefer-hooks-in-order rule (#1098)
* feat: create `prefer-hooks-in-order` rule * wip * Implement prefer-hooks-in-order logic * Fix all rules tests * ci: run prettier and docs generation, fix test description * test: Add examples to the tests * test: Add some more complicated tests * ci: change isHook to isHookCall * feat: use early returns consistently Co-authored-by: Gareth Jones <[email protected]>
1 parent 7c28c6b commit 384654c

File tree

6 files changed

+904
-1
lines changed

6 files changed

+904
-1
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ installations requiring long-term consistency.
209209
| [prefer-equality-matcher](docs/rules/prefer-equality-matcher.md) | Suggest using the built-in equality matchers | | ![suggest][] |
210210
| [prefer-expect-assertions](docs/rules/prefer-expect-assertions.md) | Suggest using `expect.assertions()` OR `expect.hasAssertions()` | | ![suggest][] |
211211
| [prefer-expect-resolves](docs/rules/prefer-expect-resolves.md) | Prefer `await expect(...).resolves` over `expect(await ...)` syntax | | ![fixable][] |
212+
| [prefer-hooks-in-order](docs/rules/prefer-hooks-in-order.md) | Prefer having hooks in a consistent order | | |
212213
| [prefer-hooks-on-top](docs/rules/prefer-hooks-on-top.md) | Suggest having hooks before any test cases | | |
213214
| [prefer-lowercase-title](docs/rules/prefer-lowercase-title.md) | Enforce lowercase test names | | ![fixable][] |
214215
| [prefer-snapshot-hint](docs/rules/prefer-snapshot-hint.md) | Prefer including a hint with external snapshots | | |

docs/rules/prefer-hooks-in-order.md

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Prefer having hooks in a consistent order (`prefer-hooks-in-order`)
2+
3+
While hooks can be setup in any order, they're always called by `jest` in this
4+
specific order:
5+
6+
1. `beforeAll`
7+
1. `beforeEach`
8+
1. `afterEach`
9+
1. `afterAll`
10+
11+
This rule aims to make that more obvious by enforcing grouped hooks be setup in
12+
that order within tests.
13+
14+
## Rule Details
15+
16+
Examples of **incorrect** code for this rule
17+
18+
```js
19+
/* eslint jest/prefer-hooks-in-order: "error" */
20+
21+
describe('foo', () => {
22+
beforeEach(() => {
23+
seedMyDatabase();
24+
});
25+
26+
beforeAll(() => {
27+
createMyDatabase();
28+
});
29+
30+
it('accepts this input', () => {
31+
// ...
32+
});
33+
34+
it('returns that value', () => {
35+
// ...
36+
});
37+
38+
describe('when the database has specific values', () => {
39+
const specificValue = '...';
40+
41+
beforeEach(() => {
42+
seedMyDatabase(specificValue);
43+
});
44+
45+
it('accepts that input', () => {
46+
// ...
47+
});
48+
49+
it('throws an error', () => {
50+
// ...
51+
});
52+
53+
afterEach(() => {
54+
clearLogger();
55+
});
56+
beforeEach(() => {
57+
mockLogger();
58+
});
59+
60+
it('logs a message', () => {
61+
// ...
62+
});
63+
});
64+
65+
afterAll(() => {
66+
removeMyDatabase();
67+
});
68+
});
69+
```
70+
71+
Examples of **correct** code for this rule
72+
73+
```js
74+
/* eslint jest/prefer-hooks-in-order: "error" */
75+
76+
describe('foo', () => {
77+
beforeAll(() => {
78+
createMyDatabase();
79+
});
80+
81+
beforeEach(() => {
82+
seedMyDatabase();
83+
});
84+
85+
it('accepts this input', () => {
86+
// ...
87+
});
88+
89+
it('returns that value', () => {
90+
// ...
91+
});
92+
93+
describe('when the database has specific values', () => {
94+
const specificValue = '...';
95+
96+
beforeEach(() => {
97+
seedMyDatabase(specificValue);
98+
});
99+
100+
it('accepts that input', () => {
101+
// ...
102+
});
103+
104+
it('throws an error', () => {
105+
// ...
106+
});
107+
108+
beforeEach(() => {
109+
mockLogger();
110+
});
111+
112+
afterEach(() => {
113+
clearLogger();
114+
});
115+
116+
it('logs a message', () => {
117+
// ...
118+
});
119+
});
120+
121+
afterAll(() => {
122+
removeMyDatabase();
123+
});
124+
});
125+
```
126+
127+
## Also See
128+
129+
- [`prefer-hooks-on-top`](prefer-hooks-on-top.md)
130+
131+
## Further Reading
132+
133+
- [Order of execution of describe and test blocks](https://jestjs.io/docs/setup-teardown#order-of-execution-of-describe-and-test-blocks)

src/__tests__/__snapshots__/rules.test.ts.snap

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Object {
3939
"jest/prefer-equality-matcher": "error",
4040
"jest/prefer-expect-assertions": "error",
4141
"jest/prefer-expect-resolves": "error",
42+
"jest/prefer-hooks-in-order": "error",
4243
"jest/prefer-hooks-on-top": "error",
4344
"jest/prefer-lowercase-title": "error",
4445
"jest/prefer-snapshot-hint": "error",

src/__tests__/rules.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { existsSync } from 'fs';
22
import { resolve } from 'path';
33
import plugin from '../';
44

5-
const numberOfRules = 47;
5+
const numberOfRules = 48;
66
const ruleNames = Object.keys(plugin.rules);
77
const deprecatedRules = Object.entries(plugin.rules)
88
.filter(([, rule]) => rule.meta.deprecated)

0 commit comments

Comments
 (0)