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,46 +4,38 @@ 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 isFirstStatement = node => {
13
10
  let parent = node;
14
-
15
11
  while (parent) {
16
- var _parent$parent;
17
-
12
+ var _parent$parent, _parent$parent2;
18
13
  if (((_parent$parent = parent.parent) === null || _parent$parent === void 0 ? void 0 : _parent$parent.type) === _utils.AST_NODE_TYPES.BlockStatement) {
19
14
  return parent.parent.body[0] === parent;
20
15
  }
21
16
 
17
+ // if we've hit an arrow function, then it must have a single expression
18
+ // as its body, as otherwise we would have hit the block statement already
19
+ if (((_parent$parent2 = parent.parent) === null || _parent$parent2 === void 0 ? void 0 : _parent$parent2.type) === _utils.AST_NODE_TYPES.ArrowFunctionExpression) {
20
+ return true;
21
+ }
22
22
  parent = parent.parent;
23
23
  }
24
- /* istanbul ignore next */
25
-
26
24
 
25
+ /* istanbul ignore next */
27
26
  throw new Error(`Could not find BlockStatement - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
28
27
  };
29
-
30
- const suggestRemovingExtraArguments = (args, extraArgsStartAt) => ({
28
+ const suggestRemovingExtraArguments = (context, func, from) => ({
31
29
  messageId: 'suggestRemovingExtraArguments',
32
- fix: fixer => fixer.removeRange([args[extraArgsStartAt].range[0] - Math.sign(extraArgsStartAt), args[args.length - 1].range[1]])
30
+ fix: fixer => (0, _utils2.removeExtraArgumentsFixer)(fixer, context, func, from)
33
31
  });
34
-
35
- // const suggestions: Array<[MessageIds, string]> = [
36
- // ['suggestAddingHasAssertions', 'expect.hasAssertions();'],
37
- // ['suggestAddingAssertions', 'expect.assertions();'],
38
- // ];
39
32
  var _default = (0, _utils2.createRule)({
40
33
  name: __filename,
41
34
  meta: {
42
35
  docs: {
43
36
  category: 'Best Practices',
44
37
  description: 'Suggest using `expect.assertions()` OR `expect.hasAssertions()`',
45
- recommended: false,
46
- suggestion: true
38
+ recommended: false
47
39
  },
48
40
  messages: {
49
41
  hasAssertionsTakesNoArguments: '`expect.hasAssertions` expects no arguments',
@@ -77,7 +69,6 @@ var _default = (0, _utils2.createRule)({
77
69
  onlyFunctionsWithExpectInLoop: false,
78
70
  onlyFunctionsWithExpectInCallback: false
79
71
  }],
80
-
81
72
  create(context, [options]) {
82
73
  let expressionDepth = 0;
83
74
  let hasExpectInCallback = false;
@@ -85,57 +76,47 @@ var _default = (0, _utils2.createRule)({
85
76
  let hasExpectAssertionsAsFirstStatement = false;
86
77
  let inTestCaseCall = false;
87
78
  let inForLoop = false;
88
-
89
79
  const shouldCheckFunction = testFunction => {
90
80
  if (!options.onlyFunctionsWithAsyncKeyword && !options.onlyFunctionsWithExpectInLoop && !options.onlyFunctionsWithExpectInCallback) {
91
81
  return true;
92
82
  }
93
-
94
83
  if (options.onlyFunctionsWithAsyncKeyword) {
95
84
  if (testFunction.async) {
96
85
  return true;
97
86
  }
98
87
  }
99
-
100
88
  if (options.onlyFunctionsWithExpectInLoop) {
101
89
  if (hasExpectInLoop) {
102
90
  return true;
103
91
  }
104
92
  }
105
-
106
93
  if (options.onlyFunctionsWithExpectInCallback) {
107
94
  if (hasExpectInCallback) {
108
95
  return true;
109
96
  }
110
97
  }
111
-
112
98
  return false;
113
99
  };
114
-
115
- const checkExpectHasAssertions = expectFnCall => {
100
+ const checkExpectHasAssertions = (expectFnCall, func) => {
116
101
  if ((0, _utils2.getAccessorValue)(expectFnCall.members[0]) === 'hasAssertions') {
117
102
  if (expectFnCall.args.length) {
118
103
  context.report({
119
104
  messageId: 'hasAssertionsTakesNoArguments',
120
105
  node: expectFnCall.matcher,
121
- suggest: [suggestRemovingExtraArguments(expectFnCall.args, 0)]
106
+ suggest: [suggestRemovingExtraArguments(context, func, 0)]
122
107
  });
123
108
  }
124
-
125
109
  return;
126
110
  }
127
-
128
111
  if (expectFnCall.args.length !== 1) {
129
112
  let {
130
113
  loc
131
114
  } = expectFnCall.matcher;
132
115
  const suggest = [];
133
-
134
116
  if (expectFnCall.args.length) {
135
117
  loc = expectFnCall.args[1].loc;
136
- suggest.push(suggestRemovingExtraArguments(expectFnCall.args, 1));
118
+ suggest.push(suggestRemovingExtraArguments(context, func, 1));
137
119
  }
138
-
139
120
  context.report({
140
121
  messageId: 'assertionsRequiresOneArgument',
141
122
  suggest,
@@ -143,27 +124,19 @@ var _default = (0, _utils2.createRule)({
143
124
  });
144
125
  return;
145
126
  }
146
-
147
127
  const [arg] = expectFnCall.args;
148
-
149
128
  if (arg.type === _utils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value)) {
150
129
  return;
151
130
  }
152
-
153
131
  context.report({
154
132
  messageId: 'assertionsRequiresNumberArgument',
155
133
  node: arg
156
134
  });
157
135
  };
158
-
159
136
  const enterExpression = () => inTestCaseCall && expressionDepth++;
160
-
161
137
  const exitExpression = () => inTestCaseCall && expressionDepth--;
162
-
163
138
  const enterForLoop = () => inForLoop = true;
164
-
165
139
  const exitForLoop = () => inForLoop = false;
166
-
167
140
  return {
168
141
  FunctionExpression: enterExpression,
169
142
  'FunctionExpression:exit': exitExpression,
@@ -175,64 +148,48 @@ var _default = (0, _utils2.createRule)({
175
148
  'ForInStatement:exit': exitForLoop,
176
149
  ForOfStatement: enterForLoop,
177
150
  'ForOfStatement:exit': exitForLoop,
178
-
179
151
  CallExpression(node) {
180
152
  const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
181
-
182
153
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test') {
183
154
  inTestCaseCall = true;
184
155
  return;
185
156
  }
186
-
187
157
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect' && inTestCaseCall) {
188
158
  var _jestFnCall$head$node;
189
-
190
159
  if (expressionDepth === 1 && isFirstStatement(node) && ((_jestFnCall$head$node = jestFnCall.head.node.parent) === null || _jestFnCall$head$node === void 0 ? void 0 : _jestFnCall$head$node.type) === _utils.AST_NODE_TYPES.MemberExpression && jestFnCall.members.length === 1 && ['assertions', 'hasAssertions'].includes((0, _utils2.getAccessorValue)(jestFnCall.members[0]))) {
191
- checkExpectHasAssertions(jestFnCall);
160
+ checkExpectHasAssertions(jestFnCall, node);
192
161
  hasExpectAssertionsAsFirstStatement = true;
193
162
  }
194
-
195
163
  if (inForLoop) {
196
164
  hasExpectInLoop = true;
197
165
  }
198
-
199
166
  if (expressionDepth > 1) {
200
167
  hasExpectInCallback = true;
201
168
  }
202
169
  }
203
170
  },
204
-
205
171
  'CallExpression:exit'(node) {
206
172
  if (!(0, _utils2.isTypeOfJestFnCall)(node, context, ['test'])) {
207
173
  return;
208
174
  }
209
-
210
175
  inTestCaseCall = false;
211
-
212
176
  if (node.arguments.length < 2) {
213
177
  return;
214
178
  }
215
-
216
179
  const [, testFn] = node.arguments;
217
-
218
180
  if (!(0, _utils2.isFunction)(testFn) || !shouldCheckFunction(testFn)) {
219
181
  return;
220
182
  }
221
-
222
183
  hasExpectInLoop = false;
223
184
  hasExpectInCallback = false;
224
-
225
185
  if (hasExpectAssertionsAsFirstStatement) {
226
186
  hasExpectAssertionsAsFirstStatement = false;
227
187
  return;
228
188
  }
229
-
230
189
  const suggestions = [];
231
-
232
190
  if (testFn.body.type === _utils.AST_NODE_TYPES.BlockStatement) {
233
191
  suggestions.push(['suggestAddingHasAssertions', 'expect.hasAssertions();'], ['suggestAddingAssertions', 'expect.assertions();']);
234
192
  }
235
-
236
193
  context.report({
237
194
  messageId: 'haveExpectAssertions',
238
195
  node,
@@ -242,10 +199,7 @@ var _default = (0, _utils2.createRule)({
242
199
  }))
243
200
  });
244
201
  }
245
-
246
202
  };
247
203
  }
248
-
249
204
  });
250
-
251
205
  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
  var _default = (0, _utils2.createRule)({
13
10
  name: __filename,
14
11
  meta: {
@@ -28,35 +25,26 @@ var _default = (0, _utils2.createRule)({
28
25
  create: context => ({
29
26
  CallExpression(node) {
30
27
  const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
31
-
32
28
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
33
29
  return;
34
30
  }
35
-
36
31
  const {
37
32
  parent
38
33
  } = jestFnCall.head.node;
39
-
40
34
  if ((parent === null || parent === void 0 ? void 0 : parent.type) !== _utils.AST_NODE_TYPES.CallExpression) {
41
35
  return;
42
36
  }
43
-
44
37
  const [awaitNode] = parent.arguments;
45
-
46
38
  if ((awaitNode === null || awaitNode === void 0 ? void 0 : awaitNode.type) === _utils.AST_NODE_TYPES.AwaitExpression) {
47
39
  context.report({
48
40
  node: awaitNode,
49
41
  messageId: 'expectResolves',
50
-
51
42
  fix(fixer) {
52
43
  return [fixer.insertTextBefore(parent, 'await '), fixer.removeRange([awaitNode.range[0], awaitNode.argument.range[0]]), fixer.insertTextAfter(parent, '.resolves')];
53
44
  }
54
-
55
45
  });
56
46
  }
57
47
  }
58
-
59
48
  })
60
49
  });
61
-
62
50
  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("./utils");
9
-
10
8
  const HooksOrder = ['beforeAll', 'beforeEach', 'afterEach', 'afterAll'];
11
-
12
9
  var _default = (0, _utils.createRule)({
13
10
  name: __filename,
14
11
  meta: {
@@ -24,7 +21,6 @@ var _default = (0, _utils.createRule)({
24
21
  type: 'suggestion'
25
22
  },
26
23
  defaultOptions: [],
27
-
28
24
  create(context) {
29
25
  let previousHookIndex = -1;
30
26
  let inHook = false;
@@ -34,19 +30,15 @@ var _default = (0, _utils.createRule)({
34
30
  // Ignore everything that is passed into a hook
35
31
  return;
36
32
  }
37
-
38
33
  const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
39
-
40
34
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'hook') {
41
35
  // Reset the previousHookIndex when encountering something different from a hook
42
36
  previousHookIndex = -1;
43
37
  return;
44
38
  }
45
-
46
39
  inHook = true;
47
40
  const currentHook = jestFnCall.name;
48
41
  const currentHookIndex = HooksOrder.indexOf(currentHook);
49
-
50
42
  if (currentHookIndex < previousHookIndex) {
51
43
  context.report({
52
44
  messageId: 'reorderHooks',
@@ -58,27 +50,21 @@ var _default = (0, _utils.createRule)({
58
50
  });
59
51
  return;
60
52
  }
61
-
62
53
  previousHookIndex = currentHookIndex;
63
54
  },
64
-
65
55
  'CallExpression:exit'(node) {
66
56
  if ((0, _utils.isTypeOfJestFnCall)(node, context, ['hook'])) {
67
57
  inHook = false;
68
58
  return;
69
59
  }
70
-
71
60
  if (inHook) {
72
61
  return;
73
- } // Reset the previousHookIndex when encountering something different from a hook
74
-
62
+ }
75
63
 
64
+ // Reset the previousHookIndex when encountering something different from a hook
76
65
  previousHookIndex = -1;
77
66
  }
78
-
79
67
  };
80
68
  }
81
-
82
69
  });
83
-
84
70
  exports.default = _default;
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _utils = require("./utils");
9
-
10
8
  var _default = (0, _utils.createRule)({
11
9
  name: __filename,
12
10
  meta: {
@@ -22,7 +20,6 @@ var _default = (0, _utils.createRule)({
22
20
  type: 'suggestion'
23
21
  },
24
22
  defaultOptions: [],
25
-
26
23
  create(context) {
27
24
  const hooksContext = [false];
28
25
  return {
@@ -30,24 +27,18 @@ var _default = (0, _utils.createRule)({
30
27
  if ((0, _utils.isTypeOfJestFnCall)(node, context, ['test'])) {
31
28
  hooksContext[hooksContext.length - 1] = true;
32
29
  }
33
-
34
30
  if (hooksContext[hooksContext.length - 1] && (0, _utils.isTypeOfJestFnCall)(node, context, ['hook'])) {
35
31
  context.report({
36
32
  messageId: 'noHookOnTop',
37
33
  node
38
34
  });
39
35
  }
40
-
41
36
  hooksContext.push(false);
42
37
  },
43
-
44
38
  'CallExpression:exit'() {
45
39
  hooksContext.pop();
46
40
  }
47
-
48
41
  };
49
42
  }
50
-
51
43
  });
52
-
53
44
  exports.default = _default;
@@ -4,29 +4,21 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _utils = require("./utils");
9
-
10
8
  const hasStringAsFirstArgument = node => node.arguments[0] && (0, _utils.isStringNode)(node.arguments[0]);
11
-
12
9
  const populateIgnores = ignore => {
13
10
  const ignores = [];
14
-
15
11
  if (ignore.includes(_utils.DescribeAlias.describe)) {
16
12
  ignores.push(...Object.keys(_utils.DescribeAlias));
17
13
  }
18
-
19
14
  if (ignore.includes(_utils.TestCaseName.test)) {
20
15
  ignores.push(...Object.keys(_utils.TestCaseName).filter(k => k.endsWith(_utils.TestCaseName.test)));
21
16
  }
22
-
23
17
  if (ignore.includes(_utils.TestCaseName.it)) {
24
18
  ignores.push(...Object.keys(_utils.TestCaseName).filter(k => k.endsWith(_utils.TestCaseName.it)));
25
19
  }
26
-
27
20
  return ignores;
28
21
  };
29
-
30
22
  var _default = (0, _utils.createRule)({
31
23
  name: __filename,
32
24
  meta: {
@@ -70,7 +62,6 @@ var _default = (0, _utils.createRule)({
70
62
  allowedPrefixes: [],
71
63
  ignoreTopLevelDescribe: false
72
64
  }],
73
-
74
65
  create(context, [{
75
66
  ignore = [],
76
67
  allowedPrefixes = [],
@@ -81,60 +72,46 @@ var _default = (0, _utils.createRule)({
81
72
  return {
82
73
  CallExpression(node) {
83
74
  const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
84
-
85
75
  if (!jestFnCall || !hasStringAsFirstArgument(node)) {
86
76
  return;
87
77
  }
88
-
89
78
  if (jestFnCall.type === 'describe') {
90
79
  numberOfDescribeBlocks++;
91
-
92
80
  if (ignoreTopLevelDescribe && numberOfDescribeBlocks === 1) {
93
81
  return;
94
82
  }
95
83
  } else if (jestFnCall.type !== 'test') {
96
84
  return;
97
85
  }
98
-
99
86
  const [firstArg] = node.arguments;
100
87
  const description = (0, _utils.getStringValue)(firstArg);
101
-
102
88
  if (allowedPrefixes.some(name => description.startsWith(name))) {
103
89
  return;
104
90
  }
105
-
106
91
  const firstCharacter = description.charAt(0);
107
-
108
92
  if (!firstCharacter || firstCharacter === firstCharacter.toLowerCase() || ignores.includes(jestFnCall.name)) {
109
93
  return;
110
94
  }
111
-
112
95
  context.report({
113
96
  messageId: 'unexpectedLowercase',
114
97
  node: node.arguments[0],
115
98
  data: {
116
99
  method: jestFnCall.name
117
100
  },
118
-
119
101
  fix(fixer) {
120
102
  const description = (0, _utils.getStringValue)(firstArg);
121
103
  const rangeIgnoringQuotes = [firstArg.range[0] + 1, firstArg.range[1] - 1];
122
104
  const newDescription = description.substring(0, 1).toLowerCase() + description.substring(1);
123
105
  return [fixer.replaceTextRange(rangeIgnoringQuotes, newDescription)];
124
106
  }
125
-
126
107
  });
127
108
  },
128
-
129
109
  'CallExpression:exit'(node) {
130
110
  if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe'])) {
131
111
  numberOfDescribeBlocks--;
132
112
  }
133
113
  }
134
-
135
114
  };
136
115
  }
137
-
138
116
  });
139
-
140
117
  exports.default = _default;
@@ -4,29 +4,21 @@ 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 withOnce = (name, addOnce) => {
13
10
  return `${name}${addOnce ? 'Once' : ''}`;
14
11
  };
15
-
16
12
  const findSingleReturnArgumentNode = fnNode => {
17
13
  var _fnNode$body$body$;
18
-
19
14
  if (fnNode.body.type !== _utils.AST_NODE_TYPES.BlockStatement) {
20
15
  return fnNode.body;
21
16
  }
22
-
23
17
  if (((_fnNode$body$body$ = fnNode.body.body[0]) === null || _fnNode$body$body$ === void 0 ? void 0 : _fnNode$body$body$.type) === _utils.AST_NODE_TYPES.ReturnStatement) {
24
18
  return fnNode.body.body[0].argument;
25
19
  }
26
-
27
20
  return null;
28
21
  };
29
-
30
22
  var _default = (0, _utils2.createRule)({
31
23
  name: __filename,
32
24
  meta: {
@@ -43,19 +35,15 @@ var _default = (0, _utils2.createRule)({
43
35
  fixable: 'code'
44
36
  },
45
37
  defaultOptions: [],
46
-
47
38
  create(context) {
48
39
  const report = (property, isOnce, outerArgNode, innerArgNode = outerArgNode) => {
49
40
  if ((innerArgNode === null || innerArgNode === void 0 ? void 0 : innerArgNode.type) !== _utils.AST_NODE_TYPES.CallExpression) {
50
41
  return;
51
42
  }
52
-
53
43
  const argName = (0, _utils2.getNodeName)(innerArgNode);
54
-
55
44
  if (argName !== 'Promise.resolve' && argName !== 'Promise.reject') {
56
45
  return;
57
46
  }
58
-
59
47
  const replacement = withOnce(argName.endsWith('reject') ? 'mockRejectedValue' : 'mockResolvedValue', isOnce);
60
48
  context.report({
61
49
  node: property,
@@ -63,49 +51,40 @@ var _default = (0, _utils2.createRule)({
63
51
  data: {
64
52
  replacement
65
53
  },
66
-
67
54
  fix(fixer) {
68
- const sourceCode = context.getSourceCode(); // there shouldn't be more than one argument, but if there is don't try
69
- // fixing since we have no idea what to do with the extra arguments
55
+ const sourceCode = context.getSourceCode();
70
56
 
57
+ // there shouldn't be more than one argument, but if there is don't try
58
+ // fixing since we have no idea what to do with the extra arguments
71
59
  if (innerArgNode.arguments.length > 1) {
72
60
  return null;
73
61
  }
74
-
75
- return [fixer.replaceText(property, replacement), fixer.replaceText(outerArgNode, // the value argument for both Promise methods is optional,
62
+ return [fixer.replaceText(property, replacement), fixer.replaceText(outerArgNode,
63
+ // the value argument for both Promise methods is optional,
76
64
  // whereas for Jest they're required so use an explicit undefined
77
65
  // if no argument is being passed to the call we're replacing
78
66
  innerArgNode.arguments.length === 1 ? sourceCode.getText(innerArgNode.arguments[0]) : 'undefined')];
79
67
  }
80
-
81
68
  });
82
69
  };
83
-
84
70
  return {
85
71
  CallExpression(node) {
86
72
  if (node.callee.type !== _utils.AST_NODE_TYPES.MemberExpression || !(0, _utils2.isSupportedAccessor)(node.callee.property) || node.arguments.length === 0) {
87
73
  return;
88
74
  }
89
-
90
75
  const mockFnName = (0, _utils2.getAccessorValue)(node.callee.property);
91
76
  const isOnce = mockFnName.endsWith('Once');
92
-
93
77
  if (mockFnName === withOnce('mockReturnValue', isOnce)) {
94
78
  report(node.callee.property, isOnce, node.arguments[0]);
95
79
  } else if (mockFnName === withOnce('mockImplementation', isOnce)) {
96
80
  const [arg] = node.arguments;
97
-
98
81
  if (!(0, _utils2.isFunction)(arg) || arg.params.length !== 0) {
99
82
  return;
100
83
  }
101
-
102
84
  report(node.callee.property, isOnce, arg, findSingleReturnArgumentNode(arg));
103
85
  }
104
86
  }
105
-
106
87
  };
107
88
  }
108
-
109
89
  });
110
-
111
90
  exports.default = _default;