eslint-plugin-jest 26.8.7 → 27.1.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.
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 +5 -35
  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 +8 -54
  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 +5 -30
  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 +2 -46
  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,149 +4,113 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getNodeChain = getNodeChain;
7
- exports.scopeHasLocalReference = exports.parseJestFnCallWithReason = exports.parseJestFnCall = exports.isTypeOfJestFnCall = void 0;
8
-
7
+ exports.resolveScope = exports.parseJestFnCallWithReason = exports.parseJestFnCall = exports.isTypeOfJestFnCall = void 0;
9
8
  var _utils = require("@typescript-eslint/utils");
10
-
11
9
  var _utils2 = require("../utils");
12
-
13
10
  const isTypeOfJestFnCall = (node, context, types) => {
14
11
  const jestFnCall = parseJestFnCall(node, context);
15
12
  return jestFnCall !== null && types.includes(jestFnCall.type);
16
13
  };
17
-
18
14
  exports.isTypeOfJestFnCall = isTypeOfJestFnCall;
19
-
20
15
  const joinChains = (a, b) => a && b ? [...a, ...b] : null;
21
-
22
16
  function getNodeChain(node) {
23
17
  if ((0, _utils2.isSupportedAccessor)(node)) {
24
18
  return [node];
25
19
  }
26
-
27
20
  switch (node.type) {
28
21
  case _utils.AST_NODE_TYPES.TaggedTemplateExpression:
29
22
  return getNodeChain(node.tag);
30
-
31
23
  case _utils.AST_NODE_TYPES.MemberExpression:
32
24
  return joinChains(getNodeChain(node.object), getNodeChain(node.property));
33
-
34
25
  case _utils.AST_NODE_TYPES.CallExpression:
35
26
  return getNodeChain(node.callee);
36
27
  }
37
-
38
28
  return null;
39
29
  }
40
-
41
30
  const determineJestFnType = name => {
42
31
  if (name === 'expect') {
43
32
  return 'expect';
44
33
  }
45
-
46
34
  if (name === 'jest') {
47
35
  return 'jest';
48
36
  }
49
-
50
37
  if (_utils2.DescribeAlias.hasOwnProperty(name)) {
51
38
  return 'describe';
52
39
  }
53
-
54
40
  if (_utils2.TestCaseName.hasOwnProperty(name)) {
55
41
  return 'test';
56
42
  }
57
- /* istanbul ignore else */
58
-
59
43
 
44
+ /* istanbul ignore else */
60
45
  if (_utils2.HookName.hasOwnProperty(name)) {
61
46
  return 'hook';
62
47
  }
63
- /* istanbul ignore next */
64
-
65
48
 
49
+ /* istanbul ignore next */
66
50
  return 'unknown';
67
51
  };
68
-
69
52
  const ValidJestFnCallChains = ['afterAll', 'afterEach', 'beforeAll', 'beforeEach', 'describe', 'describe.each', 'describe.only', 'describe.only.each', 'describe.skip', 'describe.skip.each', 'fdescribe', 'fdescribe.each', 'xdescribe', 'xdescribe.each', 'it', 'it.concurrent', 'it.concurrent.each', 'it.concurrent.only.each', 'it.concurrent.skip.each', 'it.each', 'it.failing', 'it.only', 'it.only.each', 'it.only.failing', 'it.skip', 'it.skip.each', 'it.skip.failing', 'it.todo', 'fit', 'fit.each', 'fit.failing', 'xit', 'xit.each', 'xit.failing', 'test', 'test.concurrent', 'test.concurrent.each', 'test.concurrent.only.each', 'test.concurrent.skip.each', 'test.each', 'test.failing', 'test.only', 'test.only.each', 'test.only.failing', 'test.skip', 'test.skip.each', 'test.skip.failing', 'test.todo', 'xtest', 'xtest.each', 'xtest.failing'];
70
-
71
53
  const resolvePossibleAliasedGlobal = (global, context) => {
72
- var _context$settings$jes, _context$settings$jes2;
73
-
74
- const globalAliases = (_context$settings$jes = (_context$settings$jes2 = context.settings.jest) === null || _context$settings$jes2 === void 0 ? void 0 : _context$settings$jes2.globalAliases) !== null && _context$settings$jes !== void 0 ? _context$settings$jes : {};
54
+ var _context$settings$jes;
55
+ const globalAliases = ((_context$settings$jes = context.settings.jest) === null || _context$settings$jes === void 0 ? void 0 : _context$settings$jes.globalAliases) ?? {};
75
56
  const alias = Object.entries(globalAliases).find(([, aliases]) => aliases.includes(global));
76
-
77
57
  if (alias) {
78
58
  return alias[0];
79
59
  }
80
-
81
60
  return null;
82
61
  };
