eslint-plugin-jest 26.3.0 → 26.4.0
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/lib/rules/consistent-test-it.js +9 -8
- package/lib/rules/expect-expect.js +1 -1
- package/lib/rules/max-nested-describe.js +2 -2
- package/lib/rules/no-conditional-expect.js +2 -2
- package/lib/rules/no-conditional-in-test.js +2 -2
- package/lib/rules/no-done-callback.js +4 -2
- package/lib/rules/no-duplicate-hooks.js +22 -23
- package/lib/rules/no-export.js +1 -1
- package/lib/rules/no-focused-tests.js +14 -22
- package/lib/rules/no-hooks.js +4 -2
- package/lib/rules/no-identical-title.js +10 -7
- package/lib/rules/no-if.js +4 -2
- package/lib/rules/no-standalone-expect.js +2 -2
- package/lib/rules/no-test-prefixes.js +12 -20
- package/lib/rules/no-test-return-statement.js +4 -1
- package/lib/rules/prefer-expect-assertions.js +2 -2
- package/lib/rules/prefer-hooks-in-order.js +5 -3
- package/lib/rules/prefer-hooks-on-top.js +2 -2
- package/lib/rules/prefer-lowercase-title.js +11 -22
- package/lib/rules/prefer-snapshot-hint.js +2 -2
- package/lib/rules/prefer-todo.js +24 -7
- package/lib/rules/require-hook.js +2 -2
- package/lib/rules/require-top-level-describe.js +9 -4
- package/lib/rules/utils/parseJestFnCall.js +306 -0
- package/lib/rules/utils.js +40 -252
- package/lib/rules/valid-describe-callback.js +4 -2
- package/lib/rules/valid-expect-in-promise.js +9 -11
- package/lib/rules/valid-title.js +7 -6
- package/package.json +1 -1
|
@@ -51,19 +51,20 @@ var _default = (0, _utils2.createRule)({
|
|
|
51
51
|
return {
|
|
52
52
|
CallExpression(node) {
|
|
53
53
|
const scope = context.getScope();
|
|
54
|
-
const
|
|
54
|
+
const jestFnCall = (0, _utils2.parseJestFnCall)(node, scope);
|
|
55
55
|
|
|
56
|
-
if (!
|
|
56
|
+
if (!jestFnCall) {
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
if (
|
|
60
|
+
if (jestFnCall.type === 'describe') {
|
|
61
61
|
describeNestingLevel++;
|
|
62
|
+
return;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
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;
|
|
65
66
|
|
|
66
|
-
if (
|
|
67
|
+
if (jestFnCall.type === 'test' && describeNestingLevel === 0 && !jestFnCall.name.endsWith(testKeyword)) {
|
|
67
68
|
const oppositeTestKeyword = getOppositeTestKeyword(testKeyword);
|
|
68
69
|
context.report({
|
|
69
70
|
messageId: 'consistentMethod',
|
|
@@ -72,11 +73,11 @@ var _default = (0, _utils2.createRule)({
|
|
|
72
73
|
testKeyword,
|
|
73
74
|
oppositeTestKeyword
|
|
74
75
|
},
|
|
75
|
-
fix: buildFixer(funcNode,
|
|
76
|
+
fix: buildFixer(funcNode, jestFnCall.name, testKeyword)
|
|
76
77
|
});
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
if (
|
|
80
|
+
if (jestFnCall.type === 'test' && describeNestingLevel > 0 && !jestFnCall.name.endsWith(testKeywordWithinDescribe)) {
|
|
80
81
|
const oppositeTestKeyword = getOppositeTestKeyword(testKeywordWithinDescribe);
|
|
81
82
|
context.report({
|
|
82
83
|
messageId: 'consistentMethodWithinDescribe',
|
|
@@ -85,13 +86,13 @@ var _default = (0, _utils2.createRule)({
|
|
|
85
86
|
testKeywordWithinDescribe,
|
|
86
87
|
oppositeTestKeyword
|
|
87
88
|
},
|
|
88
|
-
fix: buildFixer(funcNode,
|
|
89
|
+
fix: buildFixer(funcNode, jestFnCall.name, testKeywordWithinDescribe)
|
|
89
90
|
});
|
|
90
91
|
}
|
|
91
92
|
},
|
|
92
93
|
|
|
93
94
|
'CallExpression:exit'(node) {
|
|
94
|
-
if ((0, _utils2.
|
|
95
|
+
if ((0, _utils2.isTypeOfJestFnCall)(node, context.getScope(), ['describe'])) {
|
|
95
96
|
describeNestingLevel--;
|
|
96
97
|
}
|
|
97
98
|
}
|
|
@@ -93,7 +93,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
93
93
|
|
|
94
94
|
const name = (_getNodeName = (0, _utils2.getNodeName)(node.callee)) !== null && _getNodeName !== void 0 ? _getNodeName : '';
|
|
95
95
|
|
|
96
|
-
if ((0, _utils2.
|
|
96
|
+
if ((0, _utils2.isTypeOfJestFnCall)(node, context.getScope(), ['test']) || additionalTestBlockFunctions.includes(name)) {
|
|
97
97
|
if (node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property, 'todo')) {
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
@@ -46,7 +46,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
46
46
|
parent
|
|
47
47
|
} = node;
|
|
48
48
|
|
|
49
|
-
if ((parent === null || parent === void 0 ? void 0 : parent.type) !== _utils.AST_NODE_TYPES.CallExpression || !(0, _utils2.
|
|
49
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) !== _utils.AST_NODE_TYPES.CallExpression || !(0, _utils2.isTypeOfJestFnCall)(parent, context.getScope(), ['describe'])) {
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -69,7 +69,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
69
69
|
parent
|
|
70
70
|
} = node;
|
|
71
71
|
|
|
72
|
-
if ((parent === null || parent === void 0 ? void 0 : parent.type) === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.
|
|
72
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isTypeOfJestFnCall)(parent, context.getScope(), ['describe'])) {
|
|
73
73
|
describeCallbackStack.pop();
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -47,7 +47,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
47
47
|
},
|
|
48
48
|
|
|
49
49
|
CallExpression(node) {
|
|
50
|
-
if ((0, _utils2.
|
|
50
|
+
if ((0, _utils2.isTypeOfJestFnCall)(node, context.getScope(), ['test'])) {
|
|
51
51
|
inTestCase = true;
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -71,7 +71,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
71
71
|
},
|
|
72
72
|
|
|
73
73
|
'CallExpression:exit'(node) {
|
|
74
|
-
if ((0, _utils2.
|
|
74
|
+
if ((0, _utils2.isTypeOfJestFnCall)(node, context.getScope(), ['test'])) {
|
|
75
75
|
inTestCase = false;
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -37,13 +37,13 @@ var _default = (0, _utils.createRule)({
|
|
|
37
37
|
|
|
38
38
|
return {
|
|
39
39
|
CallExpression(node) {
|
|
40
|
-
if ((0, _utils.
|
|
40
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context.getScope(), ['test'])) {
|
|
41
41
|
inTestCase = true;
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
|
|
45
45
|
'CallExpression:exit'(node) {
|
|
46
|
-
if ((0, _utils.
|
|
46
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context.getScope(), ['test'])) {
|
|
47
47
|
inTestCase = false;
|
|
48
48
|
}
|
|
49
49
|
},
|
|
@@ -14,11 +14,13 @@ const findCallbackArg = (node, isJestEach, scope) => {
|
|
|
14
14
|
return node.arguments[1];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const jestFnCall = (0, _utils2.parseJestFnCall)(node, scope);
|
|
18
|
+
|
|
19
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'hook' && node.arguments.length >= 1) {
|
|
18
20
|
return node.arguments[0];
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
if ((0
|
|
23
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test' && node.arguments.length >= 2) {
|
|
22
24
|
return node.arguments[1];
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -7,13 +7,6 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _utils = require("./utils");
|
|
9
9
|
|
|
10
|
-
const newHookContext = () => ({
|
|
11
|
-
beforeAll: 0,
|
|
12
|
-
beforeEach: 0,
|
|
13
|
-
afterAll: 0,
|
|
14
|
-
afterEach: 0
|
|
15
|
-
});
|
|
16
|
-
|
|
17
10
|
var _default = (0, _utils.createRule)({
|
|
18
11
|
name: __filename,
|
|
19
12
|
meta: {
|
|
@@ -31,33 +24,39 @@ var _default = (0, _utils.createRule)({
|
|
|
31
24
|
defaultOptions: [],
|
|
32
25
|
|
|
33
26
|
create(context) {
|
|
34
|
-
const hookContexts = [
|
|
27
|
+
const hookContexts = [{}];
|
|
35
28
|
return {
|
|
36
29
|
CallExpression(node) {
|
|
30
|
+
var _jestFnCall$name;
|
|
31
|
+
|
|
37
32
|
const scope = context.getScope();
|
|
33
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, scope);
|
|
34
|
+
|
|
35
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'describe') {
|
|
36
|
+
hookContexts.push({});
|
|
37
|
+
}
|
|
38
38
|
|
|
39
|
-
if ((0
|
|
40
|
-
|
|
39
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'hook') {
|
|
40
|
+
return;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
const currentLayer = hookContexts[hookContexts.length - 1];
|
|
44
|
+
currentLayer[_jestFnCall$name = jestFnCall.name] || (currentLayer[_jestFnCall$name] = 0);
|
|
45
|
+
currentLayer[jestFnCall.name] += 1;
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
47
|
+
if (currentLayer[jestFnCall.name] > 1) {
|
|
48
|
+
context.report({
|
|
49
|
+
messageId: 'noDuplicateHook',
|
|
50
|
+
data: {
|
|
51
|
+
hook: jestFnCall.name
|
|
52
|
+
},
|
|
53
|
+
node
|
|
54
|
+
});
|
|
56
55
|
}
|
|
57
56
|
},
|
|
58
57
|
|
|
59
58
|
'CallExpression:exit'(node) {
|
|
60
|
-
if ((0, _utils.
|
|
59
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context.getScope(), ['describe'])) {
|
|
61
60
|
hookContexts.pop();
|
|
62
61
|
}
|
|
63
62
|
}
|
package/lib/rules/no-export.js
CHANGED
|
@@ -9,24 +9,6 @@ var _utils = require("@typescript-eslint/utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils2 = require("./utils");
|
|
11
11
|
|
|
12
|
-
const findOnlyNode = node => {
|
|
13
|
-
const callee = node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _utils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
|
|
14
|
-
|
|
15
|
-
if (callee.type === _utils.AST_NODE_TYPES.MemberExpression) {
|
|
16
|
-
if (callee.object.type === _utils.AST_NODE_TYPES.MemberExpression) {
|
|
17
|
-
if ((0, _utils2.isSupportedAccessor)(callee.object.property, 'only')) {
|
|
18
|
-
return callee.object.property;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if ((0, _utils2.isSupportedAccessor)(callee.property, 'only')) {
|
|
23
|
-
return callee.property;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return null;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
12
|
var _default = (0, _utils2.createRule)({
|
|
31
13
|
name: __filename,
|
|
32
14
|
meta: {
|
|
@@ -50,24 +32,34 @@ var _default = (0, _utils2.createRule)({
|
|
|
50
32
|
return {
|
|
51
33
|
CallExpression(node) {
|
|
52
34
|
const scope = context.getScope();
|
|
35
|
+
const jestFnCall = (0, _utils2.parseJestFnCall)(node, scope);
|
|
53
36
|
|
|
54
|
-
if (
|
|
37
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test' && (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'describe') {
|
|
55
38
|
return;
|
|
56
39
|
}
|
|
57
40
|
|
|
58
|
-
if (
|
|
41
|
+
if (jestFnCall.name.startsWith('f')) {
|
|
59
42
|
context.report({
|
|
60
43
|
messageId: 'focusedTest',
|
|
61
44
|
node,
|
|
62
45
|
suggest: [{
|
|
63
46
|
messageId: 'suggestRemoveFocus',
|
|
64
|
-
|
|
47
|
+
|
|
48
|
+
fix(fixer) {
|
|
49
|
+
// don't apply the fixer if we're an aliased import
|
|
50
|
+
if (jestFnCall.head.type === 'import' && jestFnCall.name !== jestFnCall.head.local) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return fixer.removeRange([node.range[0], node.range[0] + 1]);
|
|
55
|
+
}
|
|
56
|
+
|
|
65
57
|
}]
|
|
66
58
|
});
|
|
67
59
|
return;
|
|
68
60
|
}
|
|
69
61
|
|
|
70
|
-
const onlyNode =
|
|
62
|
+
const onlyNode = jestFnCall.members.find(s => (0, _utils2.getAccessorValue)(s) === 'only');
|
|
71
63
|
|
|
72
64
|
if (!onlyNode) {
|
|
73
65
|
return;
|
package/lib/rules/no-hooks.js
CHANGED
|
@@ -39,12 +39,14 @@ var _default = (0, _utils.createRule)({
|
|
|
39
39
|
}]) {
|
|
40
40
|
return {
|
|
41
41
|
CallExpression(node) {
|
|
42
|
-
|
|
42
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, context.getScope());
|
|
43
|
+
|
|
44
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'hook' && !allow.includes(jestFnCall.name)) {
|
|
43
45
|
context.report({
|
|
44
46
|
node,
|
|
45
47
|
messageId: 'unexpectedHook',
|
|
46
48
|
data: {
|
|
47
|
-
hookName:
|
|
49
|
+
hookName: jestFnCall.name
|
|
48
50
|
}
|
|
49
51
|
});
|
|
50
52
|
}
|
|
@@ -33,16 +33,19 @@ var _default = (0, _utils.createRule)({
|
|
|
33
33
|
const contexts = [newDescribeContext()];
|
|
34
34
|
return {
|
|
35
35
|
CallExpression(node) {
|
|
36
|
-
var _getNodeName;
|
|
37
|
-
|
|
38
36
|
const scope = context.getScope();
|
|
39
37
|
const currentLayer = contexts[contexts.length - 1];
|
|
38
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, scope);
|
|
39
|
+
|
|
40
|
+
if (!jestFnCall) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
40
43
|
|
|
41
|
-
if (
|
|
44
|
+
if (jestFnCall.type === 'describe') {
|
|
42
45
|
contexts.push(newDescribeContext());
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
if ((
|
|
48
|
+
if (jestFnCall.members.find(s => (0, _utils.isSupportedAccessor)(s, 'each'))) {
|
|
46
49
|
return;
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -54,7 +57,7 @@ var _default = (0, _utils.createRule)({
|
|
|
54
57
|
|
|
55
58
|
const title = (0, _utils.getStringValue)(argument);
|
|
56
59
|
|
|
57
|
-
if (
|
|
60
|
+
if (jestFnCall.type === 'test') {
|
|
58
61
|
if (currentLayer.testTitles.includes(title)) {
|
|
59
62
|
context.report({
|
|
60
63
|
messageId: 'multipleTestTitle',
|
|
@@ -65,7 +68,7 @@ var _default = (0, _utils.createRule)({
|
|
|
65
68
|
currentLayer.testTitles.push(title);
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
if (
|
|
71
|
+
if (jestFnCall.type !== 'describe') {
|
|
69
72
|
return;
|
|
70
73
|
}
|
|
71
74
|
|
|
@@ -80,7 +83,7 @@ var _default = (0, _utils.createRule)({
|
|
|
80
83
|
},
|
|
81
84
|
|
|
82
85
|
'CallExpression:exit'(node) {
|
|
83
|
-
if ((0, _utils.
|
|
86
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context.getScope(), ['describe'])) {
|
|
84
87
|
contexts.pop();
|
|
85
88
|
}
|
|
86
89
|
}
|
package/lib/rules/no-if.js
CHANGED
|
@@ -58,10 +58,12 @@ var _default = (0, _utils2.createRule)({
|
|
|
58
58
|
|
|
59
59
|
return {
|
|
60
60
|
CallExpression(node) {
|
|
61
|
-
|
|
61
|
+
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context.getScope());
|
|
62
|
+
|
|
63
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test') {
|
|
62
64
|
stack.push(true);
|
|
63
65
|
|
|
64
|
-
if ((0, _utils2.
|
|
66
|
+
if (jestFnCall.members.some(s => (0, _utils2.getAccessorValue)(s) === 'each')) {
|
|
65
67
|
stack.push(true);
|
|
66
68
|
}
|
|
67
69
|
}
|
|
@@ -30,7 +30,7 @@ const getBlockType = (statement, scope) => {
|
|
|
30
30
|
} // if it's not a variable, it will be callExpr, we only care about describe
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
if (expr.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.
|
|
33
|
+
if (expr.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isTypeOfJestFnCall)(expr, scope, ['describe'])) {
|
|
34
34
|
return 'describe';
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -73,7 +73,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
73
73
|
|
|
74
74
|
const isCustomTestBlockFunction = node => additionalTestBlockFunctions.includes((0, _utils2.getNodeName)(node) || '');
|
|
75
75
|
|
|
76
|
-
const isTestBlock = node => (0, _utils2.
|
|
76
|
+
const isTestBlock = node => (0, _utils2.isTypeOfJestFnCall)(node, context.getScope(), ['test']) || isCustomTestBlockFunction(node);
|
|
77
77
|
|
|
78
78
|
return {
|
|
79
79
|
CallExpression(node) {
|
|
@@ -30,10 +30,17 @@ var _default = (0, _utils2.createRule)({
|
|
|
30
30
|
return {
|
|
31
31
|
CallExpression(node) {
|
|
32
32
|
const scope = context.getScope();
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
const jestFnCall = (0, _utils2.parseJestFnCall)(node, scope);
|
|
34
|
+
|
|
35
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'describe' && (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test') {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (jestFnCall.name[0] !== 'f' && jestFnCall.name[0] !== 'x') {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const preferredNodeName = [jestFnCall.name.slice(1), jestFnCall.name[0] === 'f' ? 'only' : 'skip', ...jestFnCall.members.map(s => (0, _utils2.getAccessorValue)(s))].join('.');
|
|
37
44
|
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;
|
|
38
45
|
context.report({
|
|
39
46
|
messageId: 'usePreferredName',
|
|
@@ -54,19 +61,4 @@ var _default = (0, _utils2.createRule)({
|
|
|
54
61
|
|
|
55
62
|
});
|
|
56
63
|
|
|
57
|
-
exports.default = _default;
|
|
58
|
-
|
|
59
|
-
function getPreferredNodeName(nodeName) {
|
|
60
|
-
const firstChar = nodeName.charAt(0);
|
|
61
|
-
const suffix = nodeName.endsWith('.each') ? '.each' : '';
|
|
62
|
-
|
|
63
|
-
if (firstChar === 'f') {
|
|
64
|
-
return `${nodeName.slice(1).replace('.each', '')}.only${suffix}`;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (firstChar === 'x') {
|
|
68
|
-
return `${nodeName.slice(1).replace('.each', '')}.skip${suffix}`;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
64
|
+
exports.default = _default;
|
|
@@ -38,7 +38,10 @@ var _default = (0, _utils2.createRule)({
|
|
|
38
38
|
create(context) {
|
|
39
39
|
return {
|
|
40
40
|
CallExpression(node) {
|
|
41
|
-
if (!(0, _utils2.
|
|
41
|
+
if (!(0, _utils2.isTypeOfJestFnCall)(node, context.getScope(), ['test'])) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
42
45
|
const body = getBody(node.arguments);
|
|
43
46
|
const returnStmt = body.find(t => t.type === _utils.AST_NODE_TYPES.ReturnStatement);
|
|
44
47
|
if (!returnStmt) return;
|
|
@@ -116,7 +116,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
116
116
|
'ForOfStatement:exit': exitForLoop,
|
|
117
117
|
|
|
118
118
|
CallExpression(node) {
|
|
119
|
-
if ((0, _utils2.
|
|
119
|
+
if ((0, _utils2.isTypeOfJestFnCall)(node, context.getScope(), ['test'])) {
|
|
120
120
|
inTestCaseCall = true;
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
@@ -133,7 +133,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
133
133
|
},
|
|
134
134
|
|
|
135
135
|
'CallExpression:exit'(node) {
|
|
136
|
-
if (!(0, _utils2.
|
|
136
|
+
if (!(0, _utils2.isTypeOfJestFnCall)(node, context.getScope(), ['test'])) {
|
|
137
137
|
return;
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -35,14 +35,16 @@ var _default = (0, _utils.createRule)({
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, context.getScope());
|
|
39
|
+
|
|
40
|
+
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'hook') {
|
|
39
41
|
// Reset the previousHookIndex when encountering something different from a hook
|
|
40
42
|
previousHookIndex = -1;
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
inHook = true;
|
|
45
|
-
const currentHook =
|
|
47
|
+
const currentHook = jestFnCall.name;
|
|
46
48
|
const currentHookIndex = HooksOrder.indexOf(currentHook);
|
|
47
49
|
|
|
48
50
|
if (currentHookIndex < previousHookIndex) {
|
|
@@ -61,7 +63,7 @@ var _default = (0, _utils.createRule)({
|
|
|
61
63
|
},
|
|
62
64
|
|
|
63
65
|
'CallExpression:exit'(node) {
|
|
64
|
-
if ((0, _utils.
|
|
66
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context.getScope(), ['hook'])) {
|
|
65
67
|
inHook = false;
|
|
66
68
|
return;
|
|
67
69
|
}
|
|
@@ -29,11 +29,11 @@ var _default = (0, _utils.createRule)({
|
|
|
29
29
|
CallExpression(node) {
|
|
30
30
|
const scope = context.getScope();
|
|
31
31
|
|
|
32
|
-
if (
|
|
32
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, scope, ['test'])) {
|
|
33
33
|
hooksContext[hooksContext.length - 1] = true;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
if (hooksContext[hooksContext.length - 1] && (0, _utils.
|
|
36
|
+
if (hooksContext[hooksContext.length - 1] && (0, _utils.isTypeOfJestFnCall)(node, scope, ['hook'])) {
|
|
37
37
|
context.report({
|
|
38
38
|
messageId: 'noHookOnTop',
|
|
39
39
|
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, scope) => {
|
|
13
|
-
if (!((0, _utils.isTestCaseCall)(node, scope) || (0, _utils.isDescribeCall)(node, scope))) {
|
|
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
|
|
|
@@ -93,22 +81,23 @@ var _default = (0, _utils.createRule)({
|
|
|
93
81
|
return {
|
|
94
82
|
CallExpression(node) {
|
|
95
83
|
const scope = context.getScope();
|
|
84
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, scope);
|
|
96
85
|
|
|
97
|
-
if (
|
|
86
|
+
if (!jestFnCall || !hasStringAsFirstArgument(node)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (jestFnCall.type === 'describe') {
|
|
98
91
|
numberOfDescribeBlocks++;
|
|
99
92
|
|
|
100
93
|
if (ignoreTopLevelDescribe && numberOfDescribeBlocks === 1) {
|
|
101
94
|
return;
|
|
102
95
|
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const results = findNodeNameAndArgument(node, scope);
|
|
106
|
-
|
|
107
|
-
if (!results) {
|
|
96
|
+
} else if (jestFnCall.type !== 'test') {
|
|
108
97
|
return;
|
|
109
98
|
}
|
|
110
99
|
|
|
111
|
-
const [
|
|
100
|
+
const [firstArg] = node.arguments;
|
|
112
101
|
const description = (0, _utils.getStringValue)(firstArg);
|
|
113
102
|
|
|
114
103
|
if (allowedPrefixes.some(name => description.startsWith(name))) {
|
|
@@ -117,7 +106,7 @@ var _default = (0, _utils.createRule)({
|
|
|
117
106
|
|
|
118
107
|
const firstCharacter = description.charAt(0);
|
|
119
108
|
|
|
120
|
-
if (!firstCharacter || firstCharacter === firstCharacter.toLowerCase() || ignores.includes(name)) {
|
|
109
|
+
if (!firstCharacter || firstCharacter === firstCharacter.toLowerCase() || ignores.includes(jestFnCall.name)) {
|
|
121
110
|
return;
|
|
122
111
|
}
|
|
123
112
|
|
|
@@ -125,7 +114,7 @@ var _default = (0, _utils.createRule)({
|
|
|
125
114
|
messageId: 'unexpectedLowercase',
|
|
126
115
|
node: node.arguments[0],
|
|
127
116
|
data: {
|
|
128
|
-
method: name
|
|
117
|
+
method: jestFnCall.name
|
|
129
118
|
},
|
|
130
119
|
|
|
131
120
|
fix(fixer) {
|
|
@@ -139,7 +128,7 @@ var _default = (0, _utils.createRule)({
|
|
|
139
128
|
},
|
|
140
129
|
|
|
141
130
|
'CallExpression:exit'(node) {
|
|
142
|
-
if ((0, _utils.
|
|
131
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, context.getScope(), ['describe'])) {
|
|
143
132
|
numberOfDescribeBlocks--;
|
|
144
133
|
}
|
|
145
134
|
}
|
|
@@ -108,7 +108,7 @@ var _default = (0, _utils.createRule)({
|
|
|
108
108
|
'CallExpression:exit'(node) {
|
|
109
109
|
const scope = context.getScope();
|
|
110
110
|
|
|
111
|
-
if ((0, _utils.
|
|
111
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, scope, ['describe', 'test'])) {
|
|
112
112
|
var _depths$pop;
|
|
113
113
|
|
|
114
114
|
/* istanbul ignore next */
|
|
@@ -119,7 +119,7 @@ var _default = (0, _utils.createRule)({
|
|
|
119
119
|
CallExpression(node) {
|
|
120
120
|
const scope = context.getScope();
|
|
121
121
|
|
|
122
|
-
if ((0, _utils.
|
|
122
|
+
if ((0, _utils.isTypeOfJestFnCall)(node, scope, ['describe', 'test'])) {
|
|
123
123
|
depths.push(expressionDepth);
|
|
124
124
|
expressionDepth = 0;
|
|
125
125
|
}
|
package/lib/rules/prefer-todo.js
CHANGED
|
@@ -17,12 +17,28 @@ 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
|
-
const
|
|
22
|
-
|
|
20
|
+
function createTodoFixer(jestFnCall, fixer) {
|
|
21
|
+
const fixes = [fixer.replaceText(jestFnCall.head.node, `${jestFnCall.head.local}.todo`)];
|
|
22
|
+
|
|
23
|
+
if (jestFnCall.members.length) {
|
|
24
|
+
fixes.unshift(fixer.removeRange([jestFnCall.head.node.range[1], jestFnCall.members[0].range[1]]));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return fixes;
|
|
23
28
|
}
|
|
24
29
|
|
|
25
|
-
const isTargetedTestCase =
|
|
30
|
+
const isTargetedTestCase = jestFnCall => {
|
|
31
|
+
if (jestFnCall.members.some(s => (0, _utils2.getAccessorValue)(s) !== 'skip')) {
|
|
32
|
+
return false;
|
|
33
|
+
} // todo: we should support this too (needs custom fixer)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if (jestFnCall.name.startsWith('x')) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return !jestFnCall.name.startsWith('f');
|
|
41
|
+
};
|
|
26
42
|
|
|
27
43
|
var _default = (0, _utils2.createRule)({
|
|
28
44
|
name: __filename,
|
|
@@ -46,8 +62,9 @@ var _default = (0, _utils2.createRule)({
|
|
|
46
62
|
return {
|
|
47
63
|
CallExpression(node) {
|
|
48
64
|
const [title, callback] = node.arguments;
|
|
65
|
+
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context.getScope());
|
|
49
66
|
|
|
50
|
-
if (!title ||
|
|
67
|
+
if (!title || (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test' || !isTargetedTestCase(jestFnCall) || !(0, _utils2.isStringNode)(title)) {
|
|
51
68
|
return;
|
|
52
69
|
}
|
|
53
70
|
|
|
@@ -55,7 +72,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
55
72
|
context.report({
|
|
56
73
|
messageId: 'emptyTest',
|
|
57
74
|
node,
|
|
58
|
-
fix: fixer => [fixer.removeRange([title.range[1], callback.range[1]]), createTodoFixer(
|
|
75
|
+
fix: fixer => [fixer.removeRange([title.range[1], callback.range[1]]), ...createTodoFixer(jestFnCall, fixer)]
|
|
59
76
|
});
|
|
60
77
|
}
|
|
61
78
|
|
|
@@ -63,7 +80,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
63
80
|
context.report({
|
|
64
81
|
messageId: 'unimplementedTest',
|
|
65
82
|
node,
|
|
66
|
-
fix: fixer =>
|
|
83
|
+
fix: fixer => createTodoFixer(jestFnCall, fixer)
|
|
67
84
|
});
|
|
68
85
|
}
|
|
69
86
|
}
|