eslint-plugin-jest 26.6.0 → 26.8.1

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.
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.createRule = exports.TestCaseName = exports.HookName = exports.DescribeAlias = void 0;
6
+ exports.getFirstMatcherArg = exports.findTopMostCallExpression = exports.createRule = exports.TestCaseName = exports.ModifierName = exports.HookName = exports.EqualityMatcher = exports.DescribeAlias = void 0;
7
7
  exports.getNodeName = getNodeName;
8
- exports.replaceAccessorFixer = exports.isFunction = exports.hasOnlyOneArgument = exports.getTestCallExpressionsFromDeclaredVariables = void 0;
8
+ exports.replaceAccessorFixer = exports.isFunction = exports.isBooleanLiteral = exports.hasOnlyOneArgument = exports.getTestCallExpressionsFromDeclaredVariables = void 0;
9
9
 
10
10
  var _path = require("path");
11
11
 
@@ -15,6 +15,8 @@ var _package = require("../../../package.json");
15
15
 
16
16
  var _accessors = require("./accessors");
17
17
 
18
+ var _followTypeAssertionChain = require("./followTypeAssertionChain");
19
+
18
20
  var _parseJestFnCall = require("./parseJestFnCall");
19
21
 
20
22
  const REPO_URL = 'https://github.com/jest-community/eslint-plugin-jest';
@@ -70,6 +72,24 @@ exports.HookName = HookName;
70
72
  HookName["afterEach"] = "afterEach";
71
73
  })(HookName || (exports.HookName = HookName = {}));
72
74
 
75
+ let ModifierName;
76
+ exports.ModifierName = ModifierName;
77
+
78
+ (function (ModifierName) {
79
+ ModifierName["not"] = "not";
80
+ ModifierName["rejects"] = "rejects";
81
+ ModifierName["resolves"] = "resolves";
82
+ })(ModifierName || (exports.ModifierName = ModifierName = {}));
83
+
84
+ let EqualityMatcher;
85
+ exports.EqualityMatcher = EqualityMatcher;
86
+
87
+ (function (EqualityMatcher) {
88
+ EqualityMatcher["toBe"] = "toBe";
89
+ EqualityMatcher["toEqual"] = "toEqual";
90
+ EqualityMatcher["toStrictEqual"] = "toStrictEqual";
91
+ })(EqualityMatcher || (exports.EqualityMatcher = EqualityMatcher = {}));
92
+
73
93
  const joinNames = (a, b) => a && b ? `${a}.${b}` : null;
74
94
 