83
-
84
62
  const parseJestFnCallCache = new WeakMap();
85
-
86
63
  const parseJestFnCall = (node, context) => {
87
64
  const jestFnCall = parseJestFnCallWithReason(node, context);
88
-
89
65
  if (typeof jestFnCall === 'string') {
90
66
  return null;
91
67
  }
92
-
93
68
  return jestFnCall;
94
69
  };
95
-
96
70
  exports.parseJestFnCall = parseJestFnCall;
97
-
98
71
  const parseJestFnCallWithReason = (node, context) => {
99
72
  let parsedJestFnCall = parseJestFnCallCache.get(node);
100
-
101
73
  if (parsedJestFnCall) {
102
74
  return parsedJestFnCall;
103
75
  }
104
-
105
76
  parsedJestFnCall = parseJestFnCallWithReasonInner(node, context);
106
77
  parseJestFnCallCache.set(node, parsedJestFnCall);
107
78
  return parsedJestFnCall;
108
79
  };
109
-
110
80
  exports.parseJestFnCallWithReason = parseJestFnCallWithReason;
111
-
112
81
  const parseJestFnCallWithReasonInner = (node, context) => {
113
- var _resolved$original, _node$parent2, _node$parent3;
114
-
82
+ var _node$parent2, _node$parent3;
115
83
  const chain = getNodeChain(node);
116
-
117
84
  if (!(chain !== null && chain !== void 0 && chain.length)) {
118
85
  return null;
119
86
  }
120
-
121
87
  const [first, ...rest] = chain;
122
- const lastLink = (0, _utils2.getAccessorValue)(chain[chain.length - 1]); // if we're an `each()`, ensure we're the outer CallExpression (i.e `.each()()`)
88
+ const lastLink = (0, _utils2.getAccessorValue)(chain[chain.length - 1]);
123
89
 
90
+ // if we're an `each()`, ensure we're the outer CallExpression (i.e `.each()()`)
124
91
  if (lastLink === 'each') {
125
92
  if (node.callee.type !== _utils.AST_NODE_TYPES.CallExpression && node.callee.type !== _utils.AST_NODE_TYPES.TaggedTemplateExpression) {
126
93
  return null;
127
94
  }
128
95
  }
129
-
130
96
  if (node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression && lastLink !== 'each') {
131
97
  return null;
132
98
  }
99
+ const resolved = resolveToJestFn(context, (0, _utils2.getAccessorValue)(first));
133
100
 
134
- const resolved = resolveToJestFn(context, (0, _utils2.getAccessorValue)(first)); // we're not a jest function
135
-
101
+ // we're not a jest function
136
102
  if (!resolved) {
137
103
  return null;
138
104
  }
139
-
140
- const name = (_resolved$original = resolved.original) !== null && _resolved$original !== void 0 ? _resolved$original : resolved.local;
105
+ const name = resolved.original ?? resolved.local;
141
106
  const links = [name, ...rest.map(link => (0, _utils2.getAccessorValue)(link))];
142
-
143
107
  if (name !== 'jest' && name !== 'expect' && !ValidJestFnCallChains.includes(links.join('.'))) {
144
108
  return null;
145
109
  }
146
-
147
110
  const parsedJestFnCall = {
148
111
  name,
149
- head: { ...resolved,
112
+ head: {
113
+ ...resolved,
150
114
  node: first
151
115
  },
152
116
  // every member node must have a member expression as their parent
@@ -154,53 +118,46 @@ const parseJestFnCallWithReasonInner = (node, context) => {
154
118
  members: rest
155
119
  };
156
120
  const type = determineJestFnType(name);
157
-
158
121
  if (type === 'expect') {
159
- const result = parseJestExpectCall(parsedJestFnCall); // if the `expect` call chain is not valid, only report on the topmost node
160
- // since all members in the chain are likely to get flagged for some reason
122
+ const result = parseJestExpectCall(parsedJestFnCall);
161
123
 
124
+ // if the `expect` call chain is not valid, only report on the topmost node
125
+ // since all members in the chain are likely to get flagged for some reason
162
126
  if (typeof result === 'string' && (0, _utils2.findTopMostCallExpression)(node) !== node) {
163
127
  return null;
164
128
  }
165
-
166
129
  if (result === 'matcher-not-found') {
167
130
  var _node$parent;
168
-
169
131
  if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) === _utils.AST_NODE_TYPES.MemberExpression) {
170
132
  return 'matcher-not-called';
171
133
  }
172
134
  }
173
-
174
135
  return result;
175
- } // check that every link in the chain except the last is a member expression
176
-
136
+ }
177
137
 
