eslint-plugin-jest 26.1.1 → 26.5.3
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 +50 -2
- package/docs/rules/no-conditional-expect.md +1 -1
- package/docs/rules/no-deprecated-functions.md +1 -2
- package/docs/rules/no-identical-title.md +1 -1
- package/docs/rules/no-jasmine-globals.md +2 -2
- package/docs/rules/no-jest-import.md +1 -1
- package/docs/rules/no-large-snapshots.md +2 -2
- package/docs/rules/no-standalone-expect.md +1 -1
- package/docs/rules/prefer-comparison-matcher.md +1 -1
- package/docs/rules/prefer-equality-matcher.md +1 -1
- package/docs/rules/prefer-expect-assertions.md +1 -1
- package/docs/rules/prefer-hooks-in-order.md +133 -0
- package/docs/rules/prefer-hooks-on-top.md +1 -1
- package/docs/rules/prefer-lowercase-title.md +2 -2
- package/docs/rules/valid-expect.md +2 -2
- package/lib/rules/consistent-test-it.js +9 -8
- package/lib/rules/expect-expect.js +4 -4
- package/lib/rules/max-nested-describe.js +2 -2
- package/lib/rules/no-alias-methods.js +1 -1
- package/lib/rules/no-conditional-expect.js +3 -3
- package/lib/rules/no-conditional-in-test.js +2 -2
- package/lib/rules/no-deprecated-functions.js +1 -3
- package/lib/rules/no-disabled-tests.js +36 -61
- package/lib/rules/no-done-callback.js +6 -4
- package/lib/rules/no-duplicate-hooks.js +23 -23
- package/lib/rules/no-export.js +1 -1
- package/lib/rules/no-focused-tests.js +40 -43
- package/lib/rules/no-hooks.js +4 -2
- package/lib/rules/no-identical-title.js +10 -7
- package/lib/rules/no-if.js +6 -4
- package/lib/rules/no-restricted-matchers.js +39 -43
- package/lib/rules/no-standalone-expect.js +5 -5
- package/lib/rules/no-test-prefixes.js +12 -20
- package/lib/rules/no-test-return-statement.js +5 -2
- package/lib/rules/prefer-called-with.js +14 -13
- package/lib/rules/prefer-comparison-matcher.js +9 -4
- package/lib/rules/prefer-equality-matcher.js +15 -5
- package/lib/rules/prefer-expect-assertions.js +4 -2
- package/lib/rules/prefer-hooks-in-order.js +84 -0
- package/lib/rules/prefer-hooks-on-top.js +2 -2
- package/lib/rules/prefer-lowercase-title.js +12 -22
- package/lib/rules/prefer-snapshot-hint.js +34 -3
- package/lib/rules/prefer-strict-equal.js +1 -1
- package/lib/rules/prefer-to-be.js +1 -1
- package/lib/rules/prefer-todo.js +22 -7
- package/lib/rules/require-hook.js +7 -7
- package/lib/rules/require-top-level-describe.js +10 -4
- package/lib/rules/utils/accessors.js +135 -0
- package/lib/rules/{detectJestVersion.js → utils/detectJestVersion.js} +0 -0
- package/lib/rules/utils/followTypeAssertionChain.js +14 -0
- package/lib/rules/utils/index.js +83 -0
- package/lib/rules/utils/misc.js +120 -0
- package/lib/rules/utils/parseExpectCall.js +145 -0
- package/lib/rules/utils/parseJestFnCall.js +323 -0
- package/lib/rules/valid-describe-callback.js +4 -2
- package/lib/rules/valid-expect-in-promise.js +13 -15
- package/lib/rules/valid-title.js +8 -6
- package/package.json +9 -12
- package/lib/rules/utils.js +0 -513
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _utils = require("./utils");
|
|
9
|
+
|
|
10
|
+
const HooksOrder = ['beforeAll', 'beforeEach', 'afterEach', 'afterAll'];
|
|
11
|
+
|
|
12
|
+
var _default = (0, _utils.createRule)({
|
|
13
|
+
name: __filename,
|
|
14
|
+
meta: {
|
|
15
|
+
docs: {
|
|
16
|
+
category: 'Best Practices',
|
|
17
|
+
description: 'Prefer having hooks in a consistent order',
|
|
18
|
+
recommended: false
|
|
19
|
+
},
|
|
20
|
+
messages: {
|
|
21
|
+
reorderHooks: `\`{{ currentHook }}\` hooks should be before any \`{{ previousHook }}\` hooks`
|
|
22
|
+
},
|
|
23
|
+
schema: [],
|
|
24
|
+
type: 'suggestion'
|
|
25
|
+
},
|
|
26
|
+
defaultOptions: [],
|
|
27
|
+
|
|
28
|
+
create(context) {
|
|
29
|
+
let previousHookIndex = -1;
|
|
30
|
+
let inHook = false;
|
|
31
|
+
return {
|
|
32
|
+
CallExpression(node) {
|
|
33
|
+
if (inHook) {
|
|
34
|
+
// Ignore everything that is passed into a hook
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
|
|
39
|
+
|
|
40
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'hook') {
|
|
41
|
+
// Reset the previousHookIndex when encountering something different from a hook
|
|
42
|
+
previousHookIndex = -1;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
inHook = true;
|
|
47
|
+
const currentHook = jestFnCall.name;
|
|
48
|
+
const currentHookIndex = HooksOrder.indexOf(currentHook);
|
|
49
|
+
|
|
50
|
+
if (currentHookIndex < previousHookIndex) {
|
|
51
|
+
context.report({
|
|
52
|
+
messageId: 'reorderHooks',
|
|
53
|
+
node,
|
|
54
|
+
data: {
|
|
55
|
+
previousHook: HooksOrder[previousHookIndex],
|
|
56
|
+
currentHook
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
previousHookIndex = currentHookIndex;
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
'CallExpression:exit'(node) {
|
|
66
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context, ['hook'])) {
|
|
67
|
+
inHook = false;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (inHook) {
|
|
72
|
+
return;
|
|
73
|
+
} // Reset the previousHookIndex when encountering something different from a hook
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
previousHookIndex = -1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
exports.default = _default;
|
|
@@ -27,11 +27,11 @@ var _default = (0, _utils.createRule)({
|
|
|
27
27
|
const hooksContext = [false];
|
|
28
28
|
return {
|
|
29
29
|
CallExpression(node) {
|
|
30
|
-
if (
|
|
30
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context, ['test'])) {
|
|
31
31
|
hooksContext[hooksContext.length - 1] = true;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
if (hooksContext[hooksContext.length - 1] && (0, _utils.
|
|
34
|
+
if (hooksContext[hooksContext.length - 1] && (0, _utils.isTypeOfJestFnCall)(node, context, ['hook'])) {
|
|
35
35
|
context.report({
|
|
36
36
|
messageId: 'noHookOnTop',
|
|
37
37
|
node
|
|
@@ -9,18 +9,6 @@ var _utils = require("./utils");
|
|
|
9
9
|
|
|
10
10
|
const hasStringAsFirstArgument = node => node.arguments[0] && (0, _utils.isStringNode)(node.arguments[0]);
|
|
11
11
|
|
|
12
|
-
const findNodeNameAndArgument = node => {
|
|
13
|
-
if (!((0, _utils.isTestCaseCall)(node) || (0, _utils.isDescribeCall)(node))) {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (!hasStringAsFirstArgument(node)) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return [(0, _utils.getNodeName)(node).split('.')[0], node.arguments[0]];
|
|
22
|
-
};
|
|
23
|
-
|
|
24
12
|
const populateIgnores = ignore => {
|
|
25
13
|
const ignores = [];
|
|
26
14
|
|
|
@@ -92,21 +80,23 @@ var _default = (0, _utils.createRule)({
|
|
|
92
80
|
let numberOfDescribeBlocks = 0;
|
|
93
81
|
return {
|
|
94
82
|
CallExpression(node) {
|
|
95
|
-
|
|
83
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
|
|
84
|
+
|
|
85
|
+
if (!jestFnCall || !hasStringAsFirstArgument(node)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (jestFnCall.type === 'describe') {
|
|
96
90
|
numberOfDescribeBlocks++;
|
|
97
91
|
|
|
98
92
|
if (ignoreTopLevelDescribe && numberOfDescribeBlocks === 1) {
|
|
99
93
|
return;
|
|
100
94
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const results = findNodeNameAndArgument(node);
|
|
104
|
-
|
|
105
|
-
if (!results) {
|
|
95
|
+
} else if (jestFnCall.type !== 'test') {
|
|
106
96
|
return;
|
|
107
97
|
}
|
|
108
98
|
|
|
109
|
-
const [
|
|
99
|
+
const [firstArg] = node.arguments;
|
|
110
100
|
const description = (0, _utils.getStringValue)(firstArg);
|
|
111
101
|
|
|
112
102
|
if (allowedPrefixes.some(name => description.startsWith(name))) {
|
|
@@ -115,7 +105,7 @@ var _default = (0, _utils.createRule)({
|
|
|
115
105
|
|
|
116
106
|
const firstCharacter = description.charAt(0);
|
|
117
107
|
|
|
118
|
-
if (!firstCharacter || firstCharacter === firstCharacter.toLowerCase() || ignores.includes(name)) {
|
|
108
|
+
if (!firstCharacter || firstCharacter === firstCharacter.toLowerCase() || ignores.includes(jestFnCall.name)) {
|
|
119
109
|
return;
|
|
120
110
|
}
|
|
121
111
|
|
|
@@ -123,7 +113,7 @@ var _default = (0, _utils.createRule)({
|
|
|
123
113
|
messageId: 'unexpectedLowercase',
|
|
124
114
|
node: node.arguments[0],
|
|
125
115
|
data: {
|
|
126
|
-
method: name
|
|
116
|
+
method: jestFnCall.name
|
|
127
117
|
},
|
|
128
118
|
|
|
129
119
|
fix(fixer) {
|
|
@@ -137,7 +127,7 @@ var _default = (0, _utils.createRule)({
|
|
|
137
127
|
},
|
|
138
128
|
|
|
139
129
|
'CallExpression:exit'(node) {
|
|
140
|
-
if ((0, _utils.
|
|
130
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe'])) {
|
|
141
131
|
numberOfDescribeBlocks--;
|
|
142
132
|
}
|
|
143
133
|
}
|
|
@@ -14,10 +14,26 @@ const isSnapshotMatcher = matcher => {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
const isSnapshotMatcherWithoutHint = matcher => {
|
|
17
|
-
|
|
17
|
+
if (!matcher.arguments || matcher.arguments.length === 0) {
|
|
18
|
+
return true;
|
|
19
|
+
} // this matcher only supports one argument which is the hint
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
|
|
22
|
+
if (matcher.name !== 'toMatchSnapshot') {
|
|
23
|
+
return matcher.arguments.length !== 1;
|
|
24
|
+
} // if we're being passed two arguments,
|
|
25
|
+
// the second one should be the hint
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if (matcher.arguments.length === 2) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const [arg] = matcher.arguments; // the first argument to `toMatchSnapshot` can be _either_ a snapshot hint or
|
|
33
|
+
// an object with asymmetric matchers, so we can't just assume that the first
|
|
34
|
+
// argument is a hint when it's by itself.
|
|
35
|
+
|
|
36
|
+
return !(0, _utils.isStringNode)(arg);
|
|
21
37
|
};
|
|
22
38
|
|
|
23
39
|
const messages = {
|
|
@@ -43,6 +59,7 @@ var _default = (0, _utils.createRule)({
|
|
|
43
59
|
|
|
44
60
|
create(context, [mode]) {
|
|
45
61
|
const snapshotMatchers = [];
|
|
62
|
+
const depths = [];
|
|
46
63
|
let expressionDepth = 0;
|
|
47
64
|
|
|
48
65
|
const reportSnapshotMatchersWithoutHints = () => {
|
|
@@ -88,7 +105,21 @@ var _default = (0, _utils.createRule)({
|
|
|
88
105
|
ArrowFunctionExpression: enterExpression,
|
|
89
106
|
'ArrowFunctionExpression:exit': exitExpression,
|
|
90
107
|
|
|
108
|
+
'CallExpression:exit'(node) {
|
|
109
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe', 'test'])) {
|
|
110
|
+
var _depths$pop;
|
|
111
|
+
|
|
112
|
+
/* istanbul ignore next */
|
|
113
|
+
expressionDepth = (_depths$pop = depths.pop()) !== null && _depths$pop !== void 0 ? _depths$pop : 0;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
|
|
91
117
|
CallExpression(node) {
|
|
118
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe', 'test'])) {
|
|
119
|
+
depths.push(expressionDepth);
|
|
120
|
+
expressionDepth = 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
92
123
|
if (!(0, _utils.isExpectCall)(node)) {
|
|
93
124
|
return;
|
|
94
125
|
}
|
|
@@ -43,7 +43,7 @@ var _default = (0, _utils.createRule)({
|
|
|
43
43
|
node: matcher.node.property,
|
|
44
44
|
suggest: [{
|
|
45
45
|
messageId: 'suggestReplaceWithStrictEqual',
|
|
46
|
-
fix: fixer => [
|
|
46
|
+
fix: fixer => [(0, _utils.replaceAccessorFixer)(fixer, matcher.node.property, _utils.EqualityMatcher.toStrictEqual)]
|
|
47
47
|
}]
|
|
48
48
|
});
|
|
49
49
|
}
|
|
@@ -44,7 +44,7 @@ const reportPreferToBe = (context, whatToBe, matcher, modifier) => {
|
|
|
44
44
|
fix(fixer) {
|
|
45
45
|
var _matcher$arguments;
|
|
46
46
|
|
|
47
|
-
const fixes = [
|
|
47
|
+
const fixes = [(0, _utils2.replaceAccessorFixer)(fixer, matcher.node.property, `toBe${whatToBe}`)];
|
|
48
48
|
|
|
49
49
|
if ((_matcher$arguments = matcher.arguments) !== null && _matcher$arguments !== void 0 && _matcher$arguments.length && whatToBe !== '') {
|
|
50
50
|
fixes.push(fixer.remove(matcher.arguments[0]));
|
package/lib/rules/prefer-todo.js
CHANGED
|
@@ -17,12 +17,26 @@ function isEmptyFunction(node) {
|
|
|
17
17
|
return node.body.type === _utils.AST_NODE_TYPES.BlockStatement && !node.body.body.length;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
function createTodoFixer(
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
function createTodoFixer(jestFnCall, fixer) {
|
|
21
|
+
if (jestFnCall.members.length) {
|
|
22
|
+
return (0, _utils2.replaceAccessorFixer)(fixer, jestFnCall.members[0], 'todo');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return fixer.replaceText(jestFnCall.head.node, `${jestFnCall.head.local}.todo`);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
const isTargetedTestCase =
|
|
28
|
+
const isTargetedTestCase = jestFnCall => {
|
|
29
|
+
if (jestFnCall.members.some(s => (0, _utils2.getAccessorValue)(s) !== 'skip')) {
|
|
30
|
+
return false;
|
|
31
|
+
} // todo: we should support this too (needs custom fixer)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if (jestFnCall.name.startsWith('x')) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return !jestFnCall.name.startsWith('f');
|
|
39
|
+
};
|
|
26
40
|
|
|
27
41
|
var _default = (0, _utils2.createRule)({
|
|
28
42
|
name: __filename,
|
|
@@ -46,8 +60,9 @@ var _default = (0, _utils2.createRule)({
|
|
|
46
60
|
return {
|
|
47
61
|
CallExpression(node) {
|
|
48
62
|
const [title, callback] = node.arguments;
|
|
63
|
+
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
|
|
49
64
|
|
|
50
|
-
if (!title || !isTargetedTestCase(
|
|
65
|
+
if (!title || (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test' || !isTargetedTestCase(jestFnCall) || !(0, _utils2.isStringNode)(title)) {
|
|
51
66
|
return;
|
|
52
67
|
}
|
|
53
68
|
|
|
@@ -55,7 +70,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
55
70
|
context.report({
|
|
56
71
|
messageId: 'emptyTest',
|
|
57
72
|
node,
|
|
58
|
-
fix: fixer => [fixer.removeRange([title.range[1], callback.range[1]]), createTodoFixer(
|
|
73
|
+
fix: fixer => [fixer.removeRange([title.range[1], callback.range[1]]), createTodoFixer(jestFnCall, fixer)]
|
|
59
74
|
});
|
|
60
75
|
}
|
|
61
76
|
|
|
@@ -63,7 +78,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
63
78
|
context.report({
|
|
64
79
|
messageId: 'unimplementedTest',
|
|
65
80
|
node,
|
|
66
|
-
fix: fixer =>
|
|
81
|
+
fix: fixer => createTodoFixer(jestFnCall, fixer)
|
|
67
82
|
});
|
|
68
83
|
}
|
|
69
84
|
}
|
|
@@ -9,10 +9,10 @@ var _utils = require("@typescript-eslint/utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils2 = require("./utils");
|
|
11
11
|
|
|
12
|
-
const isJestFnCall = node => {
|
|
12
|
+
const isJestFnCall = (node, context) => {
|
|
13
13
|
var _getNodeName;
|
|
14
14
|
|
|
15
|
-
if ((0, _utils2.
|
|
15
|
+
if ((0, _utils2.parseJestFnCall)(node, context)) {
|
|
16
16
|
return true;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -23,13 +23,13 @@ const isNullOrUndefined = node => {
|
|
|
23
23
|
return node.type === _utils.AST_NODE_TYPES.Literal && node.value === null || (0, _utils2.isIdentifier)(node, 'undefined');
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
const shouldBeInHook = (node, allowedFunctionCalls = []) => {
|
|
26
|
+
const shouldBeInHook = (node, context, allowedFunctionCalls = []) => {
|
|
27
27
|
switch (node.type) {
|
|
28
28
|
case _utils.AST_NODE_TYPES.ExpressionStatement:
|
|
29
|
-
return shouldBeInHook(node.expression, allowedFunctionCalls);
|
|
29
|
+
return shouldBeInHook(node.expression, context, allowedFunctionCalls);
|
|
30
30
|
|
|
31
31
|
case _utils.AST_NODE_TYPES.CallExpression:
|
|
32
|
-
return !(isJestFnCall(node) || allowedFunctionCalls.includes((0, _utils2.getNodeName)(node)));
|
|
32
|
+
return !(isJestFnCall(node, context) || allowedFunctionCalls.includes((0, _utils2.getNodeName)(node)));
|
|
33
33
|
|
|
34
34
|
case _utils.AST_NODE_TYPES.VariableDeclaration:
|
|
35
35
|
{
|
|
@@ -85,7 +85,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
85
85
|
|
|
86
86
|
const checkBlockBody = body => {
|
|
87
87
|
for (const statement of body) {
|
|
88
|
-
if (shouldBeInHook(statement, allowedFunctionCalls)) {
|
|
88
|
+
if (shouldBeInHook(statement, context, allowedFunctionCalls)) {
|
|
89
89
|
context.report({
|
|
90
90
|
node: statement,
|
|
91
91
|
messageId: 'useHook'
|
|
@@ -100,7 +100,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
100
100
|
},
|
|
101
101
|
|
|
102
102
|
CallExpression(node) {
|
|
103
|
-
if (!(0, _utils2.
|
|
103
|
+
if (!(0, _utils2.isTypeOfJestFnCall)(node, context, ['describe']) || node.arguments.length < 2) {
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -46,7 +46,13 @@ var _default = (0, _utils.createRule)({
|
|
|
46
46
|
let numberOfDescribeBlocks = 0;
|
|
47
47
|
return {
|
|
48
48
|
CallExpression(node) {
|
|
49
|
-
|
|
49
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
|
|
50
|
+
|
|
51
|
+
if (!jestFnCall) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (jestFnCall.type === 'describe') {
|
|
50
56
|
numberOfDescribeBlocks++;
|
|
51
57
|
|
|
52
58
|
if (numberOfDescribeBlocks === 1) {
|
|
@@ -68,7 +74,7 @@ var _default = (0, _utils.createRule)({
|
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
if (numberOfDescribeBlocks === 0) {
|
|
71
|
-
if (
|
|
77
|
+
if (jestFnCall.type === 'test') {
|
|
72
78
|
context.report({
|
|
73
79
|
node,
|
|
74
80
|
messageId: 'unexpectedTestCase'
|
|
@@ -76,7 +82,7 @@ var _default = (0, _utils.createRule)({
|
|
|
76
82
|
return;
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
if (
|
|
85
|
+
if (jestFnCall.type === 'hook') {
|
|
80
86
|
context.report({
|
|
81
87
|
node,
|
|
82
88
|
messageId: 'unexpectedHook'
|
|
@@ -87,7 +93,7 @@ var _default = (0, _utils.createRule)({
|
|
|
87
93
|
},
|
|
88
94
|
|
|
89
95
|
'CallExpression:exit'(node) {
|
|
90
|
-
if ((0, _utils.
|
|
96
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe'])) {
|
|
91
97
|
numberOfDescribeBlocks--;
|
|
92
98
|
}
|
|
93
99
|
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isSupportedAccessor = exports.isStringNode = exports.isIdentifier = exports.getStringValue = exports.getAccessorValue = void 0;
|
|
7
|
+
|
|
8
|
+
var _utils = require("@typescript-eslint/utils");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Checks if the given `node` is a `StringLiteral`.
|
|
12
|
+
*
|
|
13
|
+
* If a `value` is provided & the `node` is a `StringLiteral`,
|
|
14
|
+
* the `value` will be compared to that of the `StringLiteral`.
|
|
15
|
+
*
|
|
16
|
+
* @param {Node} node
|
|
17
|
+
* @param {V} [value]
|
|
18
|
+
*
|
|
19
|
+
* @return {node is StringLiteral<V>}
|
|
20
|
+
*
|
|
21
|
+
* @template V
|
|
22
|
+
*/
|
|
23
|
+
const isStringLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.Literal && typeof node.value === 'string' && (value === undefined || node.value === value);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Checks if the given `node` is a `TemplateLiteral`.
|
|
27
|
+
*
|
|
28
|
+
* Complex `TemplateLiteral`s are not considered specific, and so will return `false`.
|
|
29
|
+
*
|
|
30
|
+
* If a `value` is provided & the `node` is a `TemplateLiteral`,
|
|
31
|
+
* the `value` will be compared to that of the `TemplateLiteral`.
|
|
32
|
+
*
|
|
33
|
+
* @param {Node} node
|
|
34
|
+
* @param {V} [value]
|
|
35
|
+
*
|
|
36
|
+
* @return {node is TemplateLiteral<V>}
|
|
37
|
+
*
|
|
38
|
+
* @template V
|
|
39
|
+
*/
|
|
40
|
+
const isTemplateLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.TemplateLiteral && node.quasis.length === 1 && ( // bail out if not simple
|
|
41
|
+
value === undefined || node.quasis[0].value.raw === value);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Checks if the given `node` is a {@link StringNode}.
|
|
45
|
+
*
|
|
46
|
+
* @param {Node} node
|
|
47
|
+
* @param {V} [specifics]
|
|
48
|
+
*
|
|
49
|
+
* @return {node is StringNode}
|
|
50
|
+
*
|
|
51
|
+
* @template V
|
|
52
|
+
*/
|
|
53
|
+
const isStringNode = (node, specifics) => isStringLiteral(node, specifics) || isTemplateLiteral(node, specifics);
|
|
54
|
+
/**
|
|
55
|
+
* Gets the value of the given `StringNode`.
|
|
56
|
+
*
|
|
57
|
+
* If the `node` is a `TemplateLiteral`, the `raw` value is used;
|
|
58
|
+
* otherwise, `value` is returned instead.
|
|
59
|
+
*
|
|
60
|
+
* @param {StringNode<S>} node
|
|
61
|
+
*
|
|
62
|
+
* @return {S}
|
|
63
|
+
*
|
|
64
|
+
* @template S
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
exports.isStringNode = isStringNode;
|
|
69
|
+
|
|
70
|
+
const getStringValue = node => isTemplateLiteral(node) ? node.quasis[0].value.raw : node.value;
|
|
71
|
+
/**
|
|
72
|
+
* An `Identifier` with a known `name` value - i.e `expect`.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
exports.getStringValue = getStringValue;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Checks if the given `node` is an `Identifier`.
|
|
80
|
+
*
|
|
81
|
+
* If a `name` is provided, & the `node` is an `Identifier`,
|
|
82
|
+
* the `name` will be compared to that of the `identifier`.
|
|
83
|
+
*
|
|
84
|
+
* @param {Node} node
|
|
85
|
+
* @param {V} [name]
|
|
86
|
+
*
|
|
87
|
+
* @return {node is KnownIdentifier<Name>}
|
|
88
|
+
*
|
|
89
|
+
* @template V
|
|
90
|
+
*/
|
|
91
|
+
const isIdentifier = (node, name) => node.type === _utils.AST_NODE_TYPES.Identifier && (name === undefined || node.name === name);
|
|
92
|
+
/**
|
|
93
|
+
* Checks if the given `node` is a "supported accessor".
|
|
94
|
+
*
|
|
95
|
+
* This means that it's a node can be used to access properties,
|
|
96
|
+
* and who's "value" can be statically determined.
|
|
97
|
+
*
|
|
98
|
+
* `MemberExpression` nodes most commonly contain accessors,
|
|
99
|
+
* but it's possible for other nodes to contain them.
|
|
100
|
+
*
|
|
101
|
+
* If a `value` is provided & the `node` is an `AccessorNode`,
|
|
102
|
+
* the `value` will be compared to that of the `AccessorNode`.
|
|
103
|
+
*
|
|
104
|
+
* Note that `value` here refers to the normalised value.
|
|
105
|
+
* The property that holds the value is not always called `name`.
|
|
106
|
+
*
|
|
107
|
+
* @param {Node} node
|
|
108
|
+
* @param {V} [value]
|
|
109
|
+
*
|
|
110
|
+
* @return {node is AccessorNode<V>}
|
|
111
|
+
*
|
|
112
|
+
* @template V
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
exports.isIdentifier = isIdentifier;
|
|
117
|
+
|
|
118
|
+
const isSupportedAccessor = (node, value) => isIdentifier(node, value) || isStringNode(node, value);
|
|
119
|
+
/**
|
|
120
|
+
* Gets the value of the given `AccessorNode`,
|
|
121
|
+
* account for the different node types.
|
|
122
|
+
*
|
|
123
|
+
* @param {AccessorNode<S>} accessor
|
|
124
|
+
*
|
|
125
|
+
* @return {S}
|
|
126
|
+
*
|
|
127
|
+
* @template S
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
exports.isSupportedAccessor = isSupportedAccessor;
|
|
132
|
+
|
|
133
|
+
const getAccessorValue = accessor => accessor.type === _utils.AST_NODE_TYPES.Identifier ? accessor.name : getStringValue(accessor);
|
|
134
|
+
|
|
135
|
+
exports.getAccessorValue = getAccessorValue;
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.followTypeAssertionChain = void 0;
|
|
7
|
+
|
|
8
|
+
var _utils = require("@typescript-eslint/utils");
|
|
9
|
+
|
|
10
|
+
const isTypeCastExpression = node => node.type === _utils.AST_NODE_TYPES.TSAsExpression || node.type === _utils.AST_NODE_TYPES.TSTypeAssertion;
|
|
11
|
+
|
|
12
|
+
const followTypeAssertionChain = expression => isTypeCastExpression(expression) ? followTypeAssertionChain(expression.expression) : expression;
|
|
13
|
+
|
|
14
|
+
exports.followTypeAssertionChain = followTypeAssertionChain;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var _accessors = require("./accessors");
|
|
8
|
+
|
|
9
|
+
Object.keys(_accessors).forEach(function (key) {
|
|
10
|
+
if (key === "default" || key === "__esModule") return;
|
|
11
|
+
if (key in exports && exports[key] === _accessors[key]) return;
|
|
12
|
+
Object.defineProperty(exports, key, {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _accessors[key];
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
var _detectJestVersion = require("./detectJestVersion");
|
|
21
|
+
|
|
22
|
+
Object.keys(_detectJestVersion).forEach(function (key) {
|
|
23
|
+
if (key === "default" || key === "__esModule") return;
|
|
24
|
+
if (key in exports && exports[key] === _detectJestVersion[key]) return;
|
|
25
|
+
Object.defineProperty(exports, key, {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () {
|
|
28
|
+
return _detectJestVersion[key];
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
var _followTypeAssertionChain = require("./followTypeAssertionChain");
|
|
34
|
+
|
|
35
|
+
Object.keys(_followTypeAssertionChain).forEach(function (key) {
|
|
36
|
+
if (key === "default" || key === "__esModule") return;
|
|
37
|
+
if (key in exports && exports[key] === _followTypeAssertionChain[key]) return;
|
|
38
|
+
Object.defineProperty(exports, key, {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: function () {
|
|
41
|
+
return _followTypeAssertionChain[key];
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
var _misc = require("./misc");
|
|
47
|
+
|
|
48
|
+
Object.keys(_misc).forEach(function (key) {
|
|
49
|
+
if (key === "default" || key === "__esModule") return;
|
|
50
|
+
if (key in exports && exports[key] === _misc[key]) return;
|
|
51
|
+
Object.defineProperty(exports, key, {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
get: function () {
|
|
54
|
+
return _misc[key];
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
var _parseJestFnCall = require("./parseJestFnCall");
|
|
60
|
+
|
|
61
|
+
Object.keys(_parseJestFnCall).forEach(function (key) {
|
|
62
|
+
if (key === "default" || key === "__esModule") return;
|
|
63
|
+
if (key in exports && exports[key] === _parseJestFnCall[key]) return;
|
|
64
|
+
Object.defineProperty(exports, key, {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
get: function () {
|
|
67
|
+
return _parseJestFnCall[key];
|
|
68
|
+
}
|
|
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
|
+
});
|