UNPKG

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