138
+ // check that every link in the chain except the last is a member expression
178
139
  if (chain.slice(0, chain.length - 1).some(nod => {
179
140
  var _nod$parent;
180
-
181
141
  return ((_nod$parent = nod.parent) === null || _nod$parent === void 0 ? void 0 : _nod$parent.type) !== _utils.AST_NODE_TYPES.MemberExpression;
182
142
  })) {
183
143
  return null;
184
- } // ensure that we're at the "top" of the function call chain otherwise when
144
+ }
145
+
146
+ // ensure that we're at the "top" of the function call chain otherwise when
185
147
  // parsing e.g. x().y.z(), we'll incorrectly find & parse "x()" even though
186
148
  // the full chain is not a valid jest function call chain
187
-
188
-
189
149
  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) {
190
150
  return null;
191
151
  }
192
-
193
- return { ...parsedJestFnCall,
152
+ return {
153
+ ...parsedJestFnCall,
194
154
  type
195
155
  };
196
156
  };
197
-
198
157
  const findModifiersAndMatcher = members => {
199
158
  const modifiers = [];
200
-
201
159
  for (const member of members) {
202
160
  var _member$parent, _member$parent$parent;
203
-
204
161
  // check if the member is being called, which means it is the matcher
205
162
  // (and also the end of the entire "expect" call chain)
206
163
  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) {
@@ -209,11 +166,10 @@ const findModifiersAndMatcher = members => {
209
166
  args: member.parent.parent.arguments,
210
167
  modifiers
211
168
  };
212
- } // otherwise, it should be a modifier
213
-
169
+ }
214
170
 
171
+ // otherwise, it should be a modifier
215
172
  const name = (0, _utils2.getAccessorValue)(member);
216
-
217
173
  if (modifiers.length === 0) {
218
174
  // the first modifier can be any of the three modifiers
219
175
  if (!_utils2.ModifierName.hasOwnProperty(name)) {
@@ -224,56 +180,51 @@ const findModifiersAndMatcher = members => {
224
180
  if (name !== _utils2.ModifierName.not) {
225
181
  return 'modifier-unknown';
226
182
  }
183
+ const firstModifier = (0, _utils2.getAccessorValue)(modifiers[0]);
227
184
 
228
- const firstModifier = (0, _utils2.getAccessorValue)(modifiers[0]); // and the first modifier has to be either "resolves" or "rejects"
229
-
185
+ // and the first modifier has to be either "resolves" or "rejects"
230
186
  if (firstModifier !== _utils2.ModifierName.resolves && firstModifier !== _utils2.ModifierName.rejects) {
231
187
  return 'modifier-unknown';
232
188
  }
233
189
  } else {
234
190
  return 'modifier-unknown';
235
191
  }
236
-
237
192
  modifiers.push(member);
238
- } // this will only really happen if there are no members
239
-
193
+ }
240
194
 
195
+ // this will only really happen if there are no members
241
196
  return 'matcher-not-found';
242
197
  };
243
-
244
198
  const parseJestExpectCall = typelessParsedJestFnCall => {
245
199
  const modifiersAndMatcher = findModifiersAndMatcher(typelessParsedJestFnCall.members);
246
-
247
200
  if (typeof modifiersAndMatcher === 'string') {
248
201
  return modifiersAndMatcher;
249
202
  }
250
-
251
- return { ...typelessParsedJestFnCall,
203
+ return {
204
+ ...typelessParsedJestFnCall,
252
205
  type: 'expect',
253
206
  ...modifiersAndMatcher
254
207
  };
255
208
  };
256
-
257
209
  const describeImportDefAsImport = def => {
258
210
  if (def.parent.type === _utils.AST_NODE_TYPES.TSImportEqualsDeclaration) {
259
211
  return null;
260
212
  }
261
-
262
213
  if (def.node.type !== _utils.AST_NODE_TYPES.ImportSpecifier) {
263
214
  return null;
264
- } // we only care about value imports
265
-
215
+ }
266
216
 
217
+ // we only care about value imports
267
218
  if (def.parent.importKind === 'type') {
268
219
  return null;
269
220
  }
270
-
271
221
  return {
272
222
  source: def.parent.source.value,
273
223
  imported: def.node.imported.name,
274
224
  local: def.node.local.name
275
225
  };
276
226
  };
