Skip to content

Commit 14d83ef

Browse files
kangaxSimenB
authored andcommitted
feat(rules): add no-commented-out rule (#262)
1 parent 83ff198 commit 14d83ef

File tree

5 files changed

+318
-1
lines changed

5 files changed

+318
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ for more information about extending configuration files.
9696
| [lowercase-name][] | Disallow capitalized test names | | ![fixable-green][] |
9797
| [no-alias-methods][] | Disallow alias methods | ![recommended][] | ![fixable-green][] |
9898
| [no-disabled-tests][] | Disallow disabled tests | ![recommended][] | |
99+
| [no-commented-out-tests][] | Disallow commented out tests | | |
99100
| [no-empty-title][] | Disallow empty titles | | |
100101
| [no-focused-tests][] | Disallow focused tests | ![recommended][] | |
101102
| [no-hooks][] | Disallow setup and teardown hooks | | |
@@ -142,6 +143,7 @@ https://github.com/dangreenisrael/eslint-plugin-jest-formatting
142143
[lowercase-name]: docs/rules/lowercase-name.md
143144
[no-alias-methods]: docs/rules/no-alias-methods.md
144145
[no-disabled-tests]: docs/rules/no-disabled-tests.md
146+
[no-commented-out-tests]: docs/rules/no-commented-out-tests.md
145147
[no-empty-title]: docs/rules/no-empty-title.md
146148
[no-focused-tests]: docs/rules/no-focused-tests.md
147149
[no-hooks]: docs/rules/no-hooks.md

docs/rules/no-commented-out-tests.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Disallow commented out tests (no-commented-out-tests)
2+
3+
This rule raises a warning about commented out tests. It's similar to
4+
no-disabled-tests rule.
5+
6+
## Rule Details
7+
8+
The rule uses fuzzy matching to do its best to determine what constitutes a
9+
commented out test, checking for a presence of `it(`, `describe(`, `it.skip(`,
10+
etc. in code comments.
11+
12+
The following patterns are considered warnings:
13+
14+
```js
15+
// describe('foo', () => {});
16+
// it('foo', () => {});
17+
// test('foo', () => {});
18+
19+
// describe.skip('foo', () => {});
20+
// it.skip('foo', () => {});
21+
// test.skip('foo', () => {});
22+
23+
// describe['skip']('bar', () => {});
24+
// it['skip']('bar', () => {});
25+
// test['skip']('bar', () => {});
26+
27+
// xdescribe('foo', () => {});
28+
// xit('foo', () => {});
29+
// xtest('foo', () => {});
30+
31+
/*
32+
describe('foo', () => {});
33+
*/
34+
```
35+
36+
These patterns would not be considered warnings:
37+
38+
```js
39+
describe('foo', () => {});
40+
it('foo', () => {});
41+
test('foo', () => {});
42+
43+
describe.only('bar', () => {});
44+
it.only('bar', () => {});
45+
test.only('bar', () => {});
46+
47+
// foo('bar', () => {});
48+
```
49+
50+
### Limitations
51+
52+
The plugin looks at the literal function names within test code, so will not
53+
catch more complex examples of commented out tests, such as:
54+
55+
```js
56+
// const testSkip = test.skip;
57+
// testSkip('skipped test', () => {});
58+
59+
// const myTest = test;
60+
// myTest('does not have function body');
61+
```

src/__tests__/rules.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const path = require('path');
55
const { rules } = require('../');
66

77
const ruleNames = Object.keys(rules);
8-
const numberOfRules = 31;
8+
const numberOfRules = 32;
99

1010
describe('rules', () => {
1111
it('should have a corresponding doc for each rule', () => {
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
'use strict';
2+
3+
const { RuleTester } = require('eslint');
4+
const rule = require('../no-commented-out-tests');
5+
6+
const ruleTester = new RuleTester({
7+
parserOptions: {
8+
sourceType: 'module',
9+
},
10+
});
11+
12+
ruleTester.run('no-commented-out-tests', rule, {
13+
valid: [
14+
'// foo("bar", function () {})',
15+
'describe("foo", function () {})',
16+
'it("foo", function () {})',
17+
'describe.only("foo", function () {})',
18+
'it.only("foo", function () {})',
19+
'test("foo", function () {})',
20+
'test.only("foo", function () {})',
21+
'var appliedSkip = describe.skip; appliedSkip.apply(describe)',
22+
'var calledSkip = it.skip; calledSkip.call(it)',
23+
'({ f: function () {} }).f()',
24+
'(a || b).f()',
25+
'itHappensToStartWithIt()',
26+
'testSomething()',
27+
[
28+
'import { pending } from "actions"',
29+
'',
30+
'test("foo", () => {',
31+
' expect(pending()).toEqual({})',
32+
'})',
33+
].join('\n'),
34+
[
35+
'const { pending } = require("actions")',
36+
'',
37+
'test("foo", () => {',
38+
' expect(pending()).toEqual({})',
39+
'})',
40+
].join('\n'),
41+
[
42+
'test("foo", () => {',
43+
' const pending = getPending()',
44+
' expect(pending()).toEqual({})',
45+
'})',
46+
].join('\n'),
47+
[
48+
'test("foo", () => {',
49+
' expect(pending()).toEqual({})',
50+
'})',
51+
'',
52+
'function pending() {',
53+
' return {}',
54+
'}',
55+
].join('\n'),
56+
],
57+
58+
invalid: [
59+
{
60+
code: '// describe("foo", function () {})',
61+
errors: [
62+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
63+
],
64+
},
65+
{
66+
code: '// describe["skip"]("foo", function () {})',
67+
errors: [
68+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
69+
],
70+
},
71+
{
72+
code: '// describe[\'skip\']("foo", function () {})',
73+
errors: [
74+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
75+
],
76+
},
77+
{
78+
code: '// it.skip("foo", function () {})',
79+
errors: [
80+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
81+
],
82+
},
83+
{
84+
code: '// it.only("foo", function () {})',
85+
errors: [
86+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
87+
],
88+
},
89+
{
90+
code: '// it["skip"]("foo", function () {})',
91+
errors: [
92+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
93+
],
94+
},
95+
{
96+
code: '// test.skip("foo", function () {})',
97+
errors: [
98+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
99+
],
100+
},
101+
{
102+
code: '// test["skip"]("foo", function () {})',
103+
errors: [
104+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
105+
],
106+
},
107+
{
108+
code: '// xdescribe("foo", function () {})',
109+
errors: [
110+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
111+
],
112+
},
113+
{
114+
code: '// xit("foo", function () {})',
115+
errors: [
116+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
117+
],
118+
},
119+
{
120+
code: '// fit("foo", function () {})',
121+
errors: [
122+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
123+
],
124+
},
125+
{
126+
code: '// xtest("foo", function () {})',
127+
errors: [
128+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
129+
],
130+
},
131+
{
132+
code: `// test(
133+
// "foo", function () {}
134+
// )`,
135+
errors: [
136+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
137+
],
138+
},
139+
{
140+
code: `/* test
141+
(
142+
"foo", function () {}
143+
)
144+
*/`,
145+
errors: [
146+
{ message: 'Some tests seem to be commented', column: 1, line: 1 },
147+
],
148+
},
149+
{
150+
code: '// it("has title but no callback")',
151+
errors: [
152+
{
153+
message: 'Some tests seem to be commented',
154+
column: 1,
155+
line: 1,
156+
},
157+
],
158+
},
159+
{
160+
code: '// it()',
161+
errors: [
162+
{
163+
message: 'Some tests seem to be commented',
164+
column: 1,
165+
line: 1,
166+
},
167+
],
168+
},
169+
{
170+
code: '// test.someNewMethodThatMightBeAddedInTheFuture()',
171+
errors: [
172+
{
173+
message: 'Some tests seem to be commented',
174+
column: 1,
175+
line: 1,
176+
},
177+
],
178+
},
179+
{
180+
code: '// test["someNewMethodThatMightBeAddedInTheFuture"]()',
181+
errors: [
182+
{
183+
message: 'Some tests seem to be commented',
184+
column: 1,
185+
line: 1,
186+
},
187+
],
188+
},
189+
{
190+
code: '// test("has title but no callback")',
191+
errors: [
192+
{
193+
message: 'Some tests seem to be commented',
194+
column: 1,
195+
line: 1,
196+
},
197+
],
198+
},
199+
{
200+
code: `
201+
foo()
202+
/*
203+
describe("has title but no callback", () => {})
204+
*/
205+
bar()`,
206+
errors: [
207+
{
208+
message: 'Some tests seem to be commented',
209+
column: 7,
210+
line: 3,
211+
},
212+
],
213+
},
214+
],
215+
});

src/rules/no-commented-out-tests.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
3+
const { getDocsUrl } = require('./util');
4+
5+
const message = 'Some tests seem to be commented';
6+
7+
function hasTests(node) {
8+
return /(x|f)?(test|it|describe)(\.\w+|\[['"]\w+['"]\])?\s*\(/m.test(
9+
node.value,
10+
);
11+
}
12+
13+
module.exports = {
14+
meta: {
15+
docs: {
16+
url: getDocsUrl(__filename),
17+
},
18+
},
19+
create(context) {
20+
const sourceCode = context.getSourceCode();
21+
22+
function checkNode(node) {
23+
if (!hasTests(node)) return;
24+
25+
context.report({
26+
message,
27+
node,
28+
});
29+
}
30+
31+
return {
32+
Program() {
33+
const comments = sourceCode.getAllComments();
34+
35+
comments.filter(token => token.type !== 'Shebang').forEach(checkNode);
36+
},
37+
};
38+
},
39+
};

0 commit comments

Comments
 (0)