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 width="150" height="150" src="https://eslint.org/assets/images/logo/eslint-logo-color.svg">
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 isExpectAssertionsOrHasAssertionsCall = expression => expression.type === _utils.AST_NODE_TYPES.CallExpression && expression.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(expression.callee.object, 'expect') && (0, _utils2.isSupportedAccessor)(expression.callee.property) && ['assertions', 'hasAssertions'].includes((0, _utils2.getAccessorValue)(expression.callee.property));
12
+ const isFirstStatement = node => {
13
+ let parent = node;
13
14
 
14
- const isFirstLineExprStmt = functionBody => functionBody[0] && functionBody[0].type === _utils.AST_NODE_TYPES.ExpressionStatement;
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 (arg.type === _utils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value)) {
227
+ if (hasExpectAssertionsAsFirstStatement) {
228
+ hasExpectAssertionsAsFirstStatement = false;
222
229
  return;
223
230
  }
224
231
 
225
232
  context.report({
226
- messageId: 'assertionsRequiresNumberArgument',
227
- node: arg
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.2",
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": "^5.0.0",
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",