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,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
|
-
}
|
|
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
|
-
}
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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;
|
|
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();
|
|
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 [
|
|
78
|
-
|
|
79
|
-
fixer.
|
|
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 [
|
|
58
|
-
|
|
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;
|
package/lib/rules/prefer-todo.js
CHANGED
|
@@ -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
|
-
}
|
|
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;
|