eslint-plugin-jest 26.8.7 → 27.1.6

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.
Files changed (114) hide show
  1. package/README.md +82 -78
  2. package/docs/rules/consistent-test-it.md +9 -4
  3. package/docs/rules/expect-expect.md +5 -0
  4. package/docs/rules/max-expects.md +3 -1
  5. package/docs/rules/max-nested-describe.md +3 -1
  6. package/docs/rules/no-alias-methods.md +13 -2
  7. package/docs/rules/no-commented-out-tests.md +6 -1
  8. package/docs/rules/no-conditional-expect.md +7 -2
  9. package/docs/rules/no-conditional-in-test.md +3 -1
  10. package/docs/rules/no-deprecated-functions.md +14 -7
  11. package/docs/rules/no-disabled-tests.md +6 -1
  12. package/docs/rules/no-done-callback.md +9 -1
  13. package/docs/rules/no-duplicate-hooks.md +3 -1
  14. package/docs/rules/no-export.md +6 -1
  15. package/docs/rules/no-focused-tests.md +10 -1
  16. package/docs/rules/no-hooks.md +3 -1
  17. package/docs/rules/no-identical-title.md +6 -1
  18. package/docs/rules/no-if.md +4 -4
  19. package/docs/rules/no-interpolation-in-snapshots.md +6 -1
  20. package/docs/rules/no-jasmine-globals.md +10 -2
  21. package/docs/rules/no-large-snapshots.md +4 -2
  22. package/docs/rules/no-mocks-import.md +6 -1
  23. package/docs/rules/no-restricted-jest-methods.md +51 -0
  24. package/docs/rules/no-restricted-matchers.md +19 -4
  25. package/docs/rules/no-standalone-expect.md +6 -1
  26. package/docs/rules/no-test-prefixes.md +9 -1
  27. package/docs/rules/no-test-return-statement.md +2 -0
  28. package/docs/rules/prefer-called-with.md +2 -0
  29. package/docs/rules/prefer-comparison-matcher.md +5 -0
  30. package/docs/rules/prefer-each.md +56 -0
  31. package/docs/rules/prefer-equality-matcher.md +5 -0
  32. package/docs/rules/prefer-expect-assertions.md +5 -2
  33. package/docs/rules/prefer-expect-resolves.md +8 -1
  34. package/docs/rules/prefer-hooks-in-order.md +3 -1
  35. package/docs/rules/prefer-hooks-on-top.md +3 -1
  36. package/docs/rules/prefer-lowercase-title.md +5 -0
  37. package/docs/rules/prefer-mock-promise-shorthand.md +6 -1
  38. package/docs/rules/prefer-snapshot-hint.md +2 -0
  39. package/docs/rules/prefer-spy-on.md +5 -2
  40. package/docs/rules/prefer-strict-equal.md +5 -2
  41. package/docs/rules/prefer-to-be.md +8 -0
  42. package/docs/rules/prefer-to-contain.md +8 -2
  43. package/docs/rules/prefer-to-have-length.md +8 -2
  44. package/docs/rules/prefer-todo.md +5 -2
  45. package/docs/rules/require-hook.md +2 -0
  46. package/docs/rules/require-to-throw-message.md +2 -2
  47. package/docs/rules/require-top-level-describe.md +5 -1
  48. package/docs/rules/unbound-method.md +7 -2
  49. package/docs/rules/valid-describe-callback.md +6 -1
  50. package/docs/rules/valid-expect-in-promise.md +6 -1
  51. package/docs/rules/valid-expect.md +5 -2
  52. package/docs/rules/valid-title.md +9 -1
  53. package/lib/index.js +14 -25
  54. package/lib/processors/snapshot-processor.js +3 -5
  55. package/lib/rules/consistent-test-it.js +1 -19
  56. package/lib/rules/expect-expect.js +1 -18
  57. package/lib/rules/max-expects.js +0 -16
  58. package/lib/rules/max-nested-describe.js +0 -13
  59. package/lib/rules/no-alias-methods.js +1 -10
  60. package/lib/rules/no-commented-out-tests.js +0 -10
  61. package/lib/rules/no-conditional-expect.js +2 -23
  62. package/lib/rules/no-conditional-in-test.js +0 -9
  63. package/lib/rules/no-deprecated-functions.js +2 -18
  64. package/lib/rules/no-disabled-tests.js +3 -19
  65. package/lib/rules/no-done-callback.js +20 -47
  66. package/lib/rules/no-duplicate-hooks.js +0 -12
  67. package/lib/rules/no-export.js +0 -12
  68. package/lib/rules/no-focused-tests.js +1 -17
  69. package/lib/rules/no-hooks.js +0 -7
  70. package/lib/rules/no-identical-title.js +0 -19
  71. package/lib/rules/no-if.js +0 -24
  72. package/lib/rules/no-interpolation-in-snapshots.js +0 -9
  73. package/lib/rules/no-jasmine-globals.js +1 -23
  74. package/lib/rules/no-large-snapshots.js +4 -24
  75. package/lib/rules/no-mocks-import.js +0 -12
  76. package/lib/rules/no-restricted-jest-methods.js +56 -0
  77. package/lib/rules/no-restricted-matchers.js +13 -28
  78. package/lib/rules/no-standalone-expect.js +7 -33
  79. package/lib/rules/no-test-prefixes.js +1 -13
  80. package/lib/rules/no-test-return-statement.js +0 -12
  81. package/lib/rules/prefer-called-with.js +0 -10
  82. package/lib/rules/prefer-comparison-matcher.js +8 -33
  83. package/lib/rules/prefer-each.js +80 -0
  84. package/lib/rules/prefer-equality-matcher.js +12 -25
  85. package/lib/rules/prefer-expect-assertions.js +14 -60
  86. package/lib/rules/prefer-expect-resolves.js +0 -12
  87. package/lib/rules/prefer-hooks-in-order.js +2 -16
  88. package/lib/rules/prefer-hooks-on-top.js +0 -9
  89. package/lib/rules/prefer-lowercase-title.js +0 -23
  90. package/lib/rules/prefer-mock-promise-shorthand.js +5 -26
  91. package/lib/rules/prefer-snapshot-hint.js +8 -34
  92. package/lib/rules/prefer-spy-on.js +0 -17
  93. package/lib/rules/prefer-strict-equal.js +1 -11
  94. package/lib/rules/prefer-to-be.js +12 -37
  95. package/lib/rules/prefer-to-contain.js +11 -21
  96. package/lib/rules/prefer-to-have-length.js +4 -16
  97. package/lib/rules/prefer-todo.js +2 -18
  98. package/lib/rules/require-hook.js +1 -25
  99. package/lib/rules/require-to-throw-message.js +0 -9
  100. package/lib/rules/require-top-level-describe.js +1 -18
  101. package/lib/rules/unbound-method.js +3 -30
  102. package/lib/rules/utils/accessors.js +6 -18
  103. package/lib/rules/utils/detectJestVersion.js +2 -7
  104. package/lib/rules/utils/followTypeAssertionChain.js +0 -4
  105. package/lib/rules/utils/index.js +0 -10
  106. package/lib/rules/utils/misc.js +14 -47
  107. package/lib/rules/utils/parseJestFnCall.js +51 -154
  108. package/lib/rules/valid-describe-callback.js +0 -17
  109. package/lib/rules/valid-expect-in-promise.js +28 -95
  110. package/lib/rules/valid-expect.js +5 -48
  111. package/lib/rules/valid-title.js +5 -40
  112. package/package.json +20 -16
  113. package/docs/rules/no-jest-import.md +0 -20
  114. package/lib/rules/no-jest-import.js +0 -48
