eslint-plugin-jest 27.1.1 → 27.1.3

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 (60) hide show
  1. package/lib/index.js +8 -16
  2. package/lib/processors/snapshot-processor.js +3 -5
  3. package/lib/rules/consistent-test-it.js +0 -18
  4. package/lib/rules/expect-expect.js +0 -15
  5. package/lib/rules/max-expects.js +0 -16
  6. package/lib/rules/max-nested-describe.js +0 -13
  7. package/lib/rules/no-alias-methods.js +0 -9
  8. package/lib/rules/no-commented-out-tests.js +0 -10
  9. package/lib/rules/no-conditional-expect.js +0 -19
  10. package/lib/rules/no-conditional-in-test.js +0 -9
  11. package/lib/rules/no-deprecated-functions.js +2 -18
  12. package/lib/rules/no-disabled-tests.js +2 -18
  13. package/lib/rules/no-done-callback.js +1 -30
  14. package/lib/rules/no-duplicate-hooks.js +0 -12
  15. package/lib/rules/no-export.js +0 -12
  16. package/lib/rules/no-focused-tests.js +0 -15
  17. package/lib/rules/no-hooks.js +0 -7
  18. package/lib/rules/no-identical-title.js +0 -19
  19. package/lib/rules/no-if.js +0 -24
  20. package/lib/rules/no-interpolation-in-snapshots.js +0 -9
  21. package/lib/rules/no-jasmine-globals.js +0 -22
  22. package/lib/rules/no-large-snapshots.js +2 -20
  23. package/lib/rules/no-mocks-import.js +0 -12
  24. package/lib/rules/no-restricted-jest-methods.js +1 -11
  25. package/lib/rules/no-restricted-matchers.js +0 -11
  26. package/lib/rules/no-standalone-expect.js +7 -33
  27. package/lib/rules/no-test-prefixes.js +0 -12
  28. package/lib/rules/no-test-return-statement.js +0 -12
  29. package/lib/rules/prefer-called-with.js +0 -10
  30. package/lib/rules/prefer-comparison-matcher.js +8 -33
  31. package/lib/rules/prefer-each.js +0 -18
  32. package/lib/rules/prefer-equality-matcher.js +11 -23
  33. package/lib/rules/prefer-expect-assertions.js +4 -51
  34. package/lib/rules/prefer-expect-resolves.js +0 -12
  35. package/lib/rules/prefer-hooks-in-order.js +2 -16
  36. package/lib/rules/prefer-hooks-on-top.js +0 -9
  37. package/lib/rules/prefer-lowercase-title.js +0 -23
  38. package/lib/rules/prefer-mock-promise-shorthand.js +5 -26
  39. package/lib/rules/prefer-snapshot-hint.js +7 -31
  40. package/lib/rules/prefer-spy-on.js +0 -17
  41. package/lib/rules/prefer-strict-equal.js +0 -9
  42. package/lib/rules/prefer-to-be.js +1 -30
  43. package/lib/rules/prefer-to-contain.js +11 -21
  44. package/lib/rules/prefer-to-have-length.js +4 -16
  45. package/lib/rules/prefer-todo.js +2 -18
  46. package/lib/rules/require-hook.js +0 -22
  47. package/lib/rules/require-to-throw-message.js +0 -9
  48. package/lib/rules/require-top-level-describe.js +0 -15
  49. package/lib/rules/unbound-method.js +2 -21
  50. package/lib/rules/utils/accessors.js +6 -18
  51. package/lib/rules/utils/detectJestVersion.js +2 -7
  52. package/lib/rules/utils/followTypeAssertionChain.js +0 -4
  53. package/lib/rules/utils/index.js +0 -10
  54. package/lib/rules/utils/misc.js +2 -46
  55. package/lib/rules/utils/parseJestFnCall.js +39 -114
  56. package/lib/rules/valid-describe-callback.js +0 -17
  57. package/lib/rules/valid-expect-in-promise.js +27 -94
  58. package/lib/rules/valid-expect.js +5 -48
  59. package/lib/rules/valid-title.js +0 -33
  60. package/package.json +2 -2
