1 | 'use strict';
|
2 |
|
3 | const {
|
4 | getDocsUrl,
|
5 | isFunction,
|
6 | composeFixers,
|
7 | getNodeName,
|
8 | isString,
|
9 | } = require('./util');
|
10 |
|
11 | function isOnlyTestTitle(node) {
|
12 | return node.arguments.length === 1;
|
13 | }
|
14 |
|
15 | function isFunctionBodyEmpty(node) {
|
16 | return node.body.body && !node.body.body.length;
|
17 | }
|
18 |
|
19 | function isTestBodyEmpty(node) {
|
20 | const fn = node.arguments[1];
|
21 | return fn && isFunction(fn) && isFunctionBodyEmpty(fn);
|
22 | }
|
23 |
|
24 | function addTodo(node, fixer) {
|
25 | const testName = getNodeName(node.callee)
|
26 | .split('.')
|
27 | .shift();
|
28 | return fixer.replaceText(node.callee, `${testName}.todo`);
|
29 | }
|
30 |
|
31 | function removeSecondArg({ arguments: [first, second] }, fixer) {
|
32 | return fixer.removeRange([first.range[1], second.range[1]]);
|
33 | }
|
34 |
|
35 | function isFirstArgString({ arguments: [firstArg] }) {
|
36 | return firstArg && isString(firstArg);
|
37 | }
|
38 |
|
39 | const isTestCase = node =>
|
40 | node &&
|
41 | node.type === 'CallExpression' &&
|
42 | ['it', 'test', 'it.skip', 'test.skip'].includes(getNodeName(node.callee));
|
43 |
|
44 | function create(context) {
|
45 | return {
|
46 | CallExpression(node) {
|
47 | if (isTestCase(node) && isFirstArgString(node)) {
|
48 | const combineFixers = composeFixers(node);
|
49 |
|
50 | if (isTestBodyEmpty(node)) {
|
51 | context.report({
|
52 | message: 'Prefer todo test case over empty test case',
|
53 | node,
|
54 | fix: combineFixers(removeSecondArg, addTodo),
|
55 | });
|
56 | }
|
57 |
|
58 | if (isOnlyTestTitle(node)) {
|
59 | context.report({
|
60 | message: 'Prefer todo test case over unimplemented test case',
|
61 | node,
|
62 | fix: combineFixers(addTodo),
|
63 | });
|
64 | }
|
65 | }
|
66 | },
|
67 | };
|
68 | }
|
69 |
|
70 | module.exports = {
|
71 | create,
|
72 | meta: {
|
73 | docs: {
|
74 | url: getDocsUrl(__filename),
|
75 | },
|
76 | fixable: 'code',
|
77 | },
|
78 | };
|