227
+
277
228
  /**
278
229
  * Attempts to find the node that represents the import source for the
279
230
  * given expression node, if it looks like it's an import.
@@ -281,54 +232,41 @@ const describeImportDefAsImport = def => {
281
232
  * If no such node can be found (e.g. because the expression doesn't look
282
233
  * like an import), then `null` is returned instead.
283
234
  */
284
-
285
-
286
235
  const findImportSourceNode = node => {
287
236
  if (node.type === _utils.AST_NODE_TYPES.AwaitExpression) {
288
237
  if (node.argument.type === _utils.AST_NODE_TYPES.ImportExpression) {
289
238
  return node.argument.source;
290
239
  }
291
-
292
240
  return null;
293
241
  }
294
-
295
242
  if (node.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isIdentifier)(node.callee, 'require')) {
296
- var _node$arguments$;
297
-
298
- return (_node$arguments$ = node.arguments[0]) !== null && _node$arguments$ !== void 0 ? _node$arguments$ : null;
243
+ return node.arguments[0] ?? null;
299
244
  }
300
-
301
245
  return null;
302
246
  };
303
-
304
247
  const describeVariableDefAsImport = def => {
305
248
  var _def$name$parent;
306
-
307
249
  // make sure that we've actually being assigned a value
308
250
  if (!def.node.init) {
309
251
  return null;
310
252
  }
311
-
312
253
  const sourceNode = findImportSourceNode(def.node.init);
313
-
314
254
  if (!sourceNode || !(0, _utils2.isStringNode)(sourceNode)) {
315
255
  return null;
316
256
  }
317
-
318
257
  if (((_def$name$parent = def.name.parent) === null || _def$name$parent === void 0 ? void 0 : _def$name$parent.type) !== _utils.AST_NODE_TYPES.Property) {
319
258
  return null;
320
259
  }
321
-
322
260
  if (!(0, _utils2.isSupportedAccessor)(def.name.parent.key)) {
323
261
  return null;
324
262
  }
325
-
326
263
  return {
327
264
  source: (0, _utils2.getStringValue)(sourceNode),
328
265
  imported: (0, _utils2.getAccessorValue)(def.name.parent.key),
329
266
  local: def.name.name
330
267
  };
331
268
  };
269
+
332
270
  /**
333
271
  * Attempts to describe a definition as an import if possible.
334
272
  *
@@ -339,61 +277,40 @@ const describeVariableDefAsImport = def => {
339
277
  * If it's neither of these, `null` is returned to indicate that the definition
340
278
  * is not describable as an import of any kind.
341
279
  */
342
-
343
-
344
280
  const describePossibleImportDef = def => {
345
281
  if (def.type === 'Variable') {
346
282
  return describeVariableDefAsImport(def);
347
283
  }
348
-
349
284
  if (def.type === 'ImportBinding') {
350
285
  return describeImportDefAsImport(def);
351
286
  }
352
-
353
287
  return null;
354
288
  };