@@ -6,32 +6,22 @@ Object.defineProperty(exports, "__esModule", {
6
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
8
  exports.replaceAccessorFixer = exports.isFunction = exports.isBooleanLiteral = exports.hasOnlyOneArgument = exports.getTestCallExpressionsFromDeclaredVariables = void 0;
9
-
10
9
  var _path = require("path");
11
-
12
10
  var _utils = require("@typescript-eslint/utils");
13
-
14
11
  var _package = require("../../../package.json");
15
-
16
12
  var _accessors = require("./accessors");
17
-
18
13
  var _followTypeAssertionChain = require("./followTypeAssertionChain");
19
-
20
14
  var _parseJestFnCall = require("./parseJestFnCall");
21
-
22
15
  const REPO_URL = 'https://github.com/jest-community/eslint-plugin-jest';
23
-
24
16
  const createRule = _utils.ESLintUtils.RuleCreator(name => {
25
17
  const ruleName = (0, _path.parse)(name).name;
26
18
  return `${REPO_URL}/blob/v${_package.version}/docs/rules/${ruleName}.md`;
27
19
  });
20
+
28
21
  /**
29
22
  * Represents a `MemberExpression` with a "known" `property`.
30
23
  */
31
-
32
-
33
24
  exports.createRule = createRule;
34
-
35
25
  /**
36
26
  * Guards that the given `call` has only one `argument`.
37
27
  *
@@ -40,20 +30,16 @@ exports.createRule = createRule;
40
30
  * @return {call is CallExpressionWithSingleArgument}
41
31
  */
42
32
  const hasOnlyOneArgument = call => call.arguments.length === 1;
43
-
44
33
  exports.hasOnlyOneArgument = hasOnlyOneArgument;
45
34
  let DescribeAlias;
46
35
  exports.DescribeAlias = DescribeAlias;
47
-
48
36
  (function (DescribeAlias) {
49
37
  DescribeAlias["describe"] = "describe";
50
38
  DescribeAlias["fdescribe"] = "fdescribe";
51
39
  DescribeAlias["xdescribe"] = "xdescribe";
52
40
  })(DescribeAlias || (exports.DescribeAlias = DescribeAlias = {}));
53
-
54
41
  let TestCaseName;
55
42
  exports.TestCaseName = TestCaseName;
56
-
57
43
  (function (TestCaseName) {
58
44
  TestCaseName["fit"] = "fit";
59
45
  TestCaseName["it"] = "it";
@@ -61,61 +47,46 @@ exports.TestCaseName = TestCaseName;
61
47
  TestCaseName["xit"] = "xit";
62
48
  TestCaseName["xtest"] = "xtest";
63
49
  })(TestCaseName || (exports.TestCaseName = TestCaseName = {}));
64
-
65
50
  let HookName;
66
51
  exports.HookName = HookName;
67
-
68
52
  (function (HookName) {
69
53
  HookName["beforeAll"] = "beforeAll";
70
54
  HookName["beforeEach"] = "beforeEach";
71
55
  HookName["afterAll"] = "afterAll";
72
56
  HookName["afterEach"] = "afterEach";
73
57
  })(HookName || (exports.HookName = HookName = {}));
74
-
75
58
  let ModifierName;
76
59
  exports.ModifierName = ModifierName;
77
-
78
60
  (function (ModifierName) {
79
61
  ModifierName["not"] = "not";
80
62
  ModifierName["rejects"] = "rejects";
81
63
  ModifierName["resolves"] = "resolves";
82
64
  })(ModifierName || (exports.ModifierName = ModifierName = {}));
83
-
84
65
  let EqualityMatcher;
85
66
  exports.EqualityMatcher = EqualityMatcher;
86
-
87
67
  (function (EqualityMatcher) {
88
68
  EqualityMatcher["toBe"] = "toBe";
89
69
  EqualityMatcher["toEqual"] = "toEqual";
90
70
  EqualityMatcher["toStrictEqual"] = "toStrictEqual";
91
71
  })(EqualityMatcher || (exports.EqualityMatcher = EqualityMatcher = {}));
92
-
93
72
  const joinNames = (a, b) => a && b ? `${a}.${b}` : null;
94
-
95
73
  function getNodeName(node) {
96
74
  if ((0, _accessors.isSupportedAccessor)(node)) {
97
75
  return (0, _accessors.getAccessorValue)(node);
98
76
  }
99
-
100
77
  switch (node.type) {
101
78
  case _utils.AST_NODE_TYPES.TaggedTemplateExpression:
102
79
  return getNodeName(node.tag);
103
-
104
80
  case _utils.AST_NODE_TYPES.MemberExpression:
105
81
  return joinNames(getNodeName(node.object), getNodeName(node.property));
106
-
107
82
  case _utils.AST_NODE_TYPES.NewExpression:
108
83
  case _utils.AST_NODE_TYPES.CallExpression:
109
84
  return getNodeName(node.callee);
110
85
  }
111
-
112
86
  return null;
113
87
  }
114
-
115
88
  const isFunction = node => node.type === _utils.AST_NODE_TYPES.FunctionExpression || node.type === _utils.AST_NODE_TYPES.ArrowFunctionExpression;
116
-
117
89
  exports.isFunction = isFunction;
118
-
119
90
  const getTestCallExpressionsFromDeclaredVariables = (declaredVariables, context) => {
120
91
  return declaredVariables.reduce((acc, {
121
92
  references
@@ -123,59 +94,44 @@ const getTestCallExpressionsFromDeclaredVariables = (declaredVariables, context)
123
94
  identifier
124
95
  }) => identifier.parent).filter(node => (node === null || node === void 0 ? void 0 : node.type) === _utils.AST_NODE_TYPES.CallExpression && (0, _parseJestFnCall.isTypeOfJestFnCall)(node, context, ['test']))), []);
125
96
  };