75
95
  function getNodeName(node) {
@@ -117,4 +137,45 @@ const replaceAccessorFixer = (fixer, node, text) => {
117
137
  return fixer.replaceText(node, node.type === _utils.AST_NODE_TYPES.Identifier ? text : `'${text}'`);
118
138
  };
119
139
 
120
- exports.replaceAccessorFixer = replaceAccessorFixer;
140
+ exports.replaceAccessorFixer = replaceAccessorFixer;
141
+
142
+ const findTopMostCallExpression = node => {
143
+ let topMostCallExpression = node;
144
+ let {
145
+ parent
146
+ } = node;
147
+
148
+ while (parent) {
149
+ if (parent.type === _utils.AST_NODE_TYPES.CallExpression) {
150
+ topMostCallExpression = parent;
151
+ parent = parent.parent;
152
+ continue;
153
+ }
154
+
155
+ if (parent.type !== _utils.AST_NODE_TYPES.MemberExpression) {
156
+ break;
157
+ }
158
+
159
+ parent = parent.parent;
160
+ }
161
+
162
+ return topMostCallExpression;
163
+ };
164
+
165
+ exports.findTopMostCallExpression = findTopMostCallExpression;
166
+
167
+ const isBooleanLiteral = node => node.type === _utils.AST_NODE_TYPES.Literal && typeof node.value === 'boolean';
168
+
169
+ exports.isBooleanLiteral = isBooleanLiteral;
170
+
171
+ const getFirstMatcherArg = expectFnCall => {
172
+ const [firstArg] = expectFnCall.args;
173
+
174
+ if (firstArg.type === _utils.AST_NODE_TYPES.SpreadElement) {
175
+ return firstArg;
176
+ }
177
+
178
+ return (0, _followTypeAssertionChain.followTypeAssertionChain)(firstArg);
179
+ };
180
+
181
+ exports.getFirstMatcherArg = getFirstMatcherArg;
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getNodeChain = getNodeChain;
7
- exports.scopeHasLocalReference = exports.parseJestFnCall = exports.isTypeOfJestFnCall = void 0;
7
+ exports.scopeHasLocalReference = exports.parseJestFnCallWithReason = exports.parseJestFnCall = exports.isTypeOfJestFnCall = void 0;
8
8
 
9
9
  var _utils = require("@typescript-eslint/utils");
10
10
 
@@ -39,9 +39,10 @@ function getNodeChain(node) {
39
39
  }
40
40
 
41
41
  const determineJestFnType = name => {
42
- // if (name === 'expect') {
43
- // return 'expect';
44
- // }
42
+ if (name === 'expect') {
43
+ return 'expect';
44
+ }
45
+
45
46
  if (name === 'jest') {
46
47
  return 'jest';
47
48
  }
@@ -81,27 +82,23 @@ const resolvePossibleAliasedGlobal = (global, context) => {
81
82
  };
82
83
 
83
84
  const parseJestFnCall = (node, context) => {
84
- var _node$parent, _node$parent2, _resolved$original;
85
+ const jestFnCall = parseJestFnCallWithReason(node, context);
85
86
 
86
- // ensure that we're at the "top" of the function call chain otherwise when
87
- // parsing e.g. x().y.z(), we'll incorrectly find & parse "x()" even though
88
- // the full chain is not a valid jest function call chain
89
- if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) === _utils.AST_NODE_TYPES.CallExpression || ((_node$parent2 = node.parent) === null || _node$parent2 === void 0 ? void 0 : _node$parent2.type) === _utils.AST_NODE_TYPES.MemberExpression) {
87
+ if (typeof jestFnCall === 'string') {
90
88
  return null;
91
89
  }
92
90
 
93
- const chain = getNodeChain(node);
91
+ return jestFnCall;
92
+ };
94
93
 
95
- if (!(chain !== null && chain !== void 0 && chain.length)) {
96
- return null;
97
- } // check that every link in the chain except the last is a member expression
94
+ exports.parseJestFnCall = parseJestFnCall;
98
95
 
96
+ const parseJestFnCallWithReason = (node, context) => {
97
+ var _resolved$original, _node$parent2, _node$parent3;
99
98
 
100
- if (chain.slice(0, chain.length - 1).some(nod => {
101
- var _nod$parent;
99
+ const chain = getNodeChain(node);
102
100
 
103
- return ((_nod$parent = nod.parent) === null || _nod$parent === void 0 ? void 0 : _nod$parent.type) !== _utils.AST_NODE_TYPES.MemberExpression;
104
- })) {
101
+ if (!(chain !== null && chain !== void 0 && chain.length)) {
105
102
  return null;
106
103
  }
107
104
 
@@ -127,21 +124,121 @@ const parseJestFnCall = (node, context) => {
127
124
  const name = (_resolved$original = resolved.original) !== null && _resolved$original !== void 0 ? _resolved$original : resolved.local;
128
125
  const links = [name, ...rest.map(link => (0, _utils2.getAccessorValue)(link))];
129
126
 
130
- if (name !== 'jest' && !ValidJestFnCallChains.includes(links.join('.'))) {
127
+ if (name !== 'jest' && name !== 'expect' && !ValidJestFnCallChains.includes(links.join('.'))) {
131
128
  return null;
132
129
  }
133
130
 
134
- return {
131
+ const parsedJestFnCall = {
135
132
  name,
136
- type: determineJestFnType(name),
137
133
  head: { ...resolved,
138
134
  node: first
139
135
  },
136
+ // every member node must have a member expression as their parent
137
+ // in order to be part of the call chain we're parsing
140
138
  members: rest
141
139
  };
140
+ const type = determineJestFnType(name);
141
+
142
+ if (type === 'expect') {
143
+ const result = parseJestExpectCall(parsedJestFnCall); // if the `expect` call chain is not valid, only report on the topmost node
144
+ // since all members in the chain are likely to get flagged for some reason
145
+
146
+ if (typeof result === 'string' && (0, _utils2.findTopMostCallExpression)(node) !== node) {
147
+ return null;
148
+ }
149
+
150
+ if (result === 'matcher-not-found') {
151
+ var _node$parent;
152
+
153
+ if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) === _utils.AST_NODE_TYPES.MemberExpression) {
154
+ return 'matcher-not-called';
155
+ }
156
+ }
157
+
158
+ return result;
159
+ } // check that every link in the chain except the last is a member expression
160
+
161
+
162
+ if (chain.slice(0, chain.length - 1).some(nod => {
163
+ var _nod$parent;
164
+
165
+ return ((_nod$parent = nod.parent) === null || _nod$parent === void 0 ? void 0 : _nod$parent.type) !== _utils.AST_NODE_TYPES.MemberExpression;
166
+ })) {
167
+ return null;
168
+ } // ensure that we're at the "top" of the function call chain otherwise when
169
+ // parsing e.g. x().y.z(), we'll incorrectly find & parse "x()" even though
170
+ // the full chain is not a valid jest function call chain
171
+
172
+
173
+ if (((_node$parent2 = node.parent) === null || _node$parent2 === void 0 ? void 0 : _node$parent2.type) === _utils.AST_NODE_TYPES.CallExpression || ((_node$parent3 = node.parent) === null || _node$parent3 === void 0 ? void 0 : _node$parent3.type) === _utils.AST_NODE_TYPES.MemberExpression) {
174
+ return null;
175
+ }
176
+
177
+ return { ...parsedJestFnCall,
178
+ type
179
+ };
142
180
  };
143
181
 
144
- exports.parseJestFnCall = parseJestFnCall;
182
+ exports.parseJestFnCallWithReason = parseJestFnCallWithReason;
183
+
184
+ const findModifiersAndMatcher = members => {
185
+ const modifiers = [];
186
+
187
+ for (const member of members) {
188
+ var _member$parent, _member$parent$parent;
189
+
190
+ // check if the member is being called, which means it is the matcher
191
+ // (and also the end of the entire "expect" call chain)
192
+ if (((_member$parent = member.parent) === null || _member$parent === void 0 ? void 0 : _member$parent.type) === _utils.AST_NODE_TYPES.MemberExpression && ((_member$parent$parent = member.parent.parent) === null || _member$parent$parent === void 0 ? void 0 : _member$parent$parent.type) === _utils.AST_NODE_TYPES.CallExpression) {
193
+ return {
194
+ matcher: member,
195
+ args: member.parent.parent.arguments,
196
+ modifiers
197
+ };
198
+ } // otherwise, it should be a modifier
199
+
200
+
201
+ const name = (0, _utils2.getAccessorValue)(member);
202
+
203
+ if (modifiers.length === 0) {
204
+ // the first modifier can be any of the three modifiers
205
+ if (!_utils2.ModifierName.hasOwnProperty(name)) {
206
+ return 'modifier-unknown';
207
+ }
208
+ } else if (modifiers.length === 1) {
209
+ // the second modifier can only be "not"
210
+ if (name !== _utils2.ModifierName.not) {
211
+ return 'modifier-unknown';
212
+ }
213
+
214
+ const firstModifier = (0, _utils2.getAccessorValue)(modifiers[0]); // and the first modifier has to be either "resolves" or "rejects"
215
+
216
+ if (firstModifier !== _utils2.ModifierName.resolves && firstModifier !== _utils2.ModifierName.rejects) {
217
+ return 'modifier-unknown';
218
+ }
219
+ } else {
220
+ return 'modifier-unknown';
221
+ }
222
+
223
+ modifiers.push(member);
224
+ } // this will only really happen if there are no members
225
+
226
+
227
+ return 'matcher-not-found';
228
+ };
229
+
230
+ const parseJestExpectCall = typelessParsedJestFnCall => {
231
+ const modifiersAndMatcher = findModifiersAndMatcher(typelessParsedJestFnCall.members);
232
+
233
+ if (typeof modifiersAndMatcher === 'string') {
234
+ return modifiersAndMatcher;
235
+ }
236
+
237
+ return { ...typelessParsedJestFnCall,
238
+ type: 'expect',
239
+ ...modifiersAndMatcher
240
+ };
241
+ };
145
242
 
146
243
  const describeImportDefAsImport = def => {
147
244
  if (def.parent.type === _utils.AST_NODE_TYPES.TSImportEqualsDeclaration) {
@@ -29,29 +29,6 @@ const isPromiseChainCall = node => {
29
29
  return false;
30
30
  };
31
31
 
32
- const findTopMostCallExpression = node => {
33
- let topMostCallExpression = node;
34
- let {
35
- parent
36
- } = node;
37
-
38
- while (parent) {
39
- if (parent.type === _utils.AST_NODE_TYPES.CallExpression) {
40
- topMostCallExpression = parent;
41
- parent = parent.parent;
42
- continue;
43
- }
44
-
45
- if (parent.type !== _utils.AST_NODE_TYPES.MemberExpression) {
46
- break;
47
- }
48
-
49
- parent = parent.parent;
50
- }
51
-
52
- return topMostCallExpression;
53
- };
54
-
55
32
  const isTestCaseCallWithCallbackArg = (node, context) => {
56
33
  const jestCallFn = (0, _utils2.parseJestFnCall)(node, context);
57
34
 
@@ -173,7 +150,7 @@ const getLeftMostCallExpression = call => {
173
150
  */
174
151
 
175
152
 
176
- const isValueAwaitedOrReturned = (identifier, body) => {
153
+ const isValueAwaitedOrReturned = (identifier, body, context) => {
177
154
  const {
178
155
  name
179
156
  } = identifier;
@@ -197,13 +174,13 @@ const isValueAwaitedOrReturned = (identifier, body) => {
197
174
  }
198
175
 
199
176
  const leftMostCall = getLeftMostCallExpression(node.expression);
177
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node.expression, context);
200
178
 
201
- if ((0, _utils2.isExpectCall)(leftMostCall) && leftMostCall.arguments.length > 0 && (0, _utils2.isIdentifier)(leftMostCall.arguments[0], name)) {
202
- const {
203
- modifier
204
- } = (0, _utils2.parseExpectCall)(leftMostCall);
205
-
206
- if ((modifier === null || modifier === void 0 ? void 0 : modifier.name) === _utils2.ModifierName.resolves || (modifier === null || modifier === void 0 ? void 0 : modifier.name) === _utils2.ModifierName.rejects) {
179
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect' && leftMostCall.arguments.length > 0 && (0, _utils2.isIdentifier)(leftMostCall.arguments[0], name)) {
180
+ if (jestFnCall.members.some(m => {
181
+ const v = (0, _utils2.getAccessorValue)(m);
182
+ return v === _utils2.ModifierName.resolves || v === _utils2.ModifierName.rejects;
183
+ })) {
207
184
  return true;
208
185
  }
209
186
  }
@@ -228,7 +205,7 @@ const isValueAwaitedOrReturned = (identifier, body) => {
228
205
  }
229
206
  }
230
207
 
231
- if (node.type === _utils.AST_NODE_TYPES.BlockStatement && isValueAwaitedOrReturned(identifier, node.body)) {
208
+ if (node.type === _utils.AST_NODE_TYPES.BlockStatement && isValueAwaitedOrReturned(identifier, node.body, context)) {
232
209
  return true;
233
210
  }
234
211
  }
@@ -269,7 +246,7 @@ const isDirectlyWithinTestCaseCall = (node, context) => {
269
246
  return false;
270
247
  };
271
248
 
272
- const isVariableAwaitedOrReturned = variable => {
249
+ const isVariableAwaitedOrReturned = (variable, context) => {
273
250
  const body = findFirstBlockBodyUp(variable); // it's pretty much impossible for us to track destructuring assignments,
274
251
  // so we return true to bailout gracefully
275
252
 
@@ -277,7 +254,7 @@ const isVariableAwaitedOrReturned = variable => {
277
254
  return true;
278
255
  }
279
256
 
280
- return isValueAwaitedOrReturned(variable.id, body);
257
+ return isValueAwaitedOrReturned(variable.id, body, context);
281
258
  };
282
259
 
283
260
  var _default = (0, _utils2.createRule)({
@@ -324,7 +301,7 @@ var _default = (0, _utils2.createRule)({
324
301
  // an expect call, mark the deepest chain as having an expect call
325
302
 
326
303
 
327
- if (chains.length > 0 && (0, _utils2.isExpectCall)(node)) {
304
+ if (chains.length > 0 && (0, _utils2.isTypeOfJestFnCall)(node, context, ['expect'])) {
328
305
  chains[0] = true;
329
306
  }
330
307
  },
@@ -356,7 +333,7 @@ var _default = (0, _utils2.createRule)({
356
333
 
357
334
  const {
358
335
  parent
359
- } = findTopMostCallExpression(node); // if we don't have a parent (which is technically impossible at runtime)
336
+ } = (0, _utils2.findTopMostCallExpression)(node); // if we don't have a parent (which is technically impossible at runtime)
360
337
  // or our parent is not directly within the test case, we stop checking
361
338
  // because we're most likely in the body of a function being defined
362
339
  // within the test, which we can't track
@@ -368,7 +345,7 @@ var _default = (0, _utils2.createRule)({
368
345
  switch (parent.type) {
369
346
  case _utils.AST_NODE_TYPES.VariableDeclarator:
370
347
  {
371
- if (isVariableAwaitedOrReturned(parent)) {
348
+ if (isVariableAwaitedOrReturned(parent, context)) {
372
349
  return;
373
350
  }
374
351
 
@@ -377,7 +354,7 @@ var _default = (0, _utils2.createRule)({
377
354
 
378
355
  case _utils.AST_NODE_TYPES.AssignmentExpression:
379
356
  {
380
- if (parent.left.type === _utils.AST_NODE_TYPES.Identifier && isValueAwaitedOrReturned(parent.left, findFirstBlockBodyUp(parent))) {
357
+ if (parent.left.type === _utils.AST_NODE_TYPES.Identifier && isValueAwaitedOrReturned(parent.left, findFirstBlockBodyUp(parent), context)) {
381
358
  return;
382
359
  }
383
360
 
@@ -26,7 +26,7 @@ const getPromiseCallExpressionNode = node => {
26
26
  node = node.parent;
27
27
  }
28
28
 
29
- if (node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.object) && (0, _utils2.getAccessorValue)(node.callee.object) === 'Promise' && node.parent) {
29
+ 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
30
  return node;
31
31
  }
32
32
 
@@ -44,7 +44,7 @@ const getParentIfThenified = node => {
44
44
 
45
45
  const grandParentNode = (_node$parent2 = node.parent) === null || _node$parent2 === void 0 ? void 0 : _node$parent2.parent;
46
46
 
47
- if (grandParentNode && grandParentNode.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isExpectMember)(grandParentNode.callee) && ['then', 'catch'].includes((0, _utils2.getAccessorValue)(grandParentNode.callee.property)) && grandParentNode.parent) {
47
+ 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
48
  // Just in case `then`s are chained look one above.
49
49
  return getParentIfThenified(grandParentNode);
50
50
  }
@@ -64,8 +64,6 @@ const isAcceptableReturnNode = (node, allowReturn) => {
64
64
  return [_utils.AST_NODE_TYPES.ArrowFunctionExpression, _utils.AST_NODE_TYPES.AwaitExpression].includes(node.type);
65
65
  };
66
66
 
67
- const isNoAssertionsParentNode = node => node.type === _utils.AST_NODE_TYPES.ExpressionStatement || node.type === _utils.AST_NODE_TYPES.AwaitExpression && node.parent !== undefined && node.parent.type === _utils.AST_NODE_TYPES.ExpressionStatement;
68
-
69
67
  const promiseArrayExceptionKey = ({
70
68
  start,
71
69
  end
@@ -84,7 +82,7 @@ var _default = (0, _utils2.createRule)({
84
82
  messages: {
85
83
  tooManyArgs: 'Expect takes at most {{ amount }} argument{{ s }}.',
86
84
  notEnoughArgs: 'Expect requires at least {{ amount }} argument{{ s }}.',
87
- modifierUnknown: 'Expect has no modifier named "{{ modifierName }}".',
85
+ modifierUnknown: 'Expect has an unknown modifier.',
88
86
  matcherNotFound: 'Expect must have a corresponding matcher call.',
89
87
  matcherNotCalled: 'Matchers must be called to assert.',
90
88
  asyncMustBeAwaited: 'Async assertions must be awaited{{ orReturned }}.',
@@ -144,28 +142,79 @@ var _default = (0, _utils2.createRule)({
144
142
 
145
143
  const promiseArrayExceptionExists = loc => arrayExceptions.has(promiseArrayExceptionKey(loc));
146
144
 
145
+ const findTopMostMemberExpression = node => {
146
+ let topMostMemberExpression = node;
147
+ let {
148
+ parent
149
+ } = node;
150
+
151
+ while (parent) {
152
+ if (parent.type !== _utils.AST_NODE_TYPES.MemberExpression) {
153
+ break;
154
+ }
155
+
156
+ topMostMemberExpression = parent;
157
+ parent = parent.parent;
158
+ }
159
+
160
+ return topMostMemberExpression;
161
+ };
162
+
147
163
  return {
148
164
  CallExpression(node) {
149
- if (!(0, _utils2.isExpectCall)(node)) {
165
+ const jestFnCall = (0, _utils2.parseJestFnCallWithReason)(node, context);
166
+
167
+ if (typeof jestFnCall === 'string') {
168
+ var _node$parent3;
169
+
170
+ 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
+ if (jestFnCall === 'matcher-not-found') {
173
+ context.report({
174
+ messageId: 'matcherNotFound',
175
+ node: reportingNode
176
+ });
177
+ return;
178
+ }
179
+
180
+ if (jestFnCall === 'matcher-not-called') {
181
+ context.report({
182
+ messageId: (0, _utils2.isSupportedAccessor)(reportingNode) && _utils2.ModifierName.hasOwnProperty((0, _utils2.getAccessorValue)(reportingNode)) ? 'matcherNotFound' : 'matcherNotCalled',
183
+ node: reportingNode
184
+ });
185
+ }
186
+
187
+ if (jestFnCall === 'modifier-unknown') {
188
+ context.report({
189
+ messageId: 'modifierUnknown',
190
+ node: reportingNode
191
+ });
192
+ return;
193
+ }
194
+
195
+ return;
196
+ } else if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
150
197
  return;
151
198
  }
152
199
 
153
200
  const {
154
- expect,
155
- modifier,
156
- matcher
157
- } = (0, _utils2.parseExpectCall)(node);
201
+ parent: expect
202
+ } = jestFnCall.head.node;
203
+
204
+ if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
205
+ return;
206
+ }
158
207
 
159
208
  if (expect.arguments.length < minArgs) {
160
- const expectLength = (0, _utils2.getAccessorValue)(expect.callee).length;
209
+ const expectLength = (0, _utils2.getAccessorValue)(jestFnCall.head.node).length;
161
210
  const loc = {
162
211
  start: {
163
- column: node.loc.start.column + expectLength,
164
- line: node.loc.start.line
212
+ column: expect.loc.start.column + expectLength,
213
+ line: expect.loc.start.line
165
214
  },
166
215
  end: {
167
- column: node.loc.start.column + expectLength + 1,
168
- line: node.loc.start.line
216
+ column: expect.loc.start.column + expectLength + 1,
217
+ line: expect.loc.start.line
169
218
  }
170
219
  };
171
220
  context.report({
@@ -174,7 +223,7 @@ var _default = (0, _utils2.createRule)({
174
223
  amount: minArgs,
175
224
  s: minArgs === 1 ? '' : 's'
176
225
  },
177
- node,
226
+ node: expect,
178
227
  loc
179
228
  });
180
229
  }
@@ -185,7 +234,7 @@ var _default = (0, _utils2.createRule)({
185
234
  } = expect.arguments[maxArgs].loc;
186
235
  const {
187
236
  end
188
- } = expect.arguments[node.arguments.length - 1].loc;
237
+ } = expect.arguments[expect.arguments.length - 1].loc;
189
238
  const loc = {
190
239
  start,
191
240
  end: {
@@ -199,45 +248,18 @@ var _default = (0, _utils2.createRule)({
199
248
  amount: maxArgs,
200
249
  s: maxArgs === 1 ? '' : 's'
201
250
  },
202
- node,
251
+ node: expect,
203
252
  loc
204
253
  });
205
- } // something was called on `expect()`
206
-
207
-
208
- if (!matcher) {
209
- if (modifier) {
210
- context.report({
211
- messageId: 'matcherNotFound',
212
- node: modifier.node.property
213
- });
214
- }
215
-
216
- return;
217
- }
218
-
219
- if ((0, _utils2.isExpectMember)(matcher.node.parent)) {
220
- context.report({
221
- messageId: 'modifierUnknown',
222
- data: {
223
- modifierName: matcher.name
224
- },
225
- node: matcher.node.property
226
- });
227
- return;
228
254
  }
229
255
 
230
- if (!matcher.arguments) {
231
- context.report({
232
- messageId: 'matcherNotCalled',
233
- node: matcher.node.property
234
- });
235
- }
236
-
237
- const parentNode = matcher.node.parent;
238
- const shouldBeAwaited = modifier && modifier.name !== _utils2.ModifierName.not || asyncMatchers.includes(matcher.name);
256
+ const {
257
+ matcher
258
+ } = jestFnCall;
259
+ const parentNode = matcher.parent.parent;
260
+ const shouldBeAwaited = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) !== 'not') || asyncMatchers.includes((0, _utils2.getAccessorValue)(matcher));
239
261
 
240
- if (!parentNode.parent || !shouldBeAwaited) {
262
+ if (!(parentNode !== null && parentNode !== void 0 && parentNode.parent) || !shouldBeAwaited) {
241
263
  return;
242
264
  }
243
265
  /**
@@ -273,16 +295,6 @@ var _default = (0, _utils2.createRule)({
273
295
  pushPromiseArrayException(finalNode.loc);
274
296
  }
275
297
  }
276
- },
277
-
278
- // nothing called on "expect()"
279
- 'CallExpression:exit'(node) {
280
- if ((0, _utils2.isExpectCall)(node) && isNoAssertionsParentNode(node.parent)) {
281
- context.report({
282
- messageId: 'matcherNotFound',
283
- node
284
- });
285
- }
286
298
  }
287
299
 
288
300
  };