eslint-plugin-jest 26.6.0 → 26.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _utils = require("@typescript-eslint/utils");
9
+
10
+ var _utils2 = require("./utils");
11
+
12
+ const withOnce = (name, addOnce) => {
13
+ return `${name}${addOnce ? 'Once' : ''}`;
14
+ };
15
+
16
+ const findSingleReturnArgumentNode = fnNode => {
17
+ var _fnNode$body$body$;
18
+
19
+ if (fnNode.body.type !== _utils.AST_NODE_TYPES.BlockStatement) {
20
+ return fnNode.body;
21
+ }
22
+
23
+ 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
+ return fnNode.body.body[0].argument;
25
+ }
26
+
27
+ return null;
28
+ };
29
+
30
+ var _default = (0, _utils2.createRule)({
31
+ name: __filename,
32
+ meta: {
33
+ docs: {
34
+ category: 'Best Practices',
35
+ description: 'Prefer mock resolved/rejected shorthands for promises',
36
+ recommended: false
37
+ },
38
+ messages: {
39
+ useMockShorthand: 'Prefer {{ replacement }}'
40
+ },
41
+ schema: [],
42
+ type: 'suggestion',
43
+ fixable: 'code'
44
+ },
45
+ defaultOptions: [],
46
+
47
+ create(context) {
48
+ const report = (property, isOnce, outerArgNode, innerArgNode = outerArgNode) => {
49
+ if ((innerArgNode === null || innerArgNode === void 0 ? void 0 : innerArgNode.type) !== _utils.AST_NODE_TYPES.CallExpression) {
50
+ return;
51
+ }
52
+
53
+ const argName = (0, _utils2.getNodeName)(innerArgNode);
54
+
55
+ if (argName !== 'Promise.resolve' && argName !== 'Promise.reject') {
56
+ return;
57
+ }
58
+
59
+ const replacement = withOnce(argName.endsWith('reject') ? 'mockRejectedValue' : 'mockResolvedValue', isOnce);
60
+ context.report({
61
+ node: property,
62
+ messageId: 'useMockShorthand',
63
+ data: {
64
+ replacement
65
+ },
66
+
67
+ 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
70
+
71
+ if (innerArgNode.arguments.length > 1) {
72
+ return null;
73
+ }
74
+
75
+ return [fixer.replaceText(property, replacement), fixer.replaceText(outerArgNode, // the value argument for both Promise methods is optional,
76
+ // whereas for Jest they're required so use an explicit undefined
77
+ // if no argument is being passed to the call we're replacing
78
+ innerArgNode.arguments.length === 1 ? sourceCode.getText(innerArgNode.arguments[0]) : 'undefined')];
79
+ }
80
+
81
+ });
82
+ };
83
+
84
+ return {
85
+ CallExpression(node) {
86
+ if (node.callee.type !== _utils.AST_NODE_TYPES.MemberExpression || !(0, _utils2.isSupportedAccessor)(node.callee.property) || node.arguments.length === 0) {
87
+ return;
88
+ }
89
+
90
+ const mockFnName = (0, _utils2.getAccessorValue)(node.callee.property);
91
+ const isOnce = mockFnName.endsWith('Once');
92
+
93
+ if (mockFnName === withOnce('mockReturnValue', isOnce)) {
94
+ report(node.callee.property, isOnce, node.arguments[0]);
95
+ } else if (mockFnName === withOnce('mockImplementation', isOnce)) {
96
+ const [arg] = node.arguments;
97
+
98
+ if (!(0, _utils2.isFunction)(arg)) {
99
+ return;
100
+ }
101
+
102
+ report(node.callee.property, isOnce, arg, findSingleReturnArgumentNode(arg));
103
+ }
104
+ }
105
+
106
+ };
107
+ }
108
+
109
+ });
110
+
111
+ exports.default = _default;
@@ -8,28 +8,25 @@ exports.default = void 0;
8
8
  var _utils = require("./utils");