97
+
126
98
  /**
127
99
  * Replaces an accessor node with the given `text`, surrounding it in quotes if required.
128
100
  *
129
101
  * This ensures that fixes produce valid code when replacing both dot-based and
130
102
  * bracket-based property accessors.
131
103
  */
132
-
133
-
134
104
  exports.getTestCallExpressionsFromDeclaredVariables = getTestCallExpressionsFromDeclaredVariables;
135
-
136
105
  const replaceAccessorFixer = (fixer, node, text) => {
137
106
  return fixer.replaceText(node, node.type === _utils.AST_NODE_TYPES.Identifier ? text : `'${text}'`);
138
107
  };
139
-
140
108
  exports.replaceAccessorFixer = replaceAccessorFixer;
141
-
142
109
  const findTopMostCallExpression = node => {
143
110
  let topMostCallExpression = node;
144
111
  let {
145
112
  parent
146
113
  } = node;
147
-
148
114
  while (parent) {
149
115
  if (parent.type === _utils.AST_NODE_TYPES.CallExpression) {
150
116
  topMostCallExpression = parent;
151
117
  parent = parent.parent;
152
118
  continue;
153
119
  }
154
-
155
120
  if (parent.type !== _utils.AST_NODE_TYPES.MemberExpression) {
156
121
  break;
157
122
  }
158
-
159
123
  parent = parent.parent;
160
124
  }
161
-
162
125
  return topMostCallExpression;
163
126
  };
164
-
165
127
  exports.findTopMostCallExpression = findTopMostCallExpression;
166
-
167
128
  const isBooleanLiteral = node => node.type === _utils.AST_NODE_TYPES.Literal && typeof node.value === 'boolean';
168
-
169
129
  exports.isBooleanLiteral = isBooleanLiteral;
170
-
171
130
  const getFirstMatcherArg = expectFnCall => {
172
131
  const [firstArg] = expectFnCall.args;
173
-
174
132
  if (firstArg.type === _utils.AST_NODE_TYPES.SpreadElement) {
175
133
  return firstArg;
176
134
  }
177
-
178
135
  return (0, _followTypeAssertionChain.followTypeAssertionChain)(firstArg);
179
136
  };
180
-
181
137
  exports.getFirstMatcherArg = getFirstMatcherArg;
@@ -5,148 +5,112 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getNodeChain = getNodeChain;
7
7
  exports.scopeHasLocalReference = exports.parseJestFnCallWithReason = exports.parseJestFnCall = exports.isTypeOfJestFnCall = void 0;
8
-
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
54
  var _context$settings$jes;
73
-
74
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
82
  var _node$parent2, _node$parent3;
114
-
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
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,52 +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
243
  return node.arguments[0] ?? null;
297
244
  }
298
-
299
245
  return null;
300
246
  };
301
-
302
247
  const describeVariableDefAsImport = def => {
303
248
  var _def$name$parent;
304
-
305
249
  // make sure that we've actually being assigned a value
306
250
  if (!def.node.init) {
307
251
  return null;
308
252
  }
309
-
310
253
  const sourceNode = findImportSourceNode(def.node.init);
311
-
312
254
  if (!sourceNode || !(0, _utils2.isStringNode)(sourceNode)) {
313
255
  return null;
314
256
  }
315
-
316
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) {
317
258
  return null;
318
259
  }
