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,39 +4,34 @@ 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 snapshotMatchers = ['toMatchSnapshot', 'toThrowErrorMatchingSnapshot'];
11
9
  const snapshotMatcherNames = snapshotMatchers;
12
-
13
10
  const isSnapshotMatcherWithoutHint = expectFnCall => {
14
11
  if (expectFnCall.args.length === 0) {
15
12
  return true;
16
- } // this matcher only supports one argument which is the hint
17
-
13
+ }
18
14
 
15
+ // this matcher only supports one argument which is the hint
19
16
  if (!(0, _utils.isSupportedAccessor)(expectFnCall.matcher, 'toMatchSnapshot')) {
20
17
  return expectFnCall.args.length !== 1;
21
- } // if we're being passed two arguments,
22
- // the second one should be the hint
23
-
18
+ }
24
19
 
20
+ // if we're being passed two arguments,
21
+ // the second one should be the hint
25
22
  if (expectFnCall.args.length === 2) {
26
23
  return false;
27
24
  }
25
+ const [arg] = expectFnCall.args;
28
26
 
29
- const [arg] = expectFnCall.args; // the first argument to `toMatchSnapshot` can be _either_ a snapshot hint or
27
+ // the first argument to `toMatchSnapshot` can be _either_ a snapshot hint or
30
28
  // an object with asymmetric matchers, so we can't just assume that the first
31
29
  // argument is a hint when it's by itself.
32
-
33
30
  return !(0, _utils.isStringNode)(arg);
34
31
  };
35
-
36
32
  const messages = {
37
33
  missingHint: 'You should provide a hint for this snapshot'
38
34
  };
39
-
40
35
  var _default = (0, _utils.createRule)({
41
36
  name: __filename,
42
37
  meta: {
@@ -53,12 +48,10 @@ var _default = (0, _utils.createRule)({
53
48
  }]
54
49
  },
55
50
  defaultOptions: ['multi'],
56
-
57
51
  create(context, [mode]) {
58
52
  const snapshotMatchers = [];
59
53
  const depths = [];
60
54
  let expressionDepth = 0;
61
-
62
55
  const reportSnapshotMatchersWithoutHints = () => {
63
56
  for (const snapshotMatcher of snapshotMatchers) {
64
57
  if (isSnapshotMatcherWithoutHint(snapshotMatcher)) {
@@ -69,72 +62,53 @@ var _default = (0, _utils.createRule)({
69
62
  }
70
63
  }
71
64
  };
72
-
73
65
  const enterExpression = () => {
74
66
  expressionDepth++;
75
67
  };
76
-
77
68
  const exitExpression = () => {
78
69
  expressionDepth--;
79
-
80
70
  if (mode === 'always') {
81
71
  reportSnapshotMatchersWithoutHints();
82
72
  snapshotMatchers.length = 0;
83
73
  }
84
-
85
74
  if (mode === 'multi' && expressionDepth === 0) {
86
75
  if (snapshotMatchers.length > 1) {
87
76
  reportSnapshotMatchersWithoutHints();
88
77
  }
89
-
90
78
  snapshotMatchers.length = 0;
91
79
  }
92
80
  };
93
-
94
81
  return {
95
82
  'Program:exit'() {
96
83
  enterExpression();
97
84
  exitExpression();
98
85
  },
99
-
100
86
  FunctionExpression: enterExpression,
101
87
  'FunctionExpression:exit': exitExpression,
102
88
  ArrowFunctionExpression: enterExpression,
103
89
  'ArrowFunctionExpression:exit': exitExpression,
104
-
105
90
  'CallExpression:exit'(node) {
106
91
  if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe', 'test'])) {
107
- var _depths$pop;
108
-
109
92
  /* istanbul ignore next */
110
- expressionDepth = (_depths$pop = depths.pop()) !== null && _depths$pop !== void 0 ? _depths$pop : 0;
93
+ expressionDepth = depths.pop() ?? 0;
111
94
  }
112
95
  },
113
-
114
96
  CallExpression(node) {
115
97
  const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
116
-
117
98
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
118
99
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'describe' || (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test') {
119
100
  depths.push(expressionDepth);
120
101
  expressionDepth = 0;
121
102
  }
122
-
123
103
  return;
124
104
  }
125
-
126
105
  const matcherName = (0, _utils.getAccessorValue)(jestFnCall.matcher);
127
-
128
106
  if (!snapshotMatcherNames.includes(matcherName)) {
129
107
  return;
130
108
  }
131
-
132
109
  snapshotMatchers.push(jestFnCall);
133
110
  }
134
-
135
111
  };
136
112
  }
137
-
138
113
  });
