/
consistent-test-it.js
121 lines (107 loc) · 3.17 KB
/
consistent-test-it.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
'use strict';
const { getDocsUrl, getNodeName, isTestCase, isDescribe } = require('./util');
module.exports = {
meta: {
docs: {
url: getDocsUrl(__filename),
},
fixable: 'code',
schema: [
{
type: 'object',
properties: {
fn: {
enum: ['it', 'test'],
},
withinDescribe: {
enum: ['it', 'test'],
},
},
additionalProperties: false,
},
],
},
create(context) {
const configObj = context.options[0] || {};
const testKeyword = configObj.fn || 'test';
const testKeywordWithinDescribe =
configObj.withinDescribe || configObj.fn || 'it';
let describeNestingLevel = 0;
return {
CallExpression(node) {
const nodeName = getNodeName(node.callee);
if (isDescribe(node)) {
describeNestingLevel++;
}
if (
isTestCase(node) &&
describeNestingLevel === 0 &&
nodeName.indexOf(testKeyword) === -1
) {
const oppositeTestKeyword = getOppositeTestKeyword(testKeyword);
context.report({
message:
"Prefer using '{{ testKeyword }}' instead of '{{ oppositeTestKeyword }}'",
node: node.callee,
data: { testKeyword, oppositeTestKeyword },
fix(fixer) {
const nodeToReplace =
node.callee.type === 'MemberExpression'
? node.callee.object
: node.callee;
const fixedNodeName = getPreferredNodeName(nodeName, testKeyword);
return [fixer.replaceText(nodeToReplace, fixedNodeName)];
},
});
}
if (
isTestCase(node) &&
describeNestingLevel > 0 &&
nodeName.indexOf(testKeywordWithinDescribe) === -1
) {
const oppositeTestKeyword = getOppositeTestKeyword(
testKeywordWithinDescribe,
);
context.report({
message:
"Prefer using '{{ testKeywordWithinDescribe }}' instead of '{{ oppositeTestKeyword }}' within describe",
node: node.callee,
data: { testKeywordWithinDescribe, oppositeTestKeyword },
fix(fixer) {
const nodeToReplace =
node.callee.type === 'MemberExpression'
? node.callee.object
: node.callee;
const fixedNodeName = getPreferredNodeName(
nodeName,
testKeywordWithinDescribe,
);
return [fixer.replaceText(nodeToReplace, fixedNodeName)];
},
});
}
},
'CallExpression:exit'(node) {
if (isDescribe(node)) {
describeNestingLevel--;
}
},
};
},
};
function getPreferredNodeName(nodeName, preferredTestKeyword) {
switch (nodeName) {
case 'fit':
return 'test.only';
default:
return nodeName.startsWith('f') || nodeName.startsWith('x')
? nodeName.charAt(0) + preferredTestKeyword
: preferredTestKeyword;
}
}
function getOppositeTestKeyword(test) {
if (test === 'test') {
return 'it';
}
return 'test';
}