319
-
320
260
  if (!(0, _utils2.isSupportedAccessor)(def.name.parent.key)) {
321
261
  return null;
322
262
  }
323
-
324
263
  return {
325
264
  source: (0, _utils2.getStringValue)(sourceNode),
326
265
  imported: (0, _utils2.getAccessorValue)(def.name.parent.key),
327
266
  local: def.name.name
328
267
  };
329
268
  };
269
+
330
270
  /**
331
271
  * Attempts to describe a definition as an import if possible.
332
272
  *
@@ -337,61 +277,47 @@ const describeVariableDefAsImport = def => {
337
277
  * If it's neither of these, `null` is returned to indicate that the definition
338
278
  * is not describable as an import of any kind.
339
279
  */
340
-
341
-
342
280
  const describePossibleImportDef = def => {
343
281
  if (def.type === 'Variable') {
344
282
  return describeVariableDefAsImport(def);
345
283
  }
346
-
347
284
  if (def.type === 'ImportBinding') {
348
285
  return describeImportDefAsImport(def);
349
286
  }
350
-
351
287
  return null;
352
288
  };
353
-
354
289
  const collectReferences = scope => {
355
290
  const locals = new Set();
356
291
  const imports = new Map();
357
292
  const unresolved = new Set();
358
293
  let currentScope = scope;
359
-
360
294
  while (currentScope !== null) {
361
295
  for (const ref of currentScope.variables) {
362
296
  if (ref.defs.length === 0) {
363
297
  continue;
364
298
  }
365
-
366
299
  const def = ref.defs[ref.defs.length - 1];
367
300
  const importDetails = describePossibleImportDef(def);
368
-
369
301
  if (importDetails) {
370
302
  imports.set(importDetails.local, importDetails);
371
303
  continue;
372
304
  }
373
-
374
305
  locals.add(ref.name);
375
306
  }
376
-
377
307
  for (const ref of currentScope.through) {
378
308
  unresolved.add(ref.identifier.name);
379
309
  }
380
-
381
310
  currentScope = currentScope.upper;
382
311
  }
383
-
384
312
  return {
385
313
  locals,
386
314
  imports,
387
315
  unresolved
388
316
  };
389
317
  };
390
-
391
318
  const resolveToJestFn = (context, identifier) => {
392
319
  const references = collectReferences(context.getScope());
393
320
  const maybeImport = references.imports.get(identifier);
394
-
395
321
  if (maybeImport) {
396
322
  // the identifier is imported from @jest/globals,
397
323
  // so return the original import name
@@ -402,31 +328,30 @@ const resolveToJestFn = (context, identifier) => {
402
328
  type: 'import'
403
329
  };
404
330
  }
405
-
406
331
  return null;
407
- } // the identifier was found as a local variable or function declaration
408
- // meaning it's not a function from jest
409
-
332
+ }
410
333
 
334
+ // the identifier was found as a local variable or function declaration
335
+ // meaning it's not a function from jest
411
336
  if (references.locals.has(identifier)) {
412
337
  return null;
413
338
  }
414
-
415
339
  return {
416
340
  original: resolvePossibleAliasedGlobal(identifier, context),
417
341
  local: identifier,
418
342
  type: 'global'
419
343
  };
420
344
  };
421
-
422
345
  const scopeHasLocalReference = (scope, referenceName) => {
423
346
  const references = collectReferences(scope);
424
- return (// referenceName was found as a local variable or function declaration.
425
- references.locals.has(referenceName) || // referenceName was found as an imported identifier
426
- references.imports.has(referenceName) || // referenceName was not found as an unresolved reference,
347
+ return (
348
+ // referenceName was found as a local variable or function declaration.
349
+ references.locals.has(referenceName) ||
350
+ // referenceName was found as an imported identifier
351
+ references.imports.has(referenceName) ||
352
+ // referenceName was not found as an unresolved reference,
427
353
  // meaning it is likely not an implicit global reference.
428
354
  !references.unresolved.has(referenceName)
429
355
  );
430
356
  };
431
-
432
357
  exports.scopeHasLocalReference = scopeHasLocalReference;