eslint-plugin-jest 26.8.4 → 26.8.7
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 +8 -0
- package/lib/rules/max-expects.js +5 -3
- package/lib/rules/prefer-expect-assertions.js +84 -69
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -282,6 +282,14 @@ as it extends the original `unbound-method` rule from that plugin.
|
|
|
282
282
|
|
|
283
283
|
## Related Projects
|
|
284
284
|
|
|
285
|
+
### eslint-plugin-jest-extended
|
|
286
|
+
|
|
287
|
+
This is a sister plugin to `eslint-plugin-jest` that provides support for the
|
|
288
|
+
matchers provided by
|
|
289
|
+
[`jest-extended`](https://github.com/jest-community/jest-extended).
|
|
290
|
+
|
|
291
|
+
https://github.com/jest-community/eslint-plugin-jest-extended
|
|
292
|
+
|
|
285
293
|
### eslint-plugin-jest-formatting
|
|
286
294
|
|
|
287
295
|
This project aims to provide formatting rules (auto-fixable where possible) to
|
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;
|
|
@@ -9,17 +9,33 @@ var _utils = require("@typescript-eslint/utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils2 = require("./utils");
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const isFirstStatement = node => {
|
|
13
|
+
let parent = node;
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
while (parent) {
|
|
16
|
+
var _parent$parent;
|
|
17
|
+
|
|
18
|
+
if (((_parent$parent = parent.parent) === null || _parent$parent === void 0 ? void 0 : _parent$parent.type) === _utils.AST_NODE_TYPES.BlockStatement) {
|
|
19
|
+
return parent.parent.body[0] === parent;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
parent = parent.parent;
|
|
23
|
+
}
|
|
24
|
+
/* istanbul ignore next */
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
throw new Error(`Could not find BlockStatement - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
|
|
28
|
+
};
|
|
15
29
|
|
|
16
30
|
const suggestRemovingExtraArguments = (args, extraArgsStartAt) => ({
|
|
17
31
|
messageId: 'suggestRemovingExtraArguments',
|
|
18
32
|
fix: fixer => fixer.removeRange([args[extraArgsStartAt].range[0] - Math.sign(extraArgsStartAt), args[args.length - 1].range[1]])
|
|
19
33
|
});
|
|
20
34
|
|
|
21
|
-
const suggestions
|
|
22
|
-
|
|
35
|
+
// const suggestions: Array<[MessageIds, string]> = [
|
|
36
|
+
// ['suggestAddingHasAssertions', 'expect.hasAssertions();'],
|
|
37
|
+
// ['suggestAddingAssertions', 'expect.assertions();'],
|
|
38
|
+
// ];
|
|
23
39
|
var _default = (0, _utils2.createRule)({
|
|
24
40
|
name: __filename,
|
|
25
41
|
meta: {
|
|
@@ -66,6 +82,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
66
82
|
let expressionDepth = 0;
|
|
67
83
|
let hasExpectInCallback = false;
|
|
68
84
|
let hasExpectInLoop = false;
|
|
85
|
+
let hasExpectAssertionsAsFirstStatement = false;
|
|
69
86
|
let inTestCaseCall = false;
|
|
70
87
|
let inForLoop = false;
|
|
71
88
|
|
|
@@ -95,6 +112,50 @@ var _default = (0, _utils2.createRule)({
|
|
|
95
112
|
return false;
|
|
96
113
|
};
|
|
97
114
|
|
|
115
|
+
const checkExpectHasAssertions = expectFnCall => {
|
|
116
|
+
if ((0, _utils2.getAccessorValue)(expectFnCall.members[0]) === 'hasAssertions') {
|
|
117
|
+
if (expectFnCall.args.length) {
|
|
118
|
+
context.report({
|
|
119
|
+
messageId: 'hasAssertionsTakesNoArguments',
|
|
120
|
+
node: expectFnCall.matcher,
|
|
121
|
+
suggest: [suggestRemovingExtraArguments(expectFnCall.args, 0)]
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (expectFnCall.args.length !== 1) {
|
|
129
|
+
let {
|
|
130
|
+
loc
|
|
131
|
+
} = expectFnCall.matcher;
|
|
132
|
+
const suggest = [];
|
|
133
|
+
|
|
134
|
+
if (expectFnCall.args.length) {
|
|
135
|
+
loc = expectFnCall.args[1].loc;
|
|
136
|
+
suggest.push(suggestRemovingExtraArguments(expectFnCall.args, 1));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
context.report({
|
|
140
|
+
messageId: 'assertionsRequiresOneArgument',
|
|
141
|
+
suggest,
|
|
142
|
+
loc
|
|
143
|
+
});
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const [arg] = expectFnCall.args;
|
|
148
|
+
|
|
149
|
+
if (arg.type === _utils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value)) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
context.report({
|
|
154
|
+
messageId: 'assertionsRequiresNumberArgument',
|
|
155
|
+
node: arg
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
|
|
98
159
|
const enterExpression = () => inTestCaseCall && expressionDepth++;
|
|
99
160
|
|
|
100
161
|
const exitExpression = () => inTestCaseCall && expressionDepth--;
|
|
@@ -124,6 +185,13 @@ var _default = (0, _utils2.createRule)({
|
|
|
124
185
|
}
|
|
125
186
|
|
|
126
187
|
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect' && inTestCaseCall) {
|
|
188
|
+
var _jestFnCall$head$node;
|
|
189
|
+
|
|
190
|
+
if (expressionDepth === 1 && isFirstStatement(node) && ((_jestFnCall$head$node = jestFnCall.head.node.parent) === null || _jestFnCall$head$node === void 0 ? void 0 : _jestFnCall$head$node.type) === _utils.AST_NODE_TYPES.MemberExpression && jestFnCall.members.length === 1 && ['assertions', 'hasAssertions'].includes((0, _utils2.getAccessorValue)(jestFnCall.members[0]))) {
|
|
191
|
+
checkExpectHasAssertions(jestFnCall);
|
|
192
|
+
hasExpectAssertionsAsFirstStatement = true;
|
|
193
|
+
}
|
|
194
|
+
|
|
127
195
|
if (inForLoop) {
|
|
128
196
|
hasExpectInLoop = true;
|
|
129
197
|
}
|
|
@@ -147,84 +215,31 @@ var _default = (0, _utils2.createRule)({
|
|
|
147
215
|
|
|
148
216
|
const [, testFn] = node.arguments;
|
|
149
217
|
|
|
150
|
-
if (!(0, _utils2.isFunction)(testFn) || testFn
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!shouldCheckFunction(testFn)) {
|
|
218
|
+
if (!(0, _utils2.isFunction)(testFn) || !shouldCheckFunction(testFn)) {
|
|
155
219
|
return;
|
|
156
220
|
}
|
|
157
221
|
|
|
158
222
|
hasExpectInLoop = false;
|
|
159
223
|
hasExpectInCallback = false;
|
|
160
|
-
const testFuncBody = testFn.body.body;
|
|
161
|
-
|
|
162
|
-
if (!isFirstLineExprStmt(testFuncBody)) {
|
|
163
|
-
context.report({
|
|
164
|
-
messageId: 'haveExpectAssertions',
|
|
165
|
-
node,
|
|
166
|
-
suggest: suggestions.map(([messageId, text]) => ({
|
|
167
|
-
messageId,
|
|
168
|
-
fix: fixer => fixer.insertTextBeforeRange([testFn.body.range[0] + 1, testFn.body.range[1]], text)
|
|
169
|
-
}))
|
|
170
|
-
});
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const testFuncFirstLine = testFuncBody[0].expression;
|
|
175
|
-
|
|
176
|
-
if (!isExpectAssertionsOrHasAssertionsCall(testFuncFirstLine)) {
|
|
177
|
-
context.report({
|
|
178
|
-
messageId: 'haveExpectAssertions',
|
|
179
|
-
node,
|
|
180
|
-
suggest: suggestions.map(([messageId, text]) => ({
|
|
181
|
-
messageId,
|
|
182
|
-
fix: fixer => fixer.insertTextBefore(testFuncBody[0], text)
|
|
183
|
-
}))
|
|
184
|
-
});
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if ((0, _utils2.isSupportedAccessor)(testFuncFirstLine.callee.property, 'hasAssertions')) {
|
|
189
|
-
if (testFuncFirstLine.arguments.length) {
|
|
190
|
-
context.report({
|
|
191
|
-
messageId: 'hasAssertionsTakesNoArguments',
|
|
192
|
-
node: testFuncFirstLine.callee.property,
|
|
193
|
-
suggest: [suggestRemovingExtraArguments(testFuncFirstLine.arguments, 0)]
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
224
|
|
|
225
|
+
if (hasExpectAssertionsAsFirstStatement) {
|
|
226
|
+
hasExpectAssertionsAsFirstStatement = false;
|
|
197
227
|
return;
|
|
198
228
|
}
|
|
199
229
|
|
|
200
|
-
|
|
201
|
-
let {
|
|
202
|
-
loc
|
|
203
|
-
} = testFuncFirstLine.callee.property;
|
|
204
|
-
const suggest = [];
|
|
230
|
+
const suggestions = [];
|
|
205
231
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
suggest.push(suggestRemovingExtraArguments(testFuncFirstLine.arguments, 1));
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
context.report({
|
|
212
|
-
messageId: 'assertionsRequiresOneArgument',
|
|
213
|
-
suggest,
|
|
214
|
-
loc
|
|
215
|
-
});
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const [arg] = testFuncFirstLine.arguments;
|
|
220
|
-
|
|
221
|
-
if (arg.type === _utils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value)) {
|
|
222
|
-
return;
|
|
232
|
+
if (testFn.body.type === _utils.AST_NODE_TYPES.BlockStatement) {
|
|
233
|
+
suggestions.push(['suggestAddingHasAssertions', 'expect.hasAssertions();'], ['suggestAddingAssertions', 'expect.assertions();']);
|
|
223
234
|
}
|
|
224
235
|
|
|
225
236
|
context.report({
|
|
226
|
-
messageId: '
|
|
227
|
-
node
|
|
237
|
+
messageId: 'haveExpectAssertions',
|
|
238
|
+
node,
|
|
239
|
+
suggest: suggestions.map(([messageId, text]) => ({
|
|
240
|
+
messageId,
|
|
241
|
+
fix: fixer => fixer.insertTextBeforeRange([testFn.body.range[0] + 1, testFn.body.range[1]], text)
|
|
242
|
+
}))
|
|
228
243
|
});
|
|
229
244
|
}
|
|
230
245
|
|