139
-
140
114
  exports.default = _default;
@@ -4,41 +4,30 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _utils = require("@typescript-eslint/utils");
9
-
10
8
  var _utils2 = require("./utils");
11
-
12
9
  const findNodeObject = node => {
13
10
  if ('object' in node) {
14
11
  return node.object;
15
12
  }
16
-
17
13
  if (node.callee.type === _utils.AST_NODE_TYPES.MemberExpression) {
18
14
  return node.callee.object;
19
15
  }
20
-
21
16
  return null;
22
17
  };
23
-
24
18
  const getJestFnCall = node => {
25
19
  if (node.type !== _utils.AST_NODE_TYPES.CallExpression && node.type !== _utils.AST_NODE_TYPES.MemberExpression) {
26
20
  return null;
27
21
  }
28
-
29
22
  const obj = findNodeObject(node);
30
-
31
23
  if (!obj) {
32
24
  return null;
33
25
  }
34
-
35
26
  if (obj.type === _utils.AST_NODE_TYPES.Identifier) {
36
27
  return node.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.getNodeName)(node.callee) === 'jest.fn' ? node : null;
37
28
  }
38
-
39
29
  return getJestFnCall(obj);
40
30
  };
41
-
42
31
  var _default = (0, _utils2.createRule)({
43
32
  name: __filename,
44
33
  meta: {
@@ -55,7 +44,6 @@ var _default = (0, _utils2.createRule)({
55
44
  type: 'suggestion'
56
45
  },
57
46
  defaultOptions: [],
58
-
59
47
  create(context) {
60
48
  return {
61
49
  AssignmentExpression(node) {
@@ -69,7 +57,6 @@ var _default = (0, _utils2.createRule)({
69
57
  context.report({
70
58
  node,
71
59
  messageId: 'useJestSpyOn',
72
-
73
60
  fix(fixer) {
74
61
  const leftPropQuote = left.property.type === _utils.AST_NODE_TYPES.Identifier ? "'" : '';
75
62
  const [arg] = jestFnCall.arguments;
@@ -77,13 +64,9 @@ var _default = (0, _utils2.createRule)({
77
64
  const mockImplementation = argSource ? `.mockImplementation(${argSource})` : '.mockImplementation()';
78
65
  return [fixer.insertTextBefore(left, `jest.spyOn(`), fixer.replaceTextRange([left.object.range[1], left.property.range[0]], `, ${leftPropQuote}`), fixer.replaceTextRange([left.property.range[1], jestFnCall.range[1]], `${leftPropQuote})${mockImplementation}`)];
79
66
  }
80
-
81
67
  });
82
68
  }
83
-
84
69
  };
85
70
  }
86
-
87
71
  });
88
-
89
72
  exports.default = _default;
@@ -4,17 +4,14 @@ 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: {
13
11
  docs: {
14
12
  category: 'Best Practices',
15
13
  description: 'Suggest using `toStrictEqual()`',
16
- recommended: false,
17
- suggestion: true
14
+ recommended: false
18
15
  },
19
16
  messages: {
20
17
  useToStrictEqual: 'Use `toStrictEqual()` instead',
@@ -25,20 +22,16 @@ var _default = (0, _utils.createRule)({
25
22
  hasSuggestions: true
26
23
  },
27
24
  defaultOptions: [],
28
-
29
25
  create(context) {
30
26
  return {
31
27
  CallExpression(node) {
32
28
  const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
33
-
34
29
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
35
30
  return;
36
31
  }
37
-
38
32
  const {
39
33
  matcher
40
34
  } = jestFnCall;
41
-
42
35
  if ((0, _utils.isSupportedAccessor)(matcher, 'toEqual')) {
43
36
  context.report({
44
37
  messageId: 'useToStrictEqual',
@@ -50,10 +43,7 @@ var _default = (0, _utils.createRule)({
50
43
  });
51
44
  }
52
45
  }
53
-
54
46
  };
55
47
  }
56
-
57
48
  });
58
-
59
49
  exports.default = _default;
@@ -4,58 +4,45 @@ 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 isNullLiteral = node => node.type === _utils.AST_NODE_TYPES.Literal && node.value === null;
10
+
13
11
  /**
14
12
  * Checks if the given `ParsedEqualityMatcherCall` is a call to one of the equality matchers,
15
13
  * with a `null` literal as the sole argument.
16
14
  */
17
-
18
-
19
15
  const isNullEqualityMatcher = expectFnCall => isNullLiteral((0, _utils2.getFirstMatcherArg)(expectFnCall));
20
-
21
16
  const isFirstArgumentIdentifier = (expectFnCall, name) => (0, _utils2.isIdentifier)((0, _utils2.getFirstMatcherArg)(expectFnCall), name);
22
-
23
17
  const shouldUseToBe = expectFnCall => {
24
- const firstArg = (0, _utils2.getFirstMatcherArg)(expectFnCall);
25
-
18
+ let firstArg = (0, _utils2.getFirstMatcherArg)(expectFnCall);
19
+ if (firstArg.type === _utils.AST_NODE_TYPES.UnaryExpression && firstArg.operator === '-') {
20
+ firstArg = firstArg.argument;
21
+ }
26
22
  if (firstArg.type === _utils.AST_NODE_TYPES.Literal) {
27
23
  // regex literals are classed as literals, but they're actually objects
28
24
  // which means "toBe" will give different results than other matchers
29
25
  return !('regex' in firstArg);
30
26
  }
31
-
32
27
  return firstArg.type === _utils.AST_NODE_TYPES.TemplateLiteral;
33
28
  };
34
-
35
- const reportPreferToBe = (context, whatToBe, expectFnCall, modifierNode) => {
29
+ const reportPreferToBe = (context, whatToBe, expectFnCall, func, modifierNode) => {
36
30
  context.report({
37
31
  messageId: `useToBe${whatToBe}`,
38
-
39
32
  fix(fixer) {
40
33
  var _expectFnCall$args;
41
-
42
34
  const fixes = [(0, _utils2.replaceAccessorFixer)(fixer, expectFnCall.matcher, `toBe${whatToBe}`)];
43
-
44
35
  if ((_expectFnCall$args = expectFnCall.args) !== null && _expectFnCall$args !== void 0 && _expectFnCall$args.length && whatToBe !== '') {
45
- fixes.push(fixer.remove(expectFnCall.args[0]));
36
+ fixes.push((0, _utils2.removeExtraArgumentsFixer)(fixer, context, func, 0));
46
37
  }
47
-
48
38
  if (modifierNode) {
49
39
  fixes.push(fixer.removeRange([modifierNode.range[0] - 1, modifierNode.range[1]]));
50
40
  }
51
-
52
41
  return fixes;
53
42
  },
54
-
55
43
  node: expectFnCall.matcher
56
44
  });
57
45
  };
58
-
59
46
  var _default = (0, _utils2.createRule)({
60
47
  name: __filename,
61
48
  meta: {
@@ -76,52 +63,40 @@ var _default = (0, _utils2.createRule)({
76
63
  schema: []
77
64
  },
78
65
  defaultOptions: [],
79
-
80
66
  create(context) {
81
67
  return {
82
68
  CallExpression(node) {
83
69
  const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
84
-
85
70
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
86
71
  return;
87
72
  }
88
-
89
73
  const matcherName = (0, _utils2.getAccessorValue)(jestFnCall.matcher);
90
74
  const notModifier = jestFnCall.modifiers.find(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
91
-
92
75
  if (notModifier && ['toBeUndefined', 'toBeDefined'].includes(matcherName)) {
93
- reportPreferToBe(context, matcherName === 'toBeDefined' ? 'Undefined' : 'Defined', jestFnCall, notModifier);
76
+ reportPreferToBe(context, matcherName === 'toBeDefined' ? 'Undefined' : 'Defined', jestFnCall, node, notModifier);
94
77
  return;
95
78
  }
96
-
97
79
  if (!_utils2.EqualityMatcher.hasOwnProperty(matcherName) || jestFnCall.args.length === 0) {
98
80
  return;
99
81
  }
100
-
101
82
  if (isNullEqualityMatcher(jestFnCall)) {
102
- reportPreferToBe(context, 'Null', jestFnCall);
83
+ reportPreferToBe(context, 'Null', jestFnCall, node);
103
84
  return;
104
85
  }
105
-
106
86
  if (isFirstArgumentIdentifier(jestFnCall, 'undefined')) {
107
87
  const name = notModifier ? 'Defined' : 'Undefined';
108
- reportPreferToBe(context, name, jestFnCall, notModifier);
88
+ reportPreferToBe(context, name, jestFnCall, node, notModifier);
109
89
  return;
110
90
  }
111
-
112
91
  if (isFirstArgumentIdentifier(jestFnCall, 'NaN')) {
113
- reportPreferToBe(context, 'NaN', jestFnCall);
92
+ reportPreferToBe(context, 'NaN', jestFnCall, node);
114
93
  return;
115
94
  }
116
-
117
95
  if (shouldUseToBe(jestFnCall) && matcherName !== _utils2.EqualityMatcher.toBe) {
118
- reportPreferToBe(context, '', jestFnCall);
96
+ reportPreferToBe(context, '', jestFnCall, node);
119
97
  }
120
98
  }
121
-
122
99
  };
123
100
  }
124
-
125
101
  });
126
-
127
102
  exports.default = _default;
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _utils = require("@typescript-eslint/utils");
9
-
10
8
  var _utils2 = require("./utils");
11
-
12
9
  /**
13
10
  * Checks if the given `node` is a `CallExpression` representing the calling
14
11
  * of an `includes`-like method that can be 'fixed' (using `toContain`).
@@ -17,9 +14,9 @@ var _utils2 = require("./utils");
17
14
  *
18
15
  * @return {node is FixableIncludesCallExpression}
19
16
  */
20
- const isFixableIncludesCallExpression = node => node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property, 'includes') && (0, _utils2.hasOnlyOneArgument)(node) && node.arguments[0].type !== _utils.AST_NODE_TYPES.SpreadElement; // expect(array.includes(<value>)[not.]{toBe,toEqual}(<boolean>)
21
-
17
+ const isFixableIncludesCallExpression = node => node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property, 'includes') && (0, _utils2.hasOnlyOneArgument)(node) && node.arguments[0].type !== _utils.AST_NODE_TYPES.SpreadElement;
22
18
 
19
+ // expect(array.includes(<value>)[not.]{toBe,toEqual}(<boolean>)
23
20
  var _default = (0, _utils2.createRule)({
24
21
  name: __filename,
25
22
  meta: {
@@ -36,24 +33,19 @@ var _default = (0, _utils2.createRule)({
36
33
  schema: []
37
34
  },
38
35
  defaultOptions: [],
39
-
40
36
  create(context) {
41
37
  return {
42
38
  CallExpression(node) {
43
39
  const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
44
-
45
40
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect' || jestFnCall.args.length === 0) {
46
41
  return;
47
42
  }
48
-
49
43
  const {
50
44
  parent: expect
51
45
  } = jestFnCall.head.node;
52
-
53
46
  if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
54
47
  return;
55
48
  }
56
-
57
49
  const {
58
50
  arguments: [includesCall],
59
51
  range: [, expectCallEnd]
@@ -62,32 +54,30 @@ var _default = (0, _utils2.createRule)({
62
54
  matcher
63
55
  } = jestFnCall;
64
56
  const matcherArg = (0, _utils2.getFirstMatcherArg)(jestFnCall);
65
-
66
57
  if (!includesCall || matcherArg.type === _utils.AST_NODE_TYPES.SpreadElement || !_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || !(0, _utils2.isBooleanLiteral)(matcherArg) || !isFixableIncludesCallExpression(includesCall)) {
67
58
  return;
68
59
  }
69
-
70
60
  const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
71
61
  context.report({
72
62
  fix(fixer) {
73
- const sourceCode = context.getSourceCode(); // we need to negate the expectation if the current expected
74
- // value is itself negated by the "not" modifier
63
+ const sourceCode = context.getSourceCode();
75
64
 
65
+ // we need to negate the expectation if the current expected
66
+ // value is itself negated by the "not" modifier
76
67
  const addNotModifier = matcherArg.value === hasNot;
77
- return [// remove the "includes" call entirely
78
- fixer.removeRange([includesCall.callee.property.range[0] - 1, includesCall.range[1]]), // replace the current matcher with "toContain", adding "not" if needed
79
- fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], addNotModifier ? `.${_utils2.ModifierName.not}.toContain` : '.toContain'), // replace the matcher argument with the value from the "includes"
68
+ return [
69
+ // remove the "includes" call entirely
70
+ fixer.removeRange([includesCall.callee.property.range[0] - 1, includesCall.range[1]]),
71
+ // replace the current matcher with "toContain", adding "not" if needed
72
+ fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], addNotModifier ? `.${_utils2.ModifierName.not}.toContain` : '.toContain'),
73
+ // replace the matcher argument with the value from the "includes"
80
74
  fixer.replaceText(jestFnCall.args[0], sourceCode.getText(includesCall.arguments[0]))];
81
75
  },
82
-
83
76
  messageId: 'useToContain',
84
77
  node: matcher
85
78
  });
86
79
  }
87
-
88
80
  };
89
81
  }
90
-
91
82
  });
92
-
93
83
  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: {
@@ -25,48 +22,39 @@ var _default = (0, _utils2.createRule)({
25
22
  schema: []
26
23
  },
27
24
  defaultOptions: [],
28
-
29
25
  create(context) {
30
26
  return {
31
27
  CallExpression(node) {
32
28
  const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
33
-
34
29
  if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
35
30
  return;
36
31
  }
37
-
38
32
  const {
39
33
  parent: expect
40
34
  } = jestFnCall.head.node;
41
-
42
35
  if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
43
36
  return;
44
37
  }
45
-
46
38
  const [argument] = expect.arguments;
47
39
  const {
48
40
  matcher
49
41
  } = jestFnCall;
50
-
51
42
  if (!_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || (argument === null || argument === void 0 ? void 0 : argument.type) !== _utils.AST_NODE_TYPES.MemberExpression || !(0, _utils2.isSupportedAccessor)(argument.property, 'length')) {
52
43
  return;
53
44
  }
54
-
55
45
  context.report({
56
46
  fix(fixer) {
57
- return [// remove the "length" property accessor
58
- fixer.removeRange([argument.property.range[0] - 1, argument.range[1]]), // replace the current matcher with "toHaveLength"
47
+ return [
48
+ // remove the "length" property accessor
49
+ fixer.removeRange([argument.property.range[0] - 1, argument.range[1]]),
50
+ // replace the current matcher with "toHaveLength"
59
51
  fixer.replaceTextRange([matcher.parent.object.range[1], matcher.parent.range[1]], '.toHaveLength')];
60
52
  },
61
-
62
53
  messageId: 'useToHaveLength',
63
54
  node: matcher
64
55
  });
65
56
  }
66
-
67
57
  };
68
58
  }
69
-
70
59
  });
71
-
72
60
  exports.default = _default;
@@ -4,40 +4,31 @@ 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
  function isEmptyFunction(node) {
13
10
  if (!(0, _utils2.isFunction)(node)) {
14
11
  return false;
15
12
  }
16
-
17
13
  return node.body.type === _utils.AST_NODE_TYPES.BlockStatement && !node.body.body.length;
18
14
  }
19
-
20
15
  function createTodoFixer(jestFnCall, fixer) {
21
16
  if (jestFnCall.members.length) {
22
17
  return (0, _utils2.replaceAccessorFixer)(fixer, jestFnCall.members[0], 'todo');
23
18
  }
24
-
25
19
  return fixer.replaceText(jestFnCall.head.node, `${jestFnCall.head.local}.todo`);
26
20
  }
27
-
28
21
  const isTargetedTestCase = jestFnCall => {
29
22
  if (jestFnCall.members.some(s => (0, _utils2.getAccessorValue)(s) !== 'skip')) {
30
23
  return false;
31
- } // todo: we should support this too (needs custom fixer)
32
-
24
+ }
33
25
 
26
+ // todo: we should support this too (needs custom fixer)
34
27
  if (jestFnCall.name.startsWith('x')) {
35
28
  return false;
36
29
  }
37
-
38
30
  return !jestFnCall.name.startsWith('f');
39
31
  };
40
-
41
32
  var _default = (0, _utils2.createRule)({
42
33
  name: __filename,
43
34
  meta: {
@@ -55,17 +46,14 @@ var _default = (0, _utils2.createRule)({
55
46
  type: 'layout'
56
47
  },
57
48
  defaultOptions: [],
58
-
59
49
  create(context) {
60
50
  return {
61
51
  CallExpression(node) {
62
52
  const [title, callback] = node.arguments;
63
53
  const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
64
-
65
54
  if (!title || (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test' || !isTargetedTestCase(jestFnCall) || !(0, _utils2.isStringNode)(title)) {
66
55
  return;
67
56
  }
68
-
69
57
  if (callback && isEmptyFunction(callback)) {
70
58
  context.report({
71
59
  messageId: 'emptyTest',
@@ -73,7 +61,6 @@ var _default = (0, _utils2.createRule)({
73
61
  fix: fixer => [fixer.removeRange([title.range[1], callback.range[1]]), createTodoFixer(jestFnCall, fixer)]
74
62
  });
75
63
  }
76
-
77
64
  if ((0, _utils2.hasOnlyOneArgument)(node)) {
78
65
  context.report({
79
66
  messageId: 'unimplementedTest',
@@ -82,10 +69,7 @@ var _default = (0, _utils2.createRule)({
82
69
  });
83
70
  }
84
71
  }
85
-
86
72
  };
87
73
  }
88
-
89
74
  });
90
-
91
75
  exports.default = _default;