Skip to content

Commit cf1f140

Browse files
Florian Breischsindresorhus
Florian Breisch
authored andcommitted
Add fixer for no-skip-test rule (#183)
1 parent 8e5d631 commit cf1f140

File tree

5 files changed

+65
-12
lines changed

5 files changed

+65
-12
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ The rules will only activate in test files.
7878
- [no-nested-tests](docs/rules/no-nested-tests.md) - Ensure no tests are nested.
7979
- [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.
81-
- [no-skip-test](docs/rules/no-skip-test.md) - Ensure no tests are skipped.
81+
- [no-skip-test](docs/rules/no-skip-test.md) - Ensure no tests are skipped. *(fixable)*
8282
- [no-statement-after-end](docs/rules/no-statement-after-end.md) - Ensure `t.end()` is the last statement executed.
8383
- [no-todo-implementation](docs/rules/no-todo-implementation.md) - Ensure `test.todo()` is not given an implementation function.
8484
- [no-todo-test](docs/rules/no-todo-test.md) - Ensure no `test.todo()` is used.

rules/no-only-test.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,11 @@ const create = context => {
1717
node: propertyNode,
1818
message: '`test.only()` should not be used.',
1919
fix: fixer => {
20-
const range = propertyNode.range.slice();
21-
const source = context.getSourceCode().getText();
22-
let dotPosition = range[0] - 1;
23-
while (source.charAt(dotPosition) !== '.') {
24-
dotPosition -= 1;
25-
}
26-
let snippet = source.substring(dotPosition, range[1]);
27-
snippet = snippet.replace(/\.|only/g, '');
28-
return fixer.replaceTextRange([dotPosition, range[1]], snippet);
20+
return fixer.replaceTextRange.apply(null, util.removeTestModifier({
21+
modifier: 'only',
22+
node,
23+
context
24+
}));
2925
}
3026
});
3127
}

rules/no-skip-test.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@ const create = context => {
1515
if (propertyNode) {
1616
context.report({
1717
node: propertyNode,
18-
message: 'No tests should be skipped.'
18+
message: 'No tests should be skipped.',
19+
fix: fixer => {
20+
return fixer.replaceTextRange.apply(null, util.removeTestModifier({
21+
modifier: 'skip',
22+
node,
23+
context
24+
}));
25+
}
1926
});
2027
}
2128
})
@@ -24,5 +31,7 @@ const create = context => {
2431

2532
module.exports = {
2633
create,
27-
meta: {}
34+
meta: {
35+
fixable: 'code'
36+
}
2837
};

test/no-skip-test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ ruleTester.run('no-skip-test', rule, {
2525
invalid: [
2626
{
2727
code: header + 'test.skip(t => { t.pass(); });',
28+
output: header + 'test(t => { t.pass(); });',
2829
errors: [{
2930
ruleId,
3031
message,
@@ -35,6 +36,7 @@ ruleTester.run('no-skip-test', rule, {
3536
},
3637
{
3738
code: header + 'test.cb.skip(t => { t.pass(); t.end(); });',
39+
output: header + 'test.cb(t => { t.pass(); t.end(); });',
3840
errors: [{
3941
ruleId,
4042
message,
@@ -45,13 +47,36 @@ ruleTester.run('no-skip-test', rule, {
4547
},
4648
{
4749
code: header + 'test.skip.cb(t => { t.pass(); t.end(); });',
50+
output: header + 'test.cb(t => { t.pass(); t.end(); });',
4851
errors: [{
4952
ruleId,
5053
message,
5154
type: 'Identifier',
5255
line: 2,
5356
column: 6
5457
}]
58+
},
59+
{
60+
code: header + 'test.\n\tskip.cb(t => { t.pass(); t.end(); });',
61+
output: header + 'test\n\t.cb(t => { t.pass(); t.end(); });',
62+
errors: [{
63+
ruleId,
64+
message,
65+
type: 'Identifier',
66+
line: 3,
67+
column: 2
68+
}]
69+
},
70+
{
71+
code: header + 'test .skip .cb(t => { t.pass(); t.end(); });',
72+
output: header + 'test .cb(t => { t.pass(); t.end(); });',
73+
errors: [{
74+
ruleId,
75+
message,
76+
type: 'Identifier',
77+
line: 2,
78+
column: 8
79+
}]
5580
}
5681
]
5782
});

util.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,29 @@ exports.getTestModifier = (node, mod) => {
6060
return testModifiers.find(property => property.name === mod);
6161
};
6262

63+
/**
64+
* Removes given test-modifier from the source surrounding the given node
65+
*
66+
* @param {string} params.modifier - Name of the modifier
67+
* @param {Node} params.node - ESTree-node as provided by ESLint
68+
* @param {Context} params.context - ESLint-context as provided
69+
*
70+
* @return {Array} Compound parameters to be used as arguments for `fix.replaceTextRange()`
71+
*/
72+
exports.removeTestModifier = function (params) {
73+
const modifier = params.modifier.trim();
74+
const range = exports.getTestModifier(params.node, modifier).range.slice();
75+
const replacementRegExp = new RegExp(`\\.|${modifier}`, 'g');
76+
const source = params.context.getSourceCode().getText();
77+
let dotPosition = range[0] - 1;
78+
while (source.charAt(dotPosition) !== '.') {
79+
dotPosition -= 1;
80+
}
81+
let snippet = source.slice(dotPosition, range[1]);
82+
snippet = snippet.replace(replacementRegExp, '');
83+
return [[dotPosition, range[1]], snippet];
84+
};
85+
6386
const getMembers = node => {
6487
const name = node.property.name;
6588

0 commit comments

Comments
 (0)