Skip to content

Commit 470deee

Browse files
Florian Breischsindresorhus
Florian Breisch
authored andcommitted
Add fixer for the no-only-test rule (#173)
1 parent 74e97cd commit 470deee

File tree

4 files changed

+65
-3
lines changed

4 files changed

+65
-3
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ The rules will only activate in test files.
7676
- [no-ignored-test-files](docs/rules/no-ignored-test-files.md) - Ensure no tests are written in ignored files.
7777
- [no-invalid-end](docs/rules/no-invalid-end.md) - Ensure `t.end()` is only called inside `test.cb()`.
7878
- [no-nested-tests](docs/rules/no-nested-tests.md) - Ensure no tests are nested.
79-
- [no-only-test](docs/rules/no-only-test.md) - Ensure no `test.only()` are present.
79+
- [no-only-test](docs/rules/no-only-test.md) - Ensure no `test.only()` are present. *(fixable)*
8080
- [no-skip-assert](docs/rules/no-skip-assert.md) - Ensure no assertions are skipped.
8181
- [no-skip-test](docs/rules/no-skip-test.md) - Ensure no tests are skipped.
8282
- [no-statement-after-end](docs/rules/no-statement-after-end.md) - Ensure `t.end()` is the last statement executed.

rules/no-only-test.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22
const visitIf = require('enhance-visitors').visitIf;
33
const createAvaRule = require('../create-ava-rule');
4+
const getTestModifier = require('../util').getTestModifier;
45

56
const create = context => {
67
const ava = createAvaRule();
@@ -13,7 +14,18 @@ const create = context => {
1314
if (ava.hasTestModifier('only')) {
1415
context.report({
1516
node,
16-
message: '`test.only()` should not be used.'
17+
message: '`test.only()` should not be used.',
18+
fix: fixer => {
19+
const range = getTestModifier(node, 'only').range.slice();
20+
const source = context.getSourceCode().getText();
21+
let dotPosition = range[0] - 1;
22+
while (source.charAt(dotPosition) !== '.') {
23+
dotPosition -= 1;
24+
}
25+
let snippet = source.substring(dotPosition, range[1]);
26+
snippet = snippet.replace(/\.|only/g, '');
27+
return fixer.replaceTextRange([dotPosition, range[1]], snippet);
28+
}
1729
});
1830
}
1931
})
@@ -22,5 +34,7 @@ const create = context => {
2234

2335
module.exports = {
2436
create,
25-
meta: {}
37+
meta: {
38+
fixable: 'code'
39+
}
2640
};

test/no-only-test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import rule from '../rules/no-only-test';
55
const ruleTester = avaRuleTester(test, {
66
env: {
77
es6: true
8+
},
9+
parserOptions: {
10+
sourceType: 'module'
811
}
912
});
1013

@@ -21,16 +24,49 @@ ruleTester.run('no-only-test', rule, {
2124
'test.only(t => {});'
2225
],
2326
invalid: [
27+
{
28+
code: header + 'test\n\t.only(t => { t.pass(); });',
29+
output: header + 'test\n\t(t => { t.pass(); });',
30+
errors
31+
},
32+
{
33+
code: header + 'test\n .only(t => { t.pass(); });',
34+
output: header + 'test\n (t => { t.pass(); });',
35+
errors
36+
},
37+
{
38+
code: header + 'test\t.only(t => { t.pass(); });',
39+
output: header + 'test\t(t => { t.pass(); });',
40+
errors
41+
},
42+
{
43+
code: header + 'test .only(t => { t.pass(); });',
44+
output: header + 'test (t => { t.pass(); });',
45+
errors
46+
},
47+
{
48+
code: header + 'test.\n\tonly(t => { t.pass(); });',
49+
output: header + 'test\n\t(t => { t.pass(); });',
50+
errors
51+
},
52+
{
53+
code: header + 'test.\n only(t => { t.pass(); });',
54+
output: header + 'test\n (t => { t.pass(); });',
55+
errors
56+
},
2457
{
2558
code: header + 'test.only(t => { t.pass(); });',
59+
output: header + 'test(t => { t.pass(); });',
2660
errors
2761
},
2862
{
2963
code: header + 'test.cb.only(t => { t.pass(); t.end(); });',
64+
output: header + 'test.cb(t => { t.pass(); t.end(); });',
3065
errors
3166
},
3267
{
3368
code: header + 'test.only.cb(t => { t.pass(); t.end(); });',
69+
output: header + 'test.cb(t => { t.pass(); t.end(); });',
3470
errors
3571
}
3672
]

util.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ exports.getTestModifiers = function getTestModifiers(node) {
5353
return [];
5454
};
5555

56+
exports.getTestModifier = function getTestModifier(node, mod) {
57+
if (node.type === 'CallExpression') {
58+
return getTestModifier(node.callee, mod);
59+
} else if (node.type === 'MemberExpression') {
60+
if (node.property.type === 'Identifier' && node.property.name === mod) {
61+
return node.property;
62+
}
63+
64+
return getTestModifier(node.object, mod);
65+
}
66+
};
67+
5668
const getMembers = node => {
5769
const name = node.property.name;
5870

0 commit comments

Comments
 (0)