@@ -4,40 +4,30 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _utils = require("@typescript-eslint/utils");
9
-
10
8
  var _utils2 = require("./utils");
11
-
12
9
  const isPromiseChainCall = node => {
13
10
  if (node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property)) {
14
11
  // promise methods should have at least 1 argument
15
12
  if (node.arguments.length === 0) {
16
13
  return false;
17
14
  }
18
-
19
15
  switch ((0, _utils2.getAccessorValue)(node.callee.property)) {
20
16
  case 'then':
21
17
  return node.arguments.length < 3;
22
-
23
18
  case 'catch':
24
19
  case 'finally':
25
20
  return node.arguments.length < 2;
26
21
  }
27
22
  }
28
-
29
23
  return false;
30
24
  };
31
-
32
25
  const isTestCaseCallWithCallbackArg = (node, context) => {
33
26
  const jestCallFn = (0, _utils2.parseJestFnCall)(node, context);
34
-
35
27
  if ((jestCallFn === null || jestCallFn === void 0 ? void 0 : jestCallFn.type) !== 'test') {
36
28
  return false;
37
29
  }
38
-
39
30
  const isJestEach = jestCallFn.members.some(s => (0, _utils2.getAccessorValue)(s) === 'each');
40
-
41
31
  if (isJestEach && node.callee.type !== _utils.AST_NODE_TYPES.TaggedTemplateExpression) {
42
32
  // isJestEach but not a TaggedTemplateExpression, so this must be
43
33
  // the `jest.each([])()` syntax which this rule doesn't support due
@@ -45,137 +35,109 @@ const isTestCaseCallWithCallbackArg = (node, context) => {
45
35
  // so we return true to trigger bailout
46
36
  return true;
47
37
  }
48
-
49
38
  const [, callback] = node.arguments;
50
39
  const callbackArgIndex = Number(isJestEach);
51
40
  return callback && (0, _utils2.isFunction)(callback) && callback.params.length === 1 + callbackArgIndex;
52
41
  };
53
-
54
42
  const isPromiseMethodThatUsesValue = (node, identifier) => {
55
43
  const {
56
44
  name
57
45
  } = identifier;
58
-
59
46
  if (node.argument === null) {
60
47
  return false;
61
48
  }
62
-
63
49
  if (node.argument.type === _utils.AST_NODE_TYPES.CallExpression && node.argument.arguments.length > 0) {
64
50
  const nodeName = (0, _utils2.getNodeName)(node.argument);
65
-
66
51
  if (['Promise.all', 'Promise.allSettled'].includes(nodeName)) {
67
52
  const [firstArg] = node.argument.arguments;
68
-
69
53
  if (firstArg.type === _utils.AST_NODE_TYPES.ArrayExpression && firstArg.elements.some(nod => (0, _utils2.isIdentifier)(nod, name))) {
70
54
  return true;
71
55
  }
72
56
  }
73
-
74
57
  if (['Promise.resolve', 'Promise.reject'].includes(nodeName) && node.argument.arguments.length === 1) {
75
58
  return (0, _utils2.isIdentifier)(node.argument.arguments[0], name);
76
59
  }
77
60
  }
78
-
79
61
  return (0, _utils2.isIdentifier)(node.argument, name);
80
62
  };
63
+
81
64
  /**
82
65
  * Attempts to determine if the runtime value represented by the given `identifier`
83
66
  * is `await`ed within the given array of elements
84
67
  */
85
-
86
-
87
68
  const isValueAwaitedInElements = (name, elements) => {
88
69
  for (const element of elements) {
89
70
  if (element.type === _utils.AST_NODE_TYPES.AwaitExpression && (0, _utils2.isIdentifier)(element.argument, name)) {
90
71
  return true;
91
72
  }
92
-
93
73
  if (element.type === _utils.AST_NODE_TYPES.ArrayExpression && isValueAwaitedInElements(name, element.elements)) {
94
74
  return true;
95
75
  }
96
76
  }
97
-
98
77
  return false;
99
78
  };
79
+
100
80
  /**
101
81
  * Attempts to determine if the runtime value represented by the given `identifier`
102
82
  * is `await`ed as an argument along the given call expression
103
83
  */
104
-
105
-
106
84
  const isValueAwaitedInArguments = (name, call) => {
107
85
  let node = call;
108
-
109
86
  while (node) {
110
87
  if (node.type === _utils.AST_NODE_TYPES.CallExpression) {
111
88
  if (isValueAwaitedInElements(name, node.arguments)) {
112
89
  return true;
113
90
  }
114
-
115
91
  node = node.callee;
116
92
  }
117
-
118
93
  if (node.type !== _utils.AST_NODE_TYPES.MemberExpression) {
119
94
  break;
120
95
  }
121
-
122
96
  node = node.object;
123
97
  }
124
-
125
98
  return false;
126
99
  };
127
-
128
100
  const getLeftMostCallExpression = call => {
129
101
  let leftMostCallExpression = call;
130
102
  let node = call;
131
-
132
103
  while (node) {
133
104
  if (node.type === _utils.AST_NODE_TYPES.CallExpression) {
134
105
  leftMostCallExpression = node;
135
106
  node = node.callee;
136
107
  }
137
-
138
108
  if (node.type !== _utils.AST_NODE_TYPES.MemberExpression) {
139
109
  break;
140
110
  }
141
-
142
111
  node = node.object;
143
112
  }
144
-
145
113
  return leftMostCallExpression;
146
114
  };
115
+
147
116
  /**
148
117
  * Attempts to determine if the runtime value represented by the given `identifier`
149
118
  * is `await`ed or `return`ed within the given `body` of statements
150
119
  */
151
-
152
-
153
120
  const isValueAwaitedOrReturned = (identifier, body, context) => {
154
121
  const {
155
122
  name
156
123
  } = identifier;
157
-
158
124
  for (const node of body) {
159
125
  // skip all nodes that are before this identifier, because they'd probably
160
126
  // be affecting a different runtime value (e.g. due to reassignment)
161
127
  if (node.range[0] <= identifier.range[0]) {
162
128
  continue;
163
129
  }
164
-
165
130
  if (node.type === _utils.AST_NODE_TYPES.ReturnStatement) {
166
131
  return isPromiseMethodThatUsesValue(node, identifier);
167
132
  }
168
-
169
133
  if (node.type === _utils.AST_NODE_TYPES.ExpressionStatement) {
170
134
  // it's possible that we're awaiting the value as an argument
171
135
  if (node.expression.type === _utils.AST_NODE_TYPES.CallExpression) {
172
136
  if (isValueAwaitedInArguments(name, node.expression)) {
173
137
  return true;
174
138
  }
175
-
176
139
  const leftMostCall = getLeftMostCallExpression(node.expression);
177
140
  const jestFnCall = (0, _utils2.parseJestFnCall)(node.expression, context);
178
-
179
141
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect' && leftMostCall.arguments.length > 0 && (0, _utils2.isIdentifier)(leftMostCall.arguments[0], name)) {
180
142
  if (jestFnCall.members.some(m => {
181
143
  const v = (0, _utils2.getAccessorValue)(m);
@@ -185,103 +147,86 @@ const isValueAwaitedOrReturned = (identifier, body, context) => {
185
147
  }
186
148
  }
187
149
  }
188
-
189
150
  if (node.expression.type === _utils.AST_NODE_TYPES.AwaitExpression && isPromiseMethodThatUsesValue(node.expression, identifier)) {
190
151
  return true;
191
- } // (re)assignment changes the runtime value, so if we've not found an
192
- // await or return already we act as if we've reached the end of the body
193
-
152
+ }
194
153
 
154
+ // (re)assignment changes the runtime value, so if we've not found an
155
+ // await or return already we act as if we've reached the end of the body
195
156
  if (node.expression.type === _utils.AST_NODE_TYPES.AssignmentExpression) {
196
157
  var _getNodeName;
197
-
198
158
  // unless we're assigning to the same identifier, in which case
199
159
  // we might be chaining off the existing promise value
200
160
  if ((0, _utils2.isIdentifier)(node.expression.left, name) && (_getNodeName = (0, _utils2.getNodeName)(node.expression.right)) !== null && _getNodeName !== void 0 && _getNodeName.startsWith(`${name}.`) && isPromiseChainCall(node.expression.right)) {
201
161
  continue;
202
162
  }
203
-
204
163
  break;
205
164
  }
206
165
  }
207
-
208
166
  if (node.type === _utils.AST_NODE_TYPES.BlockStatement && isValueAwaitedOrReturned(identifier, node.body, context)) {
209
167
  return true;
210
168
  }
211
169
  }
212
-
213
170
  return false;
214
171
  };
215
-
216
172
  const findFirstBlockBodyUp = node => {
217
173
  let parent = node;
218
-
219
174
  while (parent) {
220
175
  if (parent.type === _utils.AST_NODE_TYPES.BlockStatement) {
221
176
  return parent.body;
222
177
  }
223
-
224
178
  parent = parent.parent;
225
179
  }
226
- /* istanbul ignore next */
227
-
228
180
 
181
+ /* istanbul ignore next */
229
182
  throw new Error(`Could not find BlockStatement - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
230
183
  };
231
-
232
184
  const isDirectlyWithinTestCaseCall = (node, context) => {
233
185
  let parent = node;
234
-
235
186
  while (parent) {
236
187
  if ((0, _utils2.isFunction)(parent)) {
237
188
  var _parent;
238
-
239
189
  parent = parent.parent;
240
190
  return ((_parent = parent) === null || _parent === void 0 ? void 0 : _parent.type) === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isTypeOfJestFnCall)(parent, context, ['test']);
241
191
  }
242
-
243
192
  parent = parent.parent;
244
193
  }
245
-
246
194
  return false;
247
195
  };
248
-
249
196
  const isVariableAwaitedOrReturned = (variable, context) => {
250
- const body = findFirstBlockBodyUp(variable); // it's pretty much impossible for us to track destructuring assignments,
251
- // so we return true to bailout gracefully
197
+ const body = findFirstBlockBodyUp(variable);
252
198
 
199
+ // it's pretty much impossible for us to track destructuring assignments,
200
+ // so we return true to bailout gracefully
253
201
  if (!(0, _utils2.isIdentifier)(variable.id)) {
254
202
  return true;
255
203
  }
256
-
257
204
  return isValueAwaitedOrReturned(variable.id, body, context);
258
205
  };
259
-
260
206
  var _default = (0, _utils2.createRule)({
261
207
  name: __filename,
262
208
  meta: {
263
209
  docs: {
264
210
  category: 'Best Practices',
265
- description: 'Ensure promises that have expectations in their chain are valid',
211
+ description: 'Require promises that have expectations in their chain to be valid',
266
212
  recommended: 'error'
267
213
  },
268
214
  messages: {
269
- expectInFloatingPromise: "This promise should either be returned or awaited to ensure the expects in it's chain are called"
215
+ expectInFloatingPromise: 'This promise should either be returned or awaited to ensure the expects in its chain are called'
270
216
  },
271
217
  type: 'suggestion',
272
218
  schema: []
273
219
  },
274
220
  defaultOptions: [],
275
-
276
221
  create(context) {
277
- let inTestCaseWithDoneCallback = false; // an array of booleans representing each promise chain we enter, with the
222
+ let inTestCaseWithDoneCallback = false;
223
+ // an array of booleans representing each promise chain we enter, with the
278
224
  // boolean value representing if we think a given chain contains an expect
279
225
  // in it's body.
280
226
  //
281
227
  // since we only care about the inner-most chain, we represent the state in
282
228
  // reverse with the inner-most being the first item, as that makes it
283
229
  // slightly less code to assign to by not needing to know the length
284
-
285
230
  const chains = [];
286
231
  return {
287
232
  CallExpression(node) {
@@ -290,22 +235,21 @@ var _default = (0, _utils2.createRule)({
290
235
  if (isTestCaseCallWithCallbackArg(node, context)) {
291
236
  inTestCaseWithDoneCallback = true;
292
237
  return;
293
- } // if this call expression is a promise chain, add it to the stack with
294
- // value of "false", as we assume there are no expect calls initially
295
-
238
+ }
296
239
 
240
+ // if this call expression is a promise chain, add it to the stack with
241
+ // value of "false", as we assume there are no expect calls initially
297
242
  if (isPromiseChainCall(node)) {
298
243
  chains.unshift(false);
299
244
  return;
300
- } // if we're within a promise chain, and this call expression looks like
301
- // an expect call, mark the deepest chain as having an expect call
302
-
245
+ }
303
246
 
247
+ // if we're within a promise chain, and this call expression looks like
248
+ // an expect call, mark the deepest chain as having an expect call
304
249
  if (chains.length > 0 && (0, _utils2.isTypeOfJestFnCall)(node, context, ['expect'])) {
305
250
  chains[0] = true;
306
251
  }
307
252
  },
308
-
309
253
  'CallExpression:exit'(node) {
310
254
  // there are too many ways that the "done" argument could be used to
311
255
  // make promises containing expects safe in a test for us to be able to
@@ -314,71 +258,60 @@ var _default = (0, _utils2.createRule)({
314
258
  if ((0, _utils2.isTypeOfJestFnCall)(node, context, ['test'])) {
315
259
  inTestCaseWithDoneCallback = false;
316
260
  }
317
-
318
261
  return;
319
262
  }
320
-
321
263
  if (!isPromiseChainCall(node)) {
322
264
  return;
323
- } // since we're exiting this call expression (which is a promise chain)
324
- // we remove it from the stack of chains, since we're unwinding
265
+ }
325
266
 
267
+ // since we're exiting this call expression (which is a promise chain)
268
+ // we remove it from the stack of chains, since we're unwinding
269
+ const hasExpectCall = chains.shift();
326
270
 
327
- const hasExpectCall = chains.shift(); // if the promise chain we're exiting doesn't contain an expect,
271
+ // if the promise chain we're exiting doesn't contain an expect,
328
272
  // then we don't need to check it for anything
329
-
330
273
  if (!hasExpectCall) {
331
274
  return;
332
275
  }
333
-
334
276
  const {
335
277
  parent
336
- } = (0, _utils2.findTopMostCallExpression)(node); // if we don't have a parent (which is technically impossible at runtime)
278
+ } = (0, _utils2.findTopMostCallExpression)(node);
279
+
280
+ // if we don't have a parent (which is technically impossible at runtime)
337
281
  // or our parent is not directly within the test case, we stop checking
338
282
  // because we're most likely in the body of a function being defined
339
283
  // within the test, which we can't track
340
-
341
284
  if (!parent || !isDirectlyWithinTestCaseCall(parent, context)) {
342
285
  return;
343
286
  }
344
-
345
287
  switch (parent.type) {
346
288
  case _utils.AST_NODE_TYPES.VariableDeclarator:
347
289
  {
348
290
  if (isVariableAwaitedOrReturned(parent, context)) {
349
291
  return;
350
292
  }
351
-
352
293
  break;
353
294
  }
354
-
355
295
  case _utils.AST_NODE_TYPES.AssignmentExpression:
356
296
  {
357
297
  if (parent.left.type === _utils.AST_NODE_TYPES.Identifier && isValueAwaitedOrReturned(parent.left, findFirstBlockBodyUp(parent), context)) {
358
298
  return;
359
299
  }
360
-
361
300
  break;
362
301
  }
363
-
364
302
  case _utils.AST_NODE_TYPES.ExpressionStatement:
365
303
  break;
366
-
367
304
  case _utils.AST_NODE_TYPES.ReturnStatement:
368
305
  case _utils.AST_NODE_TYPES.AwaitExpression:
369
306
  default:
370
307
  return;
371
308
  }
372
-
373
309
  context.report({
374
310
  messageId: 'expectInFloatingPromise',
375
311
  node: parent
376
312
  });
377
313
  }
378
-
379
314
  };
380
315
  }
381
-
382
316
  });
383
-
384
317
  exports.default = _default;
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _utils = require("@typescript-eslint/utils");
9
-
10
8
  var _utils2 = require("./utils");
11
-
12
9
  /*
13
10
  * This implementation is ported from from eslint-plugin-jasmine.
14
11
  * MIT license, Tom Vincent.
@@ -25,52 +22,38 @@ const getPromiseCallExpressionNode = node => {
25
22
  if (node.type === _utils.AST_NODE_TYPES.ArrayExpression && node.parent && node.parent.type === _utils.AST_NODE_TYPES.CallExpression) {
26
23
  node = node.parent;
27
24
  }
28
-
29
25
  if (node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.object, 'Promise') && node.parent) {
30
26
  return node;
31
27
  }
32
-
33
28
  return null;
34
29
  };
35
-
36
30
  const findPromiseCallExpressionNode = node => {
37
31
  var _node$parent;
38
-
39
32
  return (_node$parent = node.parent) !== null && _node$parent !== void 0 && _node$parent.parent && [_utils.AST_NODE_TYPES.CallExpression, _utils.AST_NODE_TYPES.ArrayExpression].includes(node.parent.type) ? getPromiseCallExpressionNode(node.parent) : null;
40
33
  };
41
-
42
34
  const getParentIfThenified = node => {
43
35
  var _node$parent2;
44
-
45
36
  const grandParentNode = (_node$parent2 = node.parent) === null || _node$parent2 === void 0 ? void 0 : _node$parent2.parent;
46
-
47
37
  if (grandParentNode && grandParentNode.type === _utils.AST_NODE_TYPES.CallExpression && grandParentNode.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(grandParentNode.callee.property) && ['then', 'catch'].includes((0, _utils2.getAccessorValue)(grandParentNode.callee.property)) && grandParentNode.parent) {
48
38
  // Just in case `then`s are chained look one above.
49
39
  return getParentIfThenified(grandParentNode);
50
40
  }
51
-
52
41
  return node;
53
42
  };
54
-
55
43
  const isAcceptableReturnNode = (node, allowReturn) => {
56
44
  if (allowReturn && node.type === _utils.AST_NODE_TYPES.ReturnStatement) {
57
45
  return true;
58
46
  }
59
-
60
47
  if (node.type === _utils.AST_NODE_TYPES.ConditionalExpression && node.parent) {
61
48
  return isAcceptableReturnNode(node.parent, allowReturn);
62
49
  }
63
-
64
50
  return [_utils.AST_NODE_TYPES.ArrowFunctionExpression, _utils.AST_NODE_TYPES.AwaitExpression].includes(node.type);
65
51
  };
66
-
67
52
  const promiseArrayExceptionKey = ({
68
53
  start,
69
54
  end
70
55
  }) => `${start.line}:${start.column}-${end.line}:${end.column}`;
71
-
72
56
  const defaultAsyncMatchers = ['toReject', 'toResolve'];
73
-
74
57
  var _default = (0, _utils2.createRule)({
75
58
  name: __filename,
76
59
  meta: {
@@ -120,7 +103,6 @@ var _default = (0, _utils2.createRule)({
120
103
  minArgs: 1,
121
104
  maxArgs: 1
122
105
  }],
123
-
124
106
  create(context, [{
125
107
  alwaysAwait,
126
108
  asyncMatchers = defaultAsyncMatchers,
@@ -129,8 +111,8 @@ var _default = (0, _utils2.createRule)({
129
111
  }]) {
130
112
  // Context state
131
113
  const arrayExceptions = new Set();
132
-
133
114
  const pushPromiseArrayException = loc => arrayExceptions.add(promiseArrayExceptionKey(loc));
115
+
134
116
  /**
135
117
  * Promise method that accepts an array of promises,
136
118
  * (eg. Promise.all), will throw warnings for the each
@@ -138,37 +120,27 @@ var _default = (0, _utils2.createRule)({
138
120
  * multiple warnings, we check if there is a warning in
139
121
  * the given location.
140
122
  */
141
-
142
-
143
123
  const promiseArrayExceptionExists = loc => arrayExceptions.has(promiseArrayExceptionKey(loc));
144
-
145
124
  const findTopMostMemberExpression = node => {
146
125
  let topMostMemberExpression = node;
147
126
  let {
148
127
  parent
149
128
  } = node;
150
-
151
129
  while (parent) {
152
130
  if (parent.type !== _utils.AST_NODE_TYPES.MemberExpression) {
153
131
  break;
154
132
  }
155
-
156
133
  topMostMemberExpression = parent;
157
134
  parent = parent.parent;
158
135
  }
159
-
160
136
  return topMostMemberExpression;
161
137
  };
162
-
163
138
  return {
164
139
  CallExpression(node) {
165
140
  const jestFnCall = (0, _utils2.parseJestFnCallWithReason)(node, context);
166
-
167
141
  if (typeof jestFnCall === 'string') {
168
142
  var _node$parent3;
169
-
170
143
  const reportingNode = ((_node$parent3 = node.parent) === null || _node$parent3 === void 0 ? void 0 : _node$parent3.type) === _utils.AST_NODE_TYPES.MemberExpression ? findTopMostMemberExpression(node.parent).property : node;
171
-
172
144
  if (jestFnCall === 'matcher-not-found') {
173
145
  context.report({
174
146
  messageId: 'matcherNotFound',
@@ -176,14 +148,12 @@ var _default = (0, _utils2.createRule)({
176
148
  });
177
149
  return;
178
150
  }
179
-
180
151
  if (jestFnCall === 'matcher-not-called') {
181
152
  context.report({
182
153
  messageId: (0, _utils2.isSupportedAccessor)(reportingNode) && _utils2.ModifierName.hasOwnProperty((0, _utils2.getAccessorValue)(reportingNode)) ? 'matcherNotFound' : 'matcherNotCalled',
183
154
  node: reportingNode
184
155
  });
185
156
  }
186
-
187
157
  if (jestFnCall === 'modifier-unknown') {
188
158
  context.report({
189
159
  messageId: 'modifierUnknown',
@@ -191,20 +161,16 @@ var _default = (0, _utils2.createRule)({
191
161
  });
192
162
  return;
193
163
  }
194
-
195
164
  return;
196
165
  } else if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
197
166
  return;
198
167
  }
199
-
200
168
  const {
201
169
  parent: expect
202
170
  } = jestFnCall.head.node;
203
-
204
171
  if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
205
172
  return;
206
173
  }
207
-
208
174
  if (expect.arguments.length < minArgs) {
209
175
  const expectLength = (0, _utils2.getAccessorValue)(jestFnCall.head.node).length;
210
176
  const loc = {
@@ -227,7 +193,6 @@ var _default = (0, _utils2.createRule)({
227
193
  loc
228
194
  });
229
195
  }
230
-
231
196
  if (expect.arguments.length > maxArgs) {
232
197
  const {
233
198
  start
@@ -252,13 +217,11 @@ var _default = (0, _utils2.createRule)({
252
217
  loc
253
218
  });
254
219
  }
255
-
256
220
  const {
257
221
  matcher
258
222
  } = jestFnCall;
259
223
  const parentNode = matcher.parent.parent;
260
224
  const shouldBeAwaited = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) !== 'not') || asyncMatchers.includes((0, _utils2.getAccessorValue)(matcher));
261
-
262
225
  if (!(parentNode !== null && parentNode !== void 0 && parentNode.parent) || !shouldBeAwaited) {
263
226
  return;
264
227
  }
@@ -266,8 +229,6 @@ var _default = (0, _utils2.createRule)({
266
229
  * If parent node is an array expression, we'll report the warning,
267
230
  * for the array object, not for each individual assertion.
268
231
  */
269
-
270
-
271
232
  const isParentArrayExpression = parentNode.parent.type === _utils.AST_NODE_TYPES.ArrayExpression;
272
233
  const orReturned = alwaysAwait ? '' : ' or returned';
273
234
  /**
@@ -275,12 +236,12 @@ var _default = (0, _utils2.createRule)({
275
236
  * In that case our target CallExpression node is the one with
276
237
  * the last `then` or `catch` statement.
277
238
  */
278
-
279
239
  const targetNode = getParentIfThenified(parentNode);
280
240
  const finalNode = findPromiseCallExpressionNode(targetNode) || targetNode;
281
-
282
- if (finalNode.parent && // If node is not awaited or returned
283
- !isAcceptableReturnNode(finalNode.parent, !alwaysAwait) && // if we didn't warn user already
241
+ if (finalNode.parent &&
242
+ // If node is not awaited or returned
243
+ !isAcceptableReturnNode(finalNode.parent, !alwaysAwait) &&
244
+ // if we didn't warn user already
284
245
  !promiseArrayExceptionExists(finalNode.loc)) {
285
246
  context.report({
286
247
  loc: finalNode.loc,
@@ -290,16 +251,12 @@ var _default = (0, _utils2.createRule)({
290
251
  messageId: finalNode === targetNode ? 'asyncMustBeAwaited' : 'promisesWithAsyncAssertionsMustBeAwaited',
291
252
  node
292
253
  });
293
-
294
254
  if (isParentArrayExpression) {
295
255
  pushPromiseArrayException(finalNode.loc);
296
256
  }
297
257
  }
298
258
  }
299
-
300
259
  };
301
260
  }
302
-
303
261
  });
304
-
305
262
  exports.default = _default;