eslint-plugin-jest 26.8.5 → 26.9.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 +1 -0
- package/docs/rules/prefer-each.md +54 -0
- package/lib/rules/max-expects.js +5 -3
- package/lib/rules/prefer-each.js +102 -0
- package/lib/rules/prefer-expect-assertions.js +11 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -226,6 +226,7 @@ installations requiring long-term consistency.
|
|
|
226
226
|
| [no-test-return-statement](docs/rules/no-test-return-statement.md) | Disallow explicitly returning from tests | | |
|
|
227
227
|
| [prefer-called-with](docs/rules/prefer-called-with.md) | Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()` | | |
|
|
228
228
|
| [prefer-comparison-matcher](docs/rules/prefer-comparison-matcher.md) | Suggest using the built-in comparison matchers | | ![fixable][] |
|
|
229
|
+
| [prefer-each](docs/rules/prefer-each.md) | Prefer using `.each` rather than manual loops | | |
|
|
229
230
|
| [prefer-equality-matcher](docs/rules/prefer-equality-matcher.md) | Suggest using the built-in equality matchers | | ![suggest][] |
|
|
230
231
|
| [prefer-expect-assertions](docs/rules/prefer-expect-assertions.md) | Suggest using `expect.assertions()` OR `expect.hasAssertions()` | | ![suggest][] |
|
|
231
232
|
| [prefer-expect-resolves](docs/rules/prefer-expect-resolves.md) | Prefer `await expect(...).resolves` over `expect(await ...)` syntax | | ![fixable][] |
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Prefer using `.each` rather than manual loops (`prefer-each`)
|
|
2
|
+
|
|
3
|
+
Reports where you might be able to use `.each` instead of native loops.
|
|
4
|
+
|
|
5
|
+
## Rule details
|
|
6
|
+
|
|
7
|
+
This rule triggers a warning if you use test case functions like `describe`,
|
|
8
|
+
`test`, and `it`, in a native loop - generally you should be able to use `.each`
|
|
9
|
+
instead which gives better output and makes it easier to run specific cases.
|
|
10
|
+
|
|
11
|
+
Examples of **incorrect** code for this rule:
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
for (const number of getNumbers()) {
|
|
15
|
+
it('is greater than five', function () {
|
|
16
|
+
expect(number).toBeGreaterThan(5);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
for (const [input, expected] of data) {
|
|
21
|
+
beforeEach(() => setupSomething(input));
|
|
22
|
+
|
|
23
|
+
test(`results in ${expected}`, () => {
|
|
24
|
+
expect(doSomething()).toBe(expected);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Examples of **correct** code for this rule:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
it.each(getNumbers())(
|
|
33
|
+
'only returns numbers that are greater than seven',
|
|
34
|
+
number => {
|
|
35
|
+
expect(number).toBeGreaterThan(7);
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
describe.each(data)('when input is %s', ([input, expected]) => {
|
|
40
|
+
beforeEach(() => setupSomething(input));
|
|
41
|
+
|
|
42
|
+
test(`results in ${expected}`, () => {
|
|
43
|
+
expect(doSomething()).toBe(expected);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// we don't warn on loops _in_ test functions because those typically involve
|
|
48
|
+
// complex setup that is better done in the test function itself
|
|
49
|
+
it('returns numbers that are greater than five', () => {
|
|
50
|
+
for (const number of getNumbers()) {
|
|
51
|
+
expect(number).toBeGreaterThan(5);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
```
|
package/lib/rules/max-expects.js
CHANGED
|
@@ -41,7 +41,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
41
41
|
}]) {
|
|
42
42
|
let count = 0;
|
|
43
43
|
|
|
44
|
-
const
|
|
44
|
+
const maybeResetCount = node => {
|
|
45
45
|
var _node$parent;
|
|
46
46
|
|
|
47
47
|
const isTestFn = ((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) !== _utils.AST_NODE_TYPES.CallExpression || (0, _utils2.isTypeOfJestFnCall)(node.parent, context, ['test']);
|
|
@@ -52,8 +52,10 @@ var _default = (0, _utils2.createRule)({
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
return {
|
|
55
|
-
FunctionExpression:
|
|
56
|
-
|
|
55
|
+
FunctionExpression: maybeResetCount,
|
|
56
|
+
'FunctionExpression:exit': maybeResetCount,
|
|
57
|
+
ArrowFunctionExpression: maybeResetCount,
|
|
58
|
+
'ArrowFunctionExpression:exit': maybeResetCount,
|
|
57
59
|
|
|
58
60
|
CallExpression(node) {
|
|
59
61
|
var _jestFnCall$head$node;
|
|
@@ -0,0 +1,102 @@
|
|
|
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
|
+
var _default = (0, _utils.createRule)({
|
|
11
|
+
name: __filename,
|
|
12
|
+
meta: {
|
|
13
|
+
docs: {
|
|
14
|
+
category: 'Best Practices',
|
|
15
|
+
description: 'Prefer using `.each` rather than manual loops',
|
|
16
|
+
recommended: false
|
|
17
|
+
},
|
|
18
|
+
messages: {
|
|
19
|
+
preferEach: 'prefer using `{{ fn }}.each` rather than a manual loop'
|
|
20
|
+
},
|
|
21
|
+
type: 'suggestion',
|
|
22
|
+
schema: []
|
|
23
|
+
},
|
|
24
|
+
defaultOptions: [],
|
|
25
|
+
|
|
26
|
+
create(context) {
|
|
27
|
+
const jestFnCalls = [];
|
|
28
|
+
let inTestCaseCall = false;
|
|
29
|
+
|
|
30
|
+
const recommendFn = () => {
|
|
31
|
+
if (jestFnCalls.length === 1 && jestFnCalls[0] === 'test') {
|
|
32
|
+
return 'it';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return 'describe';
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const enterForLoop = () => {
|
|
39
|
+
if (jestFnCalls.length === 0 || inTestCaseCall) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
jestFnCalls.length = 0;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const exitForLoop = node => {
|
|
47
|
+
if (jestFnCalls.length === 0 || inTestCaseCall) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
context.report({
|
|
52
|
+
node,
|
|
53
|
+
messageId: 'preferEach',
|
|
54
|
+
data: {
|
|
55
|
+
fn: recommendFn()
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
jestFnCalls.length = 0;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
ForStatement: enterForLoop,
|
|
63
|
+
'ForStatement:exit': exitForLoop,
|
|
64
|
+
ForInStatement: enterForLoop,
|
|
65
|
+
'ForInStatement:exit': exitForLoop,
|
|
66
|
+
ForOfStatement: enterForLoop,
|
|
67
|
+
'ForOfStatement:exit': exitForLoop,
|
|
68
|
+
|
|
69
|
+
CallExpression(node) {
|
|
70
|
+
var _parseJestFnCall;
|
|
71
|
+
|
|
72
|
+
const {
|
|
73
|
+
type: jestFnCallType
|
|
74
|
+
} = (_parseJestFnCall = (0, _utils.parseJestFnCall)(node, context)) !== null && _parseJestFnCall !== void 0 ? _parseJestFnCall : {};
|
|
75
|
+
|
|
76
|
+
if (jestFnCallType === 'hook' || jestFnCallType === 'describe' || jestFnCallType === 'test') {
|
|
77
|
+
jestFnCalls.push(jestFnCallType);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (jestFnCallType === 'test') {
|
|
81
|
+
inTestCaseCall = true;
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
'CallExpression:exit'(node) {
|
|
86
|
+
var _parseJestFnCall2;
|
|
87
|
+
|
|
88
|
+
const {
|
|
89
|
+
type: jestFnCallType
|
|
90
|
+
} = (_parseJestFnCall2 = (0, _utils.parseJestFnCall)(node, context)) !== null && _parseJestFnCall2 !== void 0 ? _parseJestFnCall2 : {};
|
|
91
|
+
|
|
92
|
+
if (jestFnCallType === 'test') {
|
|
93
|
+
inTestCaseCall = false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
exports.default = _default;
|
|
@@ -32,8 +32,10 @@ const suggestRemovingExtraArguments = (args, extraArgsStartAt) => ({
|
|
|
32
32
|
fix: fixer => fixer.removeRange([args[extraArgsStartAt].range[0] - Math.sign(extraArgsStartAt), args[args.length - 1].range[1]])
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
const suggestions
|
|
36
|
-
|
|
35
|
+
// const suggestions: Array<[MessageIds, string]> = [
|
|
36
|
+
// ['suggestAddingHasAssertions', 'expect.hasAssertions();'],
|
|
37
|
+
// ['suggestAddingAssertions', 'expect.assertions();'],
|
|
38
|
+
// ];
|
|
37
39
|
var _default = (0, _utils2.createRule)({
|
|
38
40
|
name: __filename,
|
|
39
41
|
meta: {
|
|
@@ -213,11 +215,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
213
215
|
|
|
214
216
|
const [, testFn] = node.arguments;
|
|
215
217
|
|
|
216
|
-
if (!(0, _utils2.isFunction)(testFn) || testFn
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (!shouldCheckFunction(testFn)) {
|
|
218
|
+
if (!(0, _utils2.isFunction)(testFn) || !shouldCheckFunction(testFn)) {
|
|
221
219
|
return;
|
|
222
220
|
}
|
|
223
221
|
|
|
@@ -229,6 +227,12 @@ var _default = (0, _utils2.createRule)({
|
|
|
229
227
|
return;
|
|
230
228
|
}
|
|
231
229
|
|
|
230
|
+
const suggestions = [];
|
|
231
|
+
|
|
232
|
+
if (testFn.body.type === _utils.AST_NODE_TYPES.BlockStatement) {
|
|
233
|
+
suggestions.push(['suggestAddingHasAssertions', 'expect.hasAssertions();'], ['suggestAddingAssertions', 'expect.assertions();']);
|
|
234
|
+
}
|
|
235
|
+
|
|
232
236
|
context.report({
|
|
233
237
|
messageId: 'haveExpectAssertions',
|
|
234
238
|
node,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-jest",
|
|
3
|
-
"version": "26.
|
|
3
|
+
"version": "26.9.0",
|
|
4
4
|
"description": "ESLint rules for Jest",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
"optional": true
|
|
152
152
|
}
|
|
153
153
|
},
|
|
154
|
-
"packageManager": "yarn@3.2.
|
|
154
|
+
"packageManager": "yarn@3.2.3",
|
|
155
155
|
"engines": {
|
|
156
156
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
|
157
157
|
}
|