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.
- package/README.md +82 -78
- package/docs/rules/consistent-test-it.md +9 -4
- package/docs/rules/expect-expect.md +5 -0
- package/docs/rules/max-expects.md +3 -1
- package/docs/rules/max-nested-describe.md +3 -1
- package/docs/rules/no-alias-methods.md +13 -2
- package/docs/rules/no-commented-out-tests.md +6 -1
- package/docs/rules/no-conditional-expect.md +7 -2
- package/docs/rules/no-conditional-in-test.md +3 -1
- package/docs/rules/no-deprecated-functions.md +14 -7
- package/docs/rules/no-disabled-tests.md +6 -1
- package/docs/rules/no-done-callback.md +9 -1
- package/docs/rules/no-duplicate-hooks.md +3 -1
- package/docs/rules/no-export.md +6 -1
- package/docs/rules/no-focused-tests.md +10 -1
- package/docs/rules/no-hooks.md +3 -1
- package/docs/rules/no-identical-title.md +6 -1
- package/docs/rules/no-if.md +4 -4
- package/docs/rules/no-interpolation-in-snapshots.md +6 -1
- package/docs/rules/no-jasmine-globals.md +10 -2
- package/docs/rules/no-large-snapshots.md +4 -2
- package/docs/rules/no-mocks-import.md +6 -1
- package/docs/rules/no-restricted-jest-methods.md +51 -0
- package/docs/rules/no-restricted-matchers.md +19 -4
- package/docs/rules/no-standalone-expect.md +6 -1
- package/docs/rules/no-test-prefixes.md +9 -1
- package/docs/rules/no-test-return-statement.md +2 -0
- package/docs/rules/prefer-called-with.md +2 -0
- package/docs/rules/prefer-comparison-matcher.md +5 -0
- package/docs/rules/prefer-each.md +56 -0
- package/docs/rules/prefer-equality-matcher.md +5 -0
- package/docs/rules/prefer-expect-assertions.md +5 -2
- package/docs/rules/prefer-expect-resolves.md +8 -1
- package/docs/rules/prefer-hooks-in-order.md +3 -1
- package/docs/rules/prefer-hooks-on-top.md +3 -1
- package/docs/rules/prefer-lowercase-title.md +5 -0
- package/docs/rules/prefer-mock-promise-shorthand.md +6 -1
- package/docs/rules/prefer-snapshot-hint.md +2 -0
- package/docs/rules/prefer-spy-on.md +5 -2
- package/docs/rules/prefer-strict-equal.md +5 -2
- package/docs/rules/prefer-to-be.md +8 -0
- package/docs/rules/prefer-to-contain.md +8 -2
- package/docs/rules/prefer-to-have-length.md +8 -2
- package/docs/rules/prefer-todo.md +5 -2
- package/docs/rules/require-hook.md +2 -0
- package/docs/rules/require-to-throw-message.md +2 -2
- package/docs/rules/require-top-level-describe.md +5 -1
- package/docs/rules/unbound-method.md +7 -2
- package/docs/rules/valid-describe-callback.md +6 -1
- package/docs/rules/valid-expect-in-promise.md +6 -1
- package/docs/rules/valid-expect.md +5 -2
- package/docs/rules/valid-title.md +9 -1
- package/lib/index.js +14 -25
- package/lib/processors/snapshot-processor.js +3 -5
- package/lib/rules/consistent-test-it.js +1 -19
- package/lib/rules/expect-expect.js +1 -18
- package/lib/rules/max-expects.js +0 -16
- package/lib/rules/max-nested-describe.js +0 -13
- package/lib/rules/no-alias-methods.js +1 -10
- package/lib/rules/no-commented-out-tests.js +0 -10
- package/lib/rules/no-conditional-expect.js +2 -23
- package/lib/rules/no-conditional-in-test.js +0 -9
- package/lib/rules/no-deprecated-functions.js +2 -18
- package/lib/rules/no-disabled-tests.js +3 -19
- package/lib/rules/no-done-callback.js +20 -47
- package/lib/rules/no-duplicate-hooks.js +0 -12
- package/lib/rules/no-export.js +0 -12
- package/lib/rules/no-focused-tests.js +1 -17
- package/lib/rules/no-hooks.js +0 -7
- package/lib/rules/no-identical-title.js +0 -19
- package/lib/rules/no-if.js +0 -24
- package/lib/rules/no-interpolation-in-snapshots.js +0 -9
- package/lib/rules/no-jasmine-globals.js +1 -23
- package/lib/rules/no-large-snapshots.js +4 -24
- package/lib/rules/no-mocks-import.js +0 -12
- package/lib/rules/no-restricted-jest-methods.js +56 -0
- package/lib/rules/no-restricted-matchers.js +13 -28
- package/lib/rules/no-standalone-expect.js +7 -33
- package/lib/rules/no-test-prefixes.js +1 -13
- package/lib/rules/no-test-return-statement.js +0 -12
- package/lib/rules/prefer-called-with.js +0 -10
- package/lib/rules/prefer-comparison-matcher.js +8 -33
- package/lib/rules/prefer-each.js +80 -0
- package/lib/rules/prefer-equality-matcher.js +12 -25
- package/lib/rules/prefer-expect-assertions.js +14 -60
- package/lib/rules/prefer-expect-resolves.js +0 -12
- package/lib/rules/prefer-hooks-in-order.js +2 -16
- package/lib/rules/prefer-hooks-on-top.js +0 -9
- package/lib/rules/prefer-lowercase-title.js +0 -23
- package/lib/rules/prefer-mock-promise-shorthand.js +5 -26
- package/lib/rules/prefer-snapshot-hint.js +8 -34
- package/lib/rules/prefer-spy-on.js +0 -17
- package/lib/rules/prefer-strict-equal.js +1 -11
- package/lib/rules/prefer-to-be.js +12 -37
- package/lib/rules/prefer-to-contain.js +11 -21
- package/lib/rules/prefer-to-have-length.js +4 -16
- package/lib/rules/prefer-todo.js +2 -18
- package/lib/rules/require-hook.js +1 -25
- package/lib/rules/require-to-throw-message.js +0 -9
- package/lib/rules/require-top-level-describe.js +1 -18
- package/lib/rules/unbound-method.js +3 -30
- package/lib/rules/utils/accessors.js +6 -18
- package/lib/rules/utils/detectJestVersion.js +2 -7
- package/lib/rules/utils/followTypeAssertionChain.js +0 -4
- package/lib/rules/utils/index.js +0 -10
- package/lib/rules/utils/misc.js +14 -47
- package/lib/rules/utils/parseJestFnCall.js +51 -154
- package/lib/rules/valid-describe-callback.js +0 -17
- package/lib/rules/valid-expect-in-promise.js +28 -95
- package/lib/rules/valid-expect.js +5 -48
- package/lib/rules/valid-title.js +5 -40
- package/package.json +20 -16
- package/docs/rules/no-jest-import.md +0 -20
- package/lib/rules/no-jest-import.js +0 -48
|
@@ -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("@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: {
|
|
15
12
|
docs: {
|
|
16
13
|
category: 'Best Practices',
|
|
17
|
-
description: '
|
|
14
|
+
description: 'Require using `.only` and `.skip` over `f` and `x`',
|
|
18
15
|
recommended: 'error'
|
|
19
16
|
},
|
|
20
17
|
messages: {
|
|
@@ -25,20 +22,16 @@ var _default = (0, _utils2.createRule)({
|
|
|
25
22
|
type: 'suggestion'
|
|
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) !== 'describe' && (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test') {
|
|
35
30
|
return;
|
|
36
31
|
}
|
|
37
|
-
|
|
38
32
|
if (jestFnCall.name[0] !== 'f' && jestFnCall.name[0] !== 'x') {
|
|
39
33
|
return;
|
|
40
34
|
}
|
|
41
|
-
|
|
42
35
|
const preferredNodeName = [jestFnCall.name.slice(1), jestFnCall.name[0] === 'f' ? 'only' : 'skip', ...jestFnCall.members.map(s => (0, _utils2.getAccessorValue)(s))].join('.');
|
|
43
36
|
const funcNode = node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _utils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
|
|
44
37
|
context.report({
|
|
@@ -47,17 +40,12 @@ var _default = (0, _utils2.createRule)({
|
|
|
47
40
|
data: {
|
|
48
41
|
preferredNodeName
|
|
49
42
|
},
|
|
50
|
-
|
|
51
43
|
fix(fixer) {
|
|
52
44
|
return [fixer.replaceText(funcNode, preferredNodeName)];
|
|
53
45
|
}
|
|
54
|
-
|
|
55
46
|
});
|
|
56
47
|
}
|
|
57
|
-
|
|
58
48
|
};
|
|
59
49
|
}
|
|
60
|
-
|
|
61
50
|
});
|
|
62
|
-
|
|
63
51
|
exports.default = _default;
|
|
@@ -4,21 +4,15 @@ 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 getBody = args => {
|
|
13
10
|
const [, secondArg] = args;
|
|
14
|
-
|
|
15
11
|
if (secondArg && (0, _utils2.isFunction)(secondArg) && secondArg.body.type === _utils.AST_NODE_TYPES.BlockStatement) {
|
|
16
12
|
return secondArg.body.body;
|
|
17
13
|
}
|
|
18
|
-
|
|
19
14
|
return [];
|
|
20
15
|
};
|
|
21
|
-
|
|
22
16
|
var _default = (0, _utils2.createRule)({
|
|
23
17
|
name: __filename,
|
|
24
18
|
meta: {
|
|
@@ -34,14 +28,12 @@ var _default = (0, _utils2.createRule)({
|
|
|
34
28
|
type: 'suggestion'
|
|
35
29
|
},
|
|
36
30
|
defaultOptions: [],
|
|
37
|
-
|
|
38
31
|
create(context) {
|
|
39
32
|
return {
|
|
40
33
|
CallExpression(node) {
|
|
41
34
|
if (!(0, _utils2.isTypeOfJestFnCall)(node, context, ['test'])) {
|
|
42
35
|
return;
|
|
43
36
|
}
|
|
44
|
-
|
|
45
37
|
const body = getBody(node.arguments);
|
|
46
38
|
const returnStmt = body.find(t => t.type === _utils.AST_NODE_TYPES.ReturnStatement);
|
|
47
39
|
if (!returnStmt) return;
|
|
@@ -50,7 +42,6 @@ var _default = (0, _utils2.createRule)({
|
|
|
50
42
|
node: returnStmt
|
|
51
43
|
});
|
|
52
44
|
},
|
|
53
|
-
|
|
54
45
|
FunctionDeclaration(node) {
|
|
55
46
|
const declaredVariables = context.getDeclaredVariables(node);
|
|
56
47
|
const testCallExpressions = (0, _utils2.getTestCallExpressionsFromDeclaredVariables)(declaredVariables, context);
|
|
@@ -62,10 +53,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
62
53
|
node: returnStmt
|
|
63
54
|
});
|
|
64
55
|
}
|
|
65
|
-
|
|
66
56
|
};
|
|
67
57
|
}
|
|
68
|
-
|
|
69
58
|
});
|
|
70
|
-
|
|
71
59
|
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,25 +20,20 @@ var _default = (0, _utils.createRule)({
|
|
|
22
20
|
schema: []
|
|
23
21
|
},
|
|
24
22
|
defaultOptions: [],
|
|
25
|
-
|
|
26
23
|
create(context) {
|
|
27
24
|
return {
|
|
28
25
|
CallExpression(node) {
|
|
29
26
|
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
|
|
30
|
-
|
|
31
27
|
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
|
|
32
28
|
return;
|
|
33
29
|
}
|
|
34
|
-
|
|
35
30
|
if (jestFnCall.modifiers.some(nod => (0, _utils.getAccessorValue)(nod) === 'not')) {
|
|
36
31
|
return;
|
|
37
32
|
}
|
|
38
|
-
|
|
39
33
|
const {
|
|
40
34
|
matcher
|
|
41
35
|
} = jestFnCall;
|
|
42
36
|
const matcherName = (0, _utils.getAccessorValue)(matcher);
|
|
43
|
-
|
|
44
37
|
if (['toBeCalled', 'toHaveBeenCalled'].includes(matcherName)) {
|
|
45
38
|
context.report({
|
|
46
39
|
data: {
|
|
@@ -51,10 +44,7 @@ var _default = (0, _utils.createRule)({
|
|
|
51
44
|
});
|
|
52
45
|
}
|
|
53
46
|
}
|
|
54
|
-
|
|
55
47
|
};
|
|
56
48
|
}
|
|
57
|
-
|
|
58
49
|
});
|
|
59
|
-
|
|
60
50
|
exports.default = _default;
|
|
@@ -4,57 +4,41 @@ 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 isString = node => {
|
|
13
10
|
return (0, _utils2.isStringNode)(node) || node.type === _utils.AST_NODE_TYPES.TemplateLiteral;
|
|
14
11
|
};
|
|
15
|
-
|
|
16
12
|
const isComparingToString = expression => {
|
|
17
13
|
return isString(expression.left) || isString(expression.right);
|
|
18
14
|
};
|
|
19
|
-
|
|
20
15
|
const invertOperator = operator => {
|
|
21
16
|
switch (operator) {
|
|
22
17
|
case '>':
|
|
23
18
|
return '<=';
|
|
24
|
-
|
|
25
19
|
case '<':
|
|
26
20
|
return '>=';
|
|
27
|
-
|
|
28
21
|
case '>=':
|
|
29
22
|
return '<';
|
|
30
|
-
|
|
31
23
|
case '<=':
|
|
32
24
|
return '>';
|
|
33
25
|
}
|
|
34
|
-
|
|
35
26
|
return null;
|
|
36
27
|
};
|
|
37
|
-
|
|
38
28
|
const determineMatcher = (operator, negated) => {
|
|
39
29
|
const op = negated ? invertOperator(operator) : operator;
|
|
40
|
-
|
|
41
30
|
switch (op) {
|
|
42
31
|
case '>':
|
|
43
32
|
return 'toBeGreaterThan';
|
|
44
|
-
|
|
45
33
|
case '<':
|
|
46
34
|
return 'toBeLessThan';
|
|
47
|
-
|
|
48
35
|
case '>=':
|
|
49
36
|
return 'toBeGreaterThanOrEqual';
|
|
50
|
-
|
|
51
37
|
case '<=':
|
|
52
38
|
return 'toBeLessThanOrEqual';
|
|
53
39
|
}
|
|
54
|
-
|
|
55
40
|
return null;
|
|
56
41
|
};
|
|
57
|
-
|
|
58
42
|
var _default = (0, _utils2.createRule)({
|
|
59
43
|
name: __filename,
|
|
60
44
|
meta: {
|
|
@@ -71,24 +55,19 @@ var _default = (0, _utils2.createRule)({
|
|
|
71
55
|
schema: []
|
|
72
56
|
},
|
|
73
57
|
defaultOptions: [],
|
|
74
|
-
|
|
75
58
|
create(context) {
|
|
76
59
|
return {
|
|
77
60
|
CallExpression(node) {
|
|
78
61
|
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
|
|
79
|
-
|
|
80
62
|
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect' || jestFnCall.args.length === 0) {
|
|
81
63
|
return;
|
|
82
64
|
}
|
|
83
|
-
|
|
84
65
|
const {
|
|
85
66
|
parent: expect
|
|
86
67
|
} = jestFnCall.head.node;
|
|
87
|
-
|
|
88
68
|
if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
|
|
89
69
|
return;
|
|
90
70
|
}
|
|
91
|
-
|
|
92
71
|
const {
|
|
93
72
|
arguments: [comparison],
|
|
94
73
|
range: [, expectCallEnd]
|
|
@@ -97,30 +76,29 @@ var _default = (0, _utils2.createRule)({
|
|
|
97
76
|
matcher
|
|
98
77
|
} = jestFnCall;
|
|
99
78
|
const matcherArg = (0, _utils2.getFirstMatcherArg)(jestFnCall);
|
|
100
|
-
|
|
101
79
|
if ((comparison === null || comparison === void 0 ? void 0 : comparison.type) !== _utils.AST_NODE_TYPES.BinaryExpression || isComparingToString(comparison) || !_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || !(0, _utils2.isBooleanLiteral)(matcherArg)) {
|
|
102
80
|
return;
|
|
103
81
|
}
|
|
104
|
-
|
|
105
82
|
const [modifier] = jestFnCall.modifiers;
|
|
106
83
|
const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
|
|
107
84
|
const preferredMatcher = determineMatcher(comparison.operator, matcherArg.value === hasNot);
|
|
108
|
-
|
|
109
85
|
if (!preferredMatcher) {
|
|
110
86
|
return;
|
|
111
87
|
}
|
|
112
|
-
|
|
113
88
|
context.report({
|
|
114
89
|
fix(fixer) {
|
|
115
|
-
const sourceCode = context.getSourceCode();
|
|
90
|
+
const sourceCode = context.getSourceCode();
|
|
116
91
|
|
|
92
|
+
// preserve the existing modifier if it's not a negation
|
|
117
93
|
const modifierText = modifier && (0, _utils2.getAccessorValue)(modifier) !== 'not' ? `.${(0, _utils2.getAccessorValue)(modifier)}` : '';
|
|
118
|
-
return [
|
|
119
|
-
|
|
120
|
-
fixer.
|
|
94
|
+
return [
|
|
95
|
+
// replace the comparison argument with the left-hand side of the comparison
|
|
96
|
+
fixer.replaceText(comparison, sourceCode.getText(comparison.left)),
|
|
97
|
+
// replace the current matcher & modifier with the preferred matcher
|
|
98
|
+
fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], `${modifierText}.${preferredMatcher}`),
|
|
99
|
+
// replace the matcher argument with the right-hand side of the comparison
|
|
121
100
|
fixer.replaceText(matcherArg, sourceCode.getText(comparison.right))];
|
|
122
101
|
},
|
|
123
|
-
|
|
124
102
|
messageId: 'useToBeComparison',
|
|
125
103
|
data: {
|
|
126
104
|
preferredMatcher
|
|
@@ -128,10 +106,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
128
106
|
node: matcher
|
|
129
107
|
});
|
|
130
108
|
}
|
|
131
|
-
|
|
132
109
|
};
|
|
133
110
|
}
|
|
134
|
-
|
|
135
111
|
});
|
|
136
|
-
|
|
137
112
|
exports.default = _default;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _utils = require("./utils");
|
|
8
|
+
var _default = (0, _utils.createRule)({
|
|
9
|
+
name: __filename,
|
|
10
|
+
meta: {
|
|
11
|
+
docs: {
|
|
12
|
+
category: 'Best Practices',
|
|
13
|
+
description: 'Prefer using `.each` rather than manual loops',
|
|
14
|
+
recommended: false
|
|
15
|
+
},
|
|
16
|
+
messages: {
|
|
17
|
+
preferEach: 'prefer using `{{ fn }}.each` rather than a manual loop'
|
|
18
|
+
},
|
|
19
|
+
type: 'suggestion',
|
|
20
|
+
schema: []
|
|
21
|
+
},
|
|
22
|
+
defaultOptions: [],
|
|
23
|
+
create(context) {
|
|
24
|
+
const jestFnCalls = [];
|
|
25
|
+
let inTestCaseCall = false;
|
|
26
|
+
const recommendFn = () => {
|
|
27
|
+
if (jestFnCalls.length === 1 && jestFnCalls[0] === 'test') {
|
|
28
|
+
return 'it';
|
|
29
|
+
}
|
|
30
|
+
return 'describe';
|
|
31
|
+
};
|
|
32
|
+
const enterForLoop = () => {
|
|
33
|
+
if (jestFnCalls.length === 0 || inTestCaseCall) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
jestFnCalls.length = 0;
|
|
37
|
+
};
|
|
38
|
+
const exitForLoop = node => {
|
|
39
|
+
if (jestFnCalls.length === 0 || inTestCaseCall) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
context.report({
|
|
43
|
+
node,
|
|
44
|
+
messageId: 'preferEach',
|
|
45
|
+
data: {
|
|
46
|
+
fn: recommendFn()
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
jestFnCalls.length = 0;
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
ForStatement: enterForLoop,
|
|
53
|
+
'ForStatement:exit': exitForLoop,
|
|
54
|
+
ForInStatement: enterForLoop,
|
|
55
|
+
'ForInStatement:exit': exitForLoop,
|
|
56
|
+
ForOfStatement: enterForLoop,
|
|
57
|
+
'ForOfStatement:exit': exitForLoop,
|
|
58
|
+
CallExpression(node) {
|
|
59
|
+
const {
|
|
60
|
+
type: jestFnCallType
|
|
61
|
+
} = (0, _utils.parseJestFnCall)(node, context) ?? {};
|
|
62
|
+
if (jestFnCallType === 'hook' || jestFnCallType === 'describe' || jestFnCallType === 'test') {
|
|
63
|
+
jestFnCalls.push(jestFnCallType);
|
|
64
|
+
}
|
|
65
|
+
if (jestFnCallType === 'test') {
|
|
66
|
+
inTestCaseCall = true;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
'CallExpression:exit'(node) {
|
|
70
|
+
const {
|
|
71
|
+
type: jestFnCallType
|
|
72
|
+
} = (0, _utils.parseJestFnCall)(node, context) ?? {};
|
|
73
|
+
if (jestFnCallType === 'test') {
|
|
74
|
+
inTestCaseCall = false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
exports.default = _default;
|
|
@@ -4,19 +4,15 @@ 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: {
|
|
15
12
|
docs: {
|
|
16
13
|
category: 'Best Practices',
|
|
17
14
|
description: 'Suggest using the built-in equality matchers',
|
|
18
|
-
recommended: false
|
|
19
|
-
suggestion: true
|
|
15
|
+
recommended: false
|
|
20
16
|
},
|
|
21
17
|
messages: {
|
|
22
18
|
useEqualityMatcher: 'Prefer using one of the equality matchers instead',
|
|
@@ -27,24 +23,19 @@ var _default = (0, _utils2.createRule)({
|
|
|
27
23
|
schema: []
|
|
28
24
|
},
|
|
29
25
|
defaultOptions: [],
|
|
30
|
-
|
|
31
26
|
create(context) {
|
|
32
27
|
return {
|
|
33
28
|
CallExpression(node) {
|
|
34
29
|
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
|
|
35
|
-
|
|
36
30
|
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect' || jestFnCall.args.length === 0) {
|
|
37
31
|
return;
|
|
38
32
|
}
|
|
39
|
-
|
|
40
33
|
const {
|
|
41
34
|
parent: expect
|
|
42
35
|
} = jestFnCall.head.node;
|
|
43
|
-
|
|
44
36
|
if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
|
|
45
37
|
return;
|
|
46
38
|
}
|
|
47
|
-
|
|
48
39
|
const {
|
|
49
40
|
arguments: [comparison],
|
|
50
41
|
range: [, expectCallEnd]
|
|
@@ -53,33 +44,32 @@ var _default = (0, _utils2.createRule)({
|
|
|
53
44
|
matcher
|
|
54
45
|
} = jestFnCall;
|
|
55
46
|
const matcherArg = (0, _utils2.getFirstMatcherArg)(jestFnCall);
|
|
56
|
-
|
|
57
47
|
if ((comparison === null || comparison === void 0 ? void 0 : comparison.type) !== _utils.AST_NODE_TYPES.BinaryExpression || comparison.operator !== '===' && comparison.operator !== '!==' || !_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || !(0, _utils2.isBooleanLiteral)(matcherArg)) {
|
|
58
48
|
return;
|
|
59
49
|
}
|
|
60
|
-
|
|
61
50
|
const matcherValue = matcherArg.value;
|
|
62
51
|
const [modifier] = jestFnCall.modifiers;
|
|
63
|
-
const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
|
|
64
|
-
// value is itself negated by the "not" modifier
|
|
52
|
+
const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
|
|
65
53
|
|
|
54
|
+
// we need to negate the expectation if the current expected
|
|
55
|
+
// value is itself negated by the "not" modifier
|
|
66
56
|
const addNotModifier = (comparison.operator === '!==' ? !matcherValue : matcherValue) === hasNot;
|
|
67
|
-
|
|
68
57
|
const buildFixer = equalityMatcher => fixer => {
|
|
69
|
-
const sourceCode = context.getSourceCode();
|
|
58
|
+
const sourceCode = context.getSourceCode();
|
|
70
59
|
|
|
60
|
+
// preserve the existing modifier if it's not a negation
|
|
71
61
|
let modifierText = modifier && (0, _utils2.getAccessorValue)(modifier) !== 'not' ? `.${(0, _utils2.getAccessorValue)(modifier)}` : '';
|
|
72
|
-
|
|
73
62
|
if (addNotModifier) {
|
|
74
63
|
modifierText += `.${_utils2.ModifierName.not}`;
|
|
75
64
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
fixer.replaceText(comparison, sourceCode.getText(comparison.left)),
|
|
79
|
-
|
|
65
|
+
return [
|
|
66
|
+
// replace the comparison argument with the left-hand side of the comparison
|
|
67
|
+
fixer.replaceText(comparison, sourceCode.getText(comparison.left)),
|
|
68
|
+
// replace the current matcher & modifier with the preferred matcher
|
|
69
|
+
fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], `${modifierText}.${equalityMatcher}`),
|
|
70
|
+
// replace the matcher argument with the right-hand side of the comparison
|
|
80
71
|
fixer.replaceText(matcherArg, sourceCode.getText(comparison.right))];
|
|
81
72
|
};
|
|
82
|
-
|
|
83
73
|
context.report({
|
|
84
74
|
messageId: 'useEqualityMatcher',
|
|
85
75
|
suggest: ['toBe', 'toEqual', 'toStrictEqual'].map(equalityMatcher => ({
|
|
@@ -92,10 +82,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
92
82
|
node: matcher
|
|
93
83
|
});
|
|
94
84
|
}
|
|
95
|
-
|
|
96
85
|
};
|
|
97
86
|
}
|
|
98
|
-
|
|
99
87
|
});
|
|
100
|
-
|
|
101
88
|
exports.default = _default;
|