355
-
356
- const collectReferences = scope => {
357
- const locals = new Set();
358
- const imports = new Map();
359
- const unresolved = new Set();
289
+ const resolveScope = (scope, identifier) => {
360
290
  let currentScope = scope;
361
-
362
291
  while (currentScope !== null) {
363
- for (const ref of currentScope.variables) {
364
- if (ref.defs.length === 0) {
365
- continue;
366
- }
367
-
292
+ const ref = currentScope.set.get(identifier);
293
+ if (ref && ref.defs.length > 0) {
368
294
  const def = ref.defs[ref.defs.length - 1];
369
295
  const importDetails = describePossibleImportDef(def);
370
-
371
- if (importDetails) {
372
- imports.set(importDetails.local, importDetails);
373
- continue;
296
+ if ((importDetails === null || importDetails === void 0 ? void 0 : importDetails.local) === identifier) {
297
+ return importDetails;
374
298
  }
375
-
376
- locals.add(ref.name);
377
- }
378
-
379
- for (const ref of currentScope.through) {
380
- unresolved.add(ref.identifier.name);
299
+ return 'local';
381
300
  }
382
-
383
301
  currentScope = currentScope.upper;
384
302
  }
385
-
386
- return {
387
- locals,
388
- imports,
389
- unresolved
390
- };
303
+ return null;
391
304
  };
392
-
305
+ exports.resolveScope = resolveScope;
393
306
  const resolveToJestFn = (context, identifier) => {
394
- const references = collectReferences(context.getScope());
395
- const maybeImport = references.imports.get(identifier);
307
+ const maybeImport = resolveScope(context.getScope(), identifier);
396
308
 
309
+ // the identifier was found as a local variable or function declaration
310
+ // meaning it's not a function from jest
311
+ if (maybeImport === 'local') {
312
+ return null;
313
+ }
397
314
  if (maybeImport) {
398
315
  // the identifier is imported from @jest/globals,
399
316
  // so return the original import name
@@ -404,31 +321,11 @@ const resolveToJestFn = (context, identifier) => {
404
321
  type: 'import'
405
322
  };
406
323
  }
407
-
408
- return null;
409
- } // the identifier was found as a local variable or function declaration
410
- // meaning it's not a function from jest
411
-
412
-
413
- if (references.locals.has(identifier)) {
414
324
  return null;
415
325
  }
416
-
417
326
  return {
418
327
  original: resolvePossibleAliasedGlobal(identifier, context),
419
328
  local: identifier,
420
329
  type: 'global'
421
330
  };
422
- };
423
-
424
- const scopeHasLocalReference = (scope, referenceName) => {
425
- const references = collectReferences(scope);
426
- return (// referenceName was found as a local variable or function declaration.
427
- references.locals.has(referenceName) || // referenceName was found as an imported identifier
428
- references.imports.has(referenceName) || // referenceName was not found as an unresolved reference,
429
- // meaning it is likely not an implicit global reference.
430
- !references.unresolved.has(referenceName)
431
- );
432
- };
433
-
434
- exports.scopeHasLocalReference = scopeHasLocalReference;
331
+ };
@@ -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
  const paramsLocation = params => {
13
10
  const [first] = params;
14
11
  const last = params[params.length - 1];
@@ -17,7 +14,6 @@ const paramsLocation = params => {
17
14
  end: last.loc.end
18
15
  };
19
16
  };
20
-
21
17
  var _default = (0, _utils2.createRule)({
22
18
  name: __filename,
23
19
  meta: {
@@ -37,25 +33,20 @@ var _default = (0, _utils2.createRule)({
37
33
  schema: []
38
34
  },
39
35
  defaultOptions: [],
40
-
41
36
  create(context) {
42
37
  return {
43
38
  CallExpression(node) {
44
39
  const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
45
-
46
40
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'describe') {
47
41
  return;
48
42
  }
49
-
50
43
  if (node.arguments.length < 1) {
51
44
  return context.report({
52
45
  messageId: 'nameAndCallback',
53
46
  loc: node.loc
54
47
  });
55
48
  }
56
-
57
49
  const [, callback] = node.arguments;
58
-
59
50
  if (!callback) {
60
51
  context.report({
61
52
  messageId: 'nameAndCallback',
@@ -63,7 +54,6 @@ var _default = (0, _utils2.createRule)({
63
54
  });
64
55
  return;
65
56
  }
66
-
67
57
  if (!(0, _utils2.isFunction)(callback)) {
68
58
  context.report({
69
59
  messageId: 'secondArgumentMustBeFunction',
@@ -71,28 +61,24 @@ var _default = (0, _utils2.createRule)({
71
61
  });
72
62
  return;
73
63
  }
74
-
75
64
  if (callback.async) {
76
65
  context.report({
77
66
  messageId: 'noAsyncDescribeCallback',
78
67
  node: callback
79
68
  });
80
69
  }
81
-
82
70
  if (jestFnCall.members.every(s => (0, _utils2.getAccessorValue)(s) !== 'each') && callback.params.length) {
83
71
  context.report({
84
72
  messageId: 'unexpectedDescribeArgument',
85
73
  loc: paramsLocation(callback.params)
86
74
  });
87
75
  }
88
-
89
76
  if (callback.body.type === _utils.AST_NODE_TYPES.CallExpression) {
90
77
  context.report({
91
78
  messageId: 'unexpectedReturnInDescribe',
92
79
  node: callback
93
80
  });
94
81
  }
95
-
96
82
  if (callback.body.type === _utils.AST_NODE_TYPES.BlockStatement) {
97
83
  callback.body.body.forEach(node => {
98
84
  if (node.type === _utils.AST_NODE_TYPES.ReturnStatement) {
@@ -104,10 +90,7 @@ var _default = (0, _utils2.createRule)({
104
90
  });
105
91
  }
106
92
  }
107
-
108
93
  };
109
94
  }
110
-
111
95
  });
112
-
113
96
  exports.default = _default;