9
9
 
10
10
  const snapshotMatchers = ['toMatchSnapshot', 'toThrowErrorMatchingSnapshot'];
11
+ const snapshotMatcherNames = snapshotMatchers;
11
12
 
12
- const isSnapshotMatcher = matcher => {
13
- return snapshotMatchers.includes(matcher.name);
14
- };
15
-
16
- const isSnapshotMatcherWithoutHint = matcher => {
17
- if (!matcher.arguments || matcher.arguments.length === 0) {
13
+ const isSnapshotMatcherWithoutHint = expectFnCall => {
14
+ if (expectFnCall.args.length === 0) {
18
15
  return true;
19
16
  } // this matcher only supports one argument which is the hint
20
17
 
21
18
 
22
- if (matcher.name !== 'toMatchSnapshot') {
23
- return matcher.arguments.length !== 1;
19
+ if (!(0, _utils.isSupportedAccessor)(expectFnCall.matcher, 'toMatchSnapshot')) {
20
+ return expectFnCall.args.length !== 1;
24
21
  } // if we're being passed two arguments,
25
22
  // the second one should be the hint
26
23
 
27
24
 
28
- if (matcher.arguments.length === 2) {
25
+ if (expectFnCall.args.length === 2) {
29
26
  return false;
30
27
  }
31
28
 
32
- const [arg] = matcher.arguments; // the first argument to `toMatchSnapshot` can be _either_ a snapshot hint or
29
+ const [arg] = expectFnCall.args; // the first argument to `toMatchSnapshot` can be _either_ a snapshot hint or
33
30
  // an object with asymmetric matchers, so we can't just assume that the first
34
31
  // argument is a hint when it's by itself.
35
32
 
@@ -67,7 +64,7 @@ var _default = (0, _utils.createRule)({
67
64
  if (isSnapshotMatcherWithoutHint(snapshotMatcher)) {
68
65
  context.report({
69
66
  messageId: 'missingHint',
70
- node: snapshotMatcher.node.property
67
+ node: snapshotMatcher.matcher
71
68
  });
72
69
  }
73
70
  }
@@ -115,24 +112,24 @@ var _default = (0, _utils.createRule)({
115
112
  },
116
113
 
117
114
  CallExpression(node) {
118
- if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe', 'test'])) {
119
- depths.push(expressionDepth);
120
- expressionDepth = 0;
121
- }
115
+ const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
116
+
117
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
118
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'describe' || (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test') {
119
+ depths.push(expressionDepth);
120
+ expressionDepth = 0;
121
+ }
122
122
 
123
- if (!(0, _utils.isExpectCall)(node)) {
124
123
  return;
125
124
  }
126
125
 
127
- const {
128
- matcher
129
- } = (0, _utils.parseExpectCall)(node);
126
+ const matcherName = (0, _utils.getAccessorValue)(jestFnCall.matcher);
130
127
 
131
- if (!matcher || !isSnapshotMatcher(matcher)) {
128
+ if (!snapshotMatcherNames.includes(matcherName)) {
132
129
  return;
133
130
  }
134
131
 
135
- snapshotMatchers.push(matcher);
132
+ snapshotMatchers.push(jestFnCall);
136
133
  }
137
134
 
138
135
  };
@@ -29,21 +29,23 @@ var _default = (0, _utils.createRule)({
29
29
  create(context) {
30
30
  return {
31
31
  CallExpression(node) {
32
- if (!(0, _utils.isExpectCall)(node)) {
32
+ const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
33
+
34
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
33
35
  return;
34
36
  }
35
37
 
36
38
  const {
37
39
  matcher
38
- } = (0, _utils.parseExpectCall)(node);
40
+ } = jestFnCall;
39
41
 
40
- if (matcher && (0, _utils.isParsedEqualityMatcherCall)(matcher, _utils.EqualityMatcher.toEqual)) {
42
+ if ((0, _utils.isSupportedAccessor)(matcher, 'toEqual')) {
41
43
  context.report({
42
44
  messageId: 'useToStrictEqual',
43
- node: matcher.node.property,
45
+ node: matcher,
44
46
  suggest: [{
45
47
  messageId: 'suggestReplaceWithStrictEqual',
46
- fix: fixer => [(0, _utils.replaceAccessorFixer)(fixer, matcher.node.property, _utils.EqualityMatcher.toStrictEqual)]
48
+ fix: fixer => [(0, _utils.replaceAccessorFixer)(fixer, matcher, _utils.EqualityMatcher.toStrictEqual)]
47
49
  }]
48
50
  });
49
51
  }
@@ -16,12 +16,12 @@ const isNullLiteral = node => node.type === _utils.AST_NODE_TYPES.Literal && nod
16
16
  */
17
17
 
18
18
 
19
- const isNullEqualityMatcher = matcher => isNullLiteral(getFirstArgument(matcher));
19
+ const isNullEqualityMatcher = expectFnCall => isNullLiteral((0, _utils2.getFirstMatcherArg)(expectFnCall));
20
20
 
21
- const isFirstArgumentIdentifier = (matcher, name) => (0, _utils2.isIdentifier)(getFirstArgument(matcher), name);
21
+ const isFirstArgumentIdentifier = (expectFnCall, name) => (0, _utils2.isIdentifier)((0, _utils2.getFirstMatcherArg)(expectFnCall), name);
22
22
 
23
- const shouldUseToBe = matcher => {
24
- const firstArg = getFirstArgument(matcher);
23
+ const shouldUseToBe = expectFnCall => {
24
+ const firstArg = (0, _utils2.getFirstMatcherArg)(expectFnCall);
25
25
 
26
26
  if (firstArg.type === _utils.AST_NODE_TYPES.Literal) {
27
27
  // regex literals are classed as literals, but they're actually objects
@@ -32,32 +32,27 @@ const shouldUseToBe = matcher => {
32
32
  return firstArg.type === _utils.AST_NODE_TYPES.TemplateLiteral;
33
33
  };
34
34
 
35
- const getFirstArgument = matcher => {
36
- return (0, _utils2.followTypeAssertionChain)(matcher.arguments[0]);
37
- };
38
-
39
- const reportPreferToBe = (context, whatToBe, matcher, modifier) => {
40
- const modifierNode = (modifier === null || modifier === void 0 ? void 0 : modifier.negation) || (modifier === null || modifier === void 0 ? void 0 : modifier.name) === _utils2.ModifierName.not && (modifier === null || modifier === void 0 ? void 0 : modifier.node);
35
+ const reportPreferToBe = (context, whatToBe, expectFnCall, modifierNode) => {
41
36
  context.report({
42
37
  messageId: `useToBe${whatToBe}`,
43
38
 
44
39
  fix(fixer) {
45
- var _matcher$arguments;
40
+ var _expectFnCall$args;
46
41
 
47
- const fixes = [(0, _utils2.replaceAccessorFixer)(fixer, matcher.node.property, `toBe${whatToBe}`)];
42
+ const fixes = [(0, _utils2.replaceAccessorFixer)(fixer, expectFnCall.matcher, `toBe${whatToBe}`)];
48
43
 
49
- if ((_matcher$arguments = matcher.arguments) !== null && _matcher$arguments !== void 0 && _matcher$arguments.length && whatToBe !== '') {
50
- fixes.push(fixer.remove(matcher.arguments[0]));
44
+ if ((_expectFnCall$args = expectFnCall.args) !== null && _expectFnCall$args !== void 0 && _expectFnCall$args.length && whatToBe !== '') {
45
+ fixes.push(fixer.remove(expectFnCall.args[0]));
51
46
  }
52
47
 
53
48
  if (modifierNode) {
54
- fixes.push(fixer.removeRange([modifierNode.property.range[0] - 1, modifierNode.property.range[1]]));
49
+ fixes.push(fixer.removeRange([modifierNode.range[0] - 1, modifierNode.range[1]]));
55
50
  }
56
51
 
57
52
  return fixes;
58
53
  },
59
54
 
60
- node: matcher.node.property
55
+ node: expectFnCall.matcher
61
56
  });
62
57
  };
63
58
 
@@ -85,46 +80,42 @@ var _default = (0, _utils2.createRule)({
85
80
  create(context) {
86
81
  return {
87
82
  CallExpression(node) {
88
- if (!(0, _utils2.isExpectCall)(node)) {
89
- return;
90
- }
91
-
92
- const {
93
- matcher,
94
- modifier
95
- } = (0, _utils2.parseExpectCall)(node);
83
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
96
84
 
97
- if (!matcher) {
85
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
98
86
  return;
99
87
  }
100
88
 
101
- if (((modifier === null || modifier === void 0 ? void 0 : modifier.name) === _utils2.ModifierName.not || modifier !== null && modifier !== void 0 && modifier.negation) && ['toBeUndefined', 'toBeDefined'].includes(matcher.name)) {
102
- reportPreferToBe(context, matcher.name === 'toBeDefined' ? 'Undefined' : 'Defined', matcher, modifier);
89
+ const matcherName = (0, _utils2.getAccessorValue)(jestFnCall.matcher);
90
+ const notModifier = jestFnCall.modifiers.find(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
91
+
92
+ if (notModifier && ['toBeUndefined', 'toBeDefined'].includes(matcherName)) {
93
+ reportPreferToBe(context, matcherName === 'toBeDefined' ? 'Undefined' : 'Defined', jestFnCall, notModifier);
103
94
  return;
104
95
  }
105
96
 
106
- if (!(0, _utils2.isParsedEqualityMatcherCall)(matcher)) {
97
+ if (!_utils2.EqualityMatcher.hasOwnProperty(matcherName) || jestFnCall.args.length === 0) {
107
98
  return;
108
99
  }
109
100
 
110
- if (isNullEqualityMatcher(matcher)) {
111
- reportPreferToBe(context, 'Null', matcher);
101
+ if (isNullEqualityMatcher(jestFnCall)) {
102
+ reportPreferToBe(context, 'Null', jestFnCall);
112
103
  return;
113
104
  }
114
105
 
115
- if (isFirstArgumentIdentifier(matcher, 'undefined')) {
116
- const name = (modifier === null || modifier === void 0 ? void 0 : modifier.name) === _utils2.ModifierName.not || modifier !== null && modifier !== void 0 && modifier.negation ? 'Defined' : 'Undefined';
117
- reportPreferToBe(context, name, matcher, modifier);
106
+ if (isFirstArgumentIdentifier(jestFnCall, 'undefined')) {
107
+ const name = notModifier ? 'Defined' : 'Undefined';
108
+ reportPreferToBe(context, name, jestFnCall, notModifier);
118
109
  return;
119
110
  }
120
111
 
121
- if (isFirstArgumentIdentifier(matcher, 'NaN')) {
122
- reportPreferToBe(context, 'NaN', matcher);
112
+ if (isFirstArgumentIdentifier(jestFnCall, 'NaN')) {
113
+ reportPreferToBe(context, 'NaN', jestFnCall);
123
114
  return;
124
115
  }
125
116
 
126
- if (shouldUseToBe(matcher) && matcher.name !== _utils2.EqualityMatcher.toBe) {
127
- reportPreferToBe(context, '', matcher);
117
+ if (shouldUseToBe(jestFnCall) && matcherName !== _utils2.EqualityMatcher.toBe) {
118
+ reportPreferToBe(context, '', jestFnCall);
128
119
  }
129
120
  }
130
121
 
@@ -9,22 +9,6 @@ var _utils = require("@typescript-eslint/utils");
9
9
 
10
10
  var _utils2 = require("./utils");
11
11
 
12
- const isBooleanLiteral = node => node.type === _utils.AST_NODE_TYPES.Literal && typeof node.value === 'boolean';
13
-
14
- /**
15
- * Checks if the given `ParsedExpectMatcher` is a call to one of the equality matchers,
16
- * with a boolean literal as the sole argument.
17
- *
18
- * @example javascript
19
- * toBe(true);
20
- * toEqual(false);
21
- *
22
- * @param {ParsedExpectMatcher} matcher
23
- *
24
- * @return {matcher is ParsedBooleanEqualityMatcher}
25
- */
26
- const isBooleanEqualityMatcher = matcher => (0, _utils2.isParsedEqualityMatcherCall)(matcher) && isBooleanLiteral((0, _utils2.followTypeAssertionChain)(matcher.arguments[0]));
27
-
28
12
  /**
29
13
  * Checks if the given `node` is a `CallExpression` representing the calling
30
14
  * of an `includes`-like method that can be 'fixed' (using `toContain`).
@@ -33,7 +17,7 @@ const isBooleanEqualityMatcher = matcher => (0, _utils2.isParsedEqualityMatcherC
33
17
  *
34
18
  * @return {node is FixableIncludesCallExpression}
35
19
  */
36
- 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); // expect(array.includes(<value>)[not.]{toBe,toEqual}(<boolean>)
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>)
37
21
 
38
22
 
39
23
  var _default = (0, _utils2.createRule)({
@@ -56,37 +40,48 @@ var _default = (0, _utils2.createRule)({
56
40
  create(context) {
57
41
  return {
58
42
  CallExpression(node) {
59
- if (!(0, _utils2.isExpectCall)(node)) {
43
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
44
+
45
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect' || jestFnCall.args.length === 0) {
60
46
  return;
61
47
  }
62
48
 
63
49
  const {
64
- expect: {
65
- arguments: [includesCall],
66
- range: [, expectCallEnd]
67
- },
68
- matcher,
69
- modifier
70
- } = (0, _utils2.parseExpectCall)(node);
50
+ parent: expect
51
+ } = jestFnCall.head.node;
52
+
53
+ if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
54
+ return;
55
+ }
56
+
57
+ const {
58
+ arguments: [includesCall],
59
+ range: [, expectCallEnd]
60
+ } = expect;
61
+ const {
62
+ matcher
63
+ } = jestFnCall;
64
+ const matcherArg = (0, _utils2.getFirstMatcherArg)(jestFnCall);
71
65
 
72
- if (!matcher || !includesCall || modifier && modifier.name !== _utils2.ModifierName.not || !isBooleanEqualityMatcher(matcher) || !isFixableIncludesCallExpression(includesCall)) {
66
+ if (!includesCall || matcherArg.type === _utils.AST_NODE_TYPES.SpreadElement || !_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || !(0, _utils2.isBooleanLiteral)(matcherArg) || !isFixableIncludesCallExpression(includesCall)) {
73
67
  return;
74
68
  }
75
69
 
70
+ const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
76
71
  context.report({
77
72
  fix(fixer) {
78
73
  const sourceCode = context.getSourceCode(); // we need to negate the expectation if the current expected
79
74
  // value is itself negated by the "not" modifier
80
75
 
81
- const addNotModifier = (0, _utils2.followTypeAssertionChain)(matcher.arguments[0]).value === !!modifier;
76
+ const addNotModifier = matcherArg.value === hasNot;
82
77
  return [// remove the "includes" call entirely
83
78
  fixer.removeRange([includesCall.callee.property.range[0] - 1, includesCall.range[1]]), // replace the current matcher with "toContain", adding "not" if needed
84
- fixer.replaceTextRange([expectCallEnd, matcher.node.range[1]], addNotModifier ? `.${_utils2.ModifierName.not}.toContain` : '.toContain'), // replace the matcher argument with the value from the "includes"
85
- fixer.replaceText(matcher.arguments[0], sourceCode.getText(includesCall.arguments[0]))];
79
+ fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], addNotModifier ? `.${_utils2.ModifierName.not}.toContain` : '.toContain'), // replace the matcher argument with the value from the "includes"
80
+ fixer.replaceText(jestFnCall.args[0], sourceCode.getText(includesCall.arguments[0]))];
86
81
  },
87
82
 
88
83
  messageId: 'useToContain',
89
- node: (modifier || matcher).node.property
84
+ node: matcher
90
85
  });
91
86
  }
92
87
 
@@ -29,18 +29,26 @@ var _default = (0, _utils2.createRule)({
29
29
  create(context) {
30
30
  return {
31
31
  CallExpression(node) {
32
- if (!(0, _utils2.isExpectCall)(node)) {
32
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
33
+
34
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
33
35
  return;
34
36
  }
35
37
 
36
38
  const {
37
- expect: {
38
- arguments: [argument]
39
- },
39
+ parent: expect
40
+ } = jestFnCall.head.node;
41
+
42
+ if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
43
+ return;
44
+ }
45
+
46
+ const [argument] = expect.arguments;
47
+ const {
40
48
  matcher
41
- } = (0, _utils2.parseExpectCall)(node);
49
+ } = jestFnCall;
42
50
 
43
- if (!matcher || !(0, _utils2.isParsedEqualityMatcherCall)(matcher) || (argument === null || argument === void 0 ? void 0 : argument.type) !== _utils.AST_NODE_TYPES.MemberExpression || !(0, _utils2.isSupportedAccessor)(argument.property, 'length')) {
51
+ 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')) {
44
52
  return;
45
53
  }
46
54
 
@@ -48,11 +56,11 @@ var _default = (0, _utils2.createRule)({
48
56
  fix(fixer) {
49
57
  return [// remove the "length" property accessor
50
58
  fixer.removeRange([argument.property.range[0] - 1, argument.range[1]]), // replace the current matcher with "toHaveLength"
51
- fixer.replaceTextRange([matcher.node.object.range[1], matcher.node.range[1]], '.toHaveLength')];
59
+ fixer.replaceTextRange([matcher.parent.object.range[1], matcher.parent.range[1]], '.toHaveLength')];
52
60
  },
53
61
 
54
62
  messageId: 'useToHaveLength',
55
- node: matcher.node.property
63
+ node: matcher
56
64
  });
57
65
  }
58
66
 
@@ -26,25 +26,25 @@ var _default = (0, _utils.createRule)({
26
26
  create(context) {
27
27
  return {
28
28
  CallExpression(node) {
29
- var _matcher$arguments;
29
+ const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
30
30
 
31
- if (!(0, _utils.isExpectCall)(node)) {
31
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
32
32
  return;
33
33
  }
34
34
 
35
35
  const {
36
- matcher,
37
- modifier
38
- } = (0, _utils.parseExpectCall)(node);
36
+ matcher
37
+ } = jestFnCall;
38
+ const matcherName = (0, _utils.getAccessorValue)(matcher);
39
39
 
40
- if ((matcher === null || matcher === void 0 ? void 0 : (_matcher$arguments = matcher.arguments) === null || _matcher$arguments === void 0 ? void 0 : _matcher$arguments.length) === 0 && ['toThrow', 'toThrowError'].includes(matcher.name) && (!modifier || !(modifier.name === _utils.ModifierName.not || modifier.negation))) {
40
+ if (jestFnCall.args.length === 0 && ['toThrow', 'toThrowError'].includes(matcherName) && !jestFnCall.modifiers.some(nod => (0, _utils.getAccessorValue)(nod) === 'not')) {
41
41
  // Look for `toThrow` calls with no arguments.
42
42
  context.report({
43
43
  messageId: 'addErrorMessage',
44
44
  data: {
45
- matcherName: matcher.name
45
+ matcherName
46
46
  },
47
- node: matcher.node.property
47
+ node: matcher
48
48
  });
49
49
  }
50
50
  }
@@ -5,25 +5,11 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _utils = require("./utils");
8
+ var _utils = require("@typescript-eslint/utils");
9
9
 
10
- const toThrowMatchers = ['toThrow', 'toThrowError', 'toThrowErrorMatchingSnapshot', 'toThrowErrorMatchingInlineSnapshot'];
11
-
12
- const isJestExpectToThrowCall = node => {
13
- if (!(0, _utils.isExpectCall)(node)) {
14
- return false;
15
- }
16
-
17
- const {
18
- matcher
19
- } = (0, _utils.parseExpectCall)(node);
20
-
21
- if (!matcher) {
22
- return false;
23
- }
10
+ var _utils2 = require("./utils");
24
11
 
25
- return !toThrowMatchers.includes(matcher.name);
26
- };
12
+ const toThrowMatchers = ['toThrow', 'toThrowError', 'toThrowErrorMatchingSnapshot', 'toThrowErrorMatchingInlineSnapshot'];
27
13
 
28
14
  const baseRule = (() => {
29
15
  try {
@@ -52,7 +38,7 @@ const tryCreateBaseRule = context => {
52
38
 
53
39
  const DEFAULT_MESSAGE = 'This rule requires `@typescript-eslint/eslint-plugin`';
54
40
 
55
- var _default = (0, _utils.createRule)({
41
+ var _default = (0, _utils2.createRule)({
56
42
  defaultOptions: [{
57
43
  ignoreStatic: false
58
44
  }],
@@ -84,24 +70,23 @@ var _default = (0, _utils.createRule)({
84
70
  return {};
85
71
  }
86
72
 
87
- let inExpectToThrowCall = false;
88
73
  return { ...baseSelectors,
89
74
 
90
- CallExpression(node) {
91
- inExpectToThrowCall = isJestExpectToThrowCall(node);
92
- },
75
+ MemberExpression(node) {
76
+ var _node$parent, _baseSelectors$Member;
93
77
 
94
- 'CallExpression:exit'(node) {
95
- if (inExpectToThrowCall && isJestExpectToThrowCall(node)) {
96
- inExpectToThrowCall = false;
97
- }
98
- },
78
+ if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) === _utils.AST_NODE_TYPES.CallExpression) {
79
+ const jestFnCall = (0, _utils2.parseJestFnCall)((0, _utils2.findTopMostCallExpression)(node.parent), context);
99
80
 
100
- MemberExpression(node) {
101
- var _baseSelectors$Member;
81
+ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect') {
82
+ const {
83
+ matcher
84
+ } = jestFnCall;
102
85
 
103
- if (inExpectToThrowCall) {
104
- return;
86
+ if (!toThrowMatchers.includes((0, _utils2.getAccessorValue)(matcher))) {
87
+ return;
88
+ }
89
+ }
105
90
  }
106
91
 
107
92
  (_baseSelectors$Member = baseSelectors.MemberExpression) === null || _baseSelectors$Member === void 0 ? void 0 : _baseSelectors$Member.call(baseSelectors, node);
@@ -67,17 +67,4 @@ Object.keys(_parseJestFnCall).forEach(function (key) {
67
67
  return _parseJestFnCall[key];
68
68
  }
69
69
  });
70
- });
71
-
72
- var _parseExpectCall = require("./parseExpectCall");
73
-
74
- Object.keys(_parseExpectCall).forEach(function (key) {
75
- if (key === "default" || key === "__esModule") return;
76
- if (key in exports && exports[key] === _parseExpectCall[key]) return;
77
- Object.defineProperty(exports, key, {
78
- enumerable: true,
79
- get: function () {
80
- return _parseExpectCall[key];
81
- }
82
- });
83
70
  });