eslint-plugin-jest 26.8.2 → 26.8.5
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<a href="https://eslint.org/">
|
|
3
|
-
<img
|
|
3
|
+
<img height="150" src="https://eslint.org/assets/images/logo/eslint-logo-color.svg">
|
|
4
4
|
</a>
|
|
5
5
|
<a href="https://facebook.github.io/jest/">
|
|
6
6
|
<img width="150" height="150" vspace="" hspace="25" src="https://jestjs.io/img/jest.png">
|
|
@@ -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
|
|
@@ -9,9 +9,23 @@ 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',
|
|
@@ -66,6 +80,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
66
80
|
let expressionDepth = 0;
|
|
67
81
|
let hasExpectInCallback = false;
|
|
68
82
|
let hasExpectInLoop = false;
|
|
83
|
+
let hasExpectAssertionsAsFirstStatement = false;
|
|
69
84
|
let inTestCaseCall = false;
|
|
70
85
|
let inForLoop = false;
|
|
71
86
|
|
|
@@ -95,6 +110,50 @@ var _default = (0, _utils2.createRule)({
|
|
|
95
110
|
return false;
|
|
96
111
|
};
|
|
97
112
|
|
|
113
|
+
const checkExpectHasAssertions = expectFnCall => {
|
|
114
|
+
if ((0, _utils2.getAccessorValue)(expectFnCall.members[0]) === 'hasAssertions') {
|
|
115
|
+
if (expectFnCall.args.length) {
|
|
116
|
+
context.report({
|
|
117
|
+
messageId: 'hasAssertionsTakesNoArguments',
|
|
118
|
+
node: expectFnCall.matcher,
|
|
119
|
+
suggest: [suggestRemovingExtraArguments(expectFnCall.args, 0)]
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (expectFnCall.args.length !== 1) {
|
|
127
|
+
let {
|
|
128
|
+
loc
|
|
129
|
+
} = expectFnCall.matcher;
|
|
130
|
+
const suggest = [];
|
|
131
|
+
|
|
132
|
+
if (expectFnCall.args.length) {
|
|
133
|
+
loc = expectFnCall.args[1].loc;
|
|
134
|
+
suggest.push(suggestRemovingExtraArguments(expectFnCall.args, 1));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
context.report({
|
|
138
|
+
messageId: 'assertionsRequiresOneArgument',
|
|
139
|
+
suggest,
|
|
140
|
+
loc
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const [arg] = expectFnCall.args;
|
|
146
|
+
|
|
147
|
+
if (arg.type === _utils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value)) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
context.report({
|
|
152
|
+
messageId: 'assertionsRequiresNumberArgument',
|
|
153
|
+
node: arg
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
|
|
98
157
|
const enterExpression = () => inTestCaseCall && expressionDepth++;
|
|
99
158
|
|
|
100
159
|
const exitExpression = () => inTestCaseCall && expressionDepth--;
|
|
@@ -124,6 +183,13 @@ var _default = (0, _utils2.createRule)({
|
|
|
124
183
|
}
|
|
125
184
|
|
|
126
185
|
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect' && inTestCaseCall) {
|
|
186
|
+
var _jestFnCall$head$node;
|
|
187
|
+
|
|
188
|
+
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]))) {
|
|
189
|
+
checkExpectHasAssertions(jestFnCall);
|
|
190
|
+
hasExpectAssertionsAsFirstStatement = true;
|
|
191
|
+
}
|
|
192
|
+
|
|
127
193
|
if (inForLoop) {
|
|
128
194
|
hasExpectInLoop = true;
|
|
129
195
|
}
|
|
@@ -157,74 +223,19 @@ var _default = (0, _utils2.createRule)({
|
|
|
157
223
|
|
|
158
224
|
hasExpectInLoop = false;
|
|
159
225
|
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
|
-
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (!(0, _utils2.hasOnlyOneArgument)(testFuncFirstLine)) {
|
|
201
|
-
let {
|
|
202
|
-
loc
|
|
203
|
-
} = testFuncFirstLine.callee.property;
|
|
204
|
-
const suggest = [];
|
|
205
|
-
|
|
206
|
-
if (testFuncFirstLine.arguments.length) {
|
|
207
|
-
loc = testFuncFirstLine.arguments[1].loc;
|
|
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
226
|
|
|
221
|
-
if (
|
|
227
|
+
if (hasExpectAssertionsAsFirstStatement) {
|
|
228
|
+
hasExpectAssertionsAsFirstStatement = false;
|
|
222
229
|
return;
|
|
223
230
|
}
|
|
224
231
|
|
|
225
232
|
context.report({
|
|
226
|
-
messageId: '
|
|
227
|
-
node
|
|
233
|
+
messageId: 'haveExpectAssertions',
|
|
234
|
+
node,
|
|
235
|
+
suggest: suggestions.map(([messageId, text]) => ({
|
|
236
|
+
messageId,
|
|
237
|
+
fix: fixer => fixer.insertTextBeforeRange([testFn.body.range[0] + 1, testFn.body.range[1]], text)
|
|
238
|
+
}))
|
|
228
239
|
});
|
|
229
240
|
}
|
|
230
241
|
|
|
@@ -95,7 +95,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
95
95
|
} else if (mockFnName === withOnce('mockImplementation', isOnce)) {
|
|
96
96
|
const [arg] = node.arguments;
|
|
97
97
|
|
|
98
|
-
if (!(0, _utils2.isFunction)(arg)) {
|
|
98
|
+
if (!(0, _utils2.isFunction)(arg) || arg.params.length !== 0) {
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -46,9 +46,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
46
46
|
name: __filename,
|
|
47
47
|
meta: {
|
|
48
48
|
messages: {
|
|
49
|
-
// eslint-disable-next-line eslint-plugin/no-unused-message-ids
|
|
50
49
|
unbound: DEFAULT_MESSAGE,
|
|
51
|
-
// eslint-disable-next-line eslint-plugin/no-unused-message-ids
|
|
52
50
|
unboundWithoutThisAnnotation: DEFAULT_MESSAGE
|
|
53
51
|
},
|
|
54
52
|
schema: [],
|
|
@@ -81,6 +81,8 @@ const resolvePossibleAliasedGlobal = (global, context) => {
|
|
|
81
81
|
return null;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
const parseJestFnCallCache = new WeakMap();
|
|
85
|
+
|
|
84
86
|
const parseJestFnCall = (node, context) => {
|
|
85
87
|
const jestFnCall = parseJestFnCallWithReason(node, context);
|
|
86
88
|
|
|
@@ -94,6 +96,20 @@ const parseJestFnCall = (node, context) => {
|
|
|
94
96
|
exports.parseJestFnCall = parseJestFnCall;
|
|
95
97
|
|
|
96
98
|
const parseJestFnCallWithReason = (node, context) => {
|
|
99
|
+
let parsedJestFnCall = parseJestFnCallCache.get(node);
|
|
100
|
+
|
|
101
|
+
if (parsedJestFnCall) {
|
|
102
|
+
return parsedJestFnCall;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
parsedJestFnCall = parseJestFnCallWithReasonInner(node, context);
|
|
106
|
+
parseJestFnCallCache.set(node, parsedJestFnCall);
|
|
107
|
+
return parsedJestFnCall;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
exports.parseJestFnCallWithReason = parseJestFnCallWithReason;
|
|
111
|
+
|
|
112
|
+
const parseJestFnCallWithReasonInner = (node, context) => {
|
|
97
113
|
var _resolved$original, _node$parent2, _node$parent3;
|
|
98
114
|
|
|
99
115
|
const chain = getNodeChain(node);
|
|
@@ -179,8 +195,6 @@ const parseJestFnCallWithReason = (node, context) => {
|
|
|
179
195
|
};
|
|
180
196
|
};
|
|
181
197
|
|
|
182
|
-
exports.parseJestFnCallWithReason = parseJestFnCallWithReason;
|
|
183
|
-
|
|
184
198
|
const findModifiersAndMatcher = members => {
|
|
185
199
|
const modifiers = [];
|
|
186
200
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-jest",
|
|
3
|
-
"version": "26.8.
|
|
3
|
+
"version": "26.8.5",
|
|
4
4
|
"description": "ESLint rules for Jest",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0",
|
|
121
121
|
"eslint-config-prettier": "^8.3.0",
|
|
122
122
|
"eslint-plugin-eslint-comments": "^3.1.2",
|
|
123
|
-
"eslint-plugin-eslint-plugin": "^
|
|
123
|
+
"eslint-plugin-eslint-plugin": "^4.0.0",
|
|
124
124
|
"eslint-plugin-import": "^2.25.1",
|
|
125
125
|
"eslint-plugin-node": "^11.0.0",
|
|
126
126
|
"eslint-plugin-prettier": "^3.4.1",
|