eslint-plugin-jest 26.2.2 → 26.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -209,6 +209,7 @@ installations requiring long-term consistency.
|
|
|
209
209
|
| [prefer-equality-matcher](docs/rules/prefer-equality-matcher.md) | Suggest using the built-in equality matchers | | ![suggest][] |
|
|
210
210
|
| [prefer-expect-assertions](docs/rules/prefer-expect-assertions.md) | Suggest using `expect.assertions()` OR `expect.hasAssertions()` | | ![suggest][] |
|
|
211
211
|
| [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 | | |
|
|
212
213
|
| [prefer-hooks-on-top](docs/rules/prefer-hooks-on-top.md) | Suggest having hooks before any test cases | | |
|
|
213
214
|
| [prefer-lowercase-title](docs/rules/prefer-lowercase-title.md) | Enforce lowercase test names | | ![fixable][] |
|
|
214
215
|
| [prefer-snapshot-hint](docs/rules/prefer-snapshot-hint.md) | Prefer including a hint with external snapshots | | |
|
|
@@ -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)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _utils = require("./utils");
|
|
9
|
+
|
|
10
|
+
const HooksOrder = ['beforeAll', 'beforeEach', 'afterEach', 'afterAll'];
|
|
11
|
+
|
|
12
|
+
var _default = (0, _utils.createRule)({
|
|
13
|
+
name: __filename,
|
|
14
|
+
meta: {
|
|
15
|
+
docs: {
|
|
16
|
+
category: 'Best Practices',
|
|
17
|
+
description: 'Prefer having hooks in a consistent order',
|
|
18
|
+
recommended: false
|
|
19
|
+
},
|
|
20
|
+
messages: {
|
|
21
|
+
reorderHooks: `\`{{ currentHook }}\` hooks should be before any \`{{ previousHook }}\` hooks`
|
|
22
|
+
},
|
|
23
|
+
schema: [],
|
|
24
|
+
type: 'suggestion'
|
|
25
|
+
},
|
|
26
|
+
defaultOptions: [],
|
|
27
|
+
|
|
28
|
+
create(context) {
|
|
29
|
+
let previousHookIndex = -1;
|
|
30
|
+
let inHook = false;
|
|
31
|
+
return {
|
|
32
|
+
CallExpression(node) {
|
|
33
|
+
if (inHook) {
|
|
34
|
+
// Ignore everything that is passed into a hook
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!(0, _utils.isHookCall)(node, context.getScope())) {
|
|
39
|
+
// Reset the previousHookIndex when encountering something different from a hook
|
|
40
|
+
previousHookIndex = -1;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
inHook = true;
|
|
45
|
+
const currentHook = node.callee.name;
|
|
46
|
+
const currentHookIndex = HooksOrder.indexOf(currentHook);
|
|
47
|
+
|
|
48
|
+
if (currentHookIndex < previousHookIndex) {
|
|
49
|
+
context.report({
|
|
50
|
+
messageId: 'reorderHooks',
|
|
51
|
+
node,
|
|
52
|
+
data: {
|
|
53
|
+
previousHook: HooksOrder[previousHookIndex],
|
|
54
|
+
currentHook
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
previousHookIndex = currentHookIndex;
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
'CallExpression:exit'(node) {
|
|
64
|
+
if ((0, _utils.isHookCall)(node, context.getScope())) {
|
|
65
|
+
inHook = false;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (inHook) {
|
|
70
|
+
return;
|
|
71
|
+
} // Reset the previousHookIndex when encountering something different from a hook
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
previousHookIndex = -1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
exports.default = _default;
|