Skip to content

Commit

Permalink
Add autofix to selector-list-comma-space-after (#3490)
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi authored and hudochenkov committed Aug 12, 2018
1 parent 2d496ad commit 7a2f199
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/user-guide/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ Here are all the rules within stylelint, grouped first [by category](../../VISIO

- [`selector-list-comma-newline-after`](../../lib/rules/selector-list-comma-newline-after/README.md): Require a newline or disallow whitespace after the commas of selector lists.
- [`selector-list-comma-newline-before`](../../lib/rules/selector-list-comma-newline-before/README.md): Require a newline or disallow whitespace before the commas of selector lists (Autofixable).
- [`selector-list-comma-space-after`](../../lib/rules/selector-list-comma-space-after/README.md): Require a single space or disallow whitespace after the commas of selector lists.
- [`selector-list-comma-space-after`](../../lib/rules/selector-list-comma-space-after/README.md): Require a single space or disallow whitespace after the commas of selector lists (Autofixable).
- [`selector-list-comma-space-before`](../../lib/rules/selector-list-comma-space-before/README.md): Require a single space or disallow whitespace before the commas of selector lists (Autofixable).

#### Rule
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/selector-list-comma-space-after/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Require a single space or disallow whitespace after the commas of selector lists
* The space after this comma */
```

The `--fix` option on the [command line](../../../docs/user-guide/cli.md#autofixing-errors) can automatically fix all of the problems reported by this rule.

## Options

`string`: `"always"|"never"|"always-single-line"|"never-single-line"`
Expand Down
40 changes: 40 additions & 0 deletions lib/rules/selector-list-comma-space-after/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const { messages, ruleName } = rule;
testRule(rule, {
ruleName,
config: ["always"],
fix: true,

accept: [
{
Expand Down Expand Up @@ -61,59 +62,75 @@ testRule(rule, {
reject: [
{
code: "a,b {}",
fixed: "a, b {}",
message: messages.expectedAfter(),
line: 1,
column: 2
},
{
code: "a, b {}",
fixed: "a, b {}",
message: messages.expectedAfter(),
line: 1,
column: 2
},
{
code: "a,\nb {}",
fixed: "a, b {}",
message: messages.expectedAfter(),
line: 1,
column: 2
},
{
code: "a,\r\nb {}",
fixed: "a, b {}",
description: "CRLF",
message: messages.expectedAfter(),
line: 1,
column: 2
},
{
code: "a,\tb {}",
fixed: "a, b {}",
message: messages.expectedAfter(),
line: 1,
column: 2
},
{
code: "a, b,c {}",
fixed: "a, b, c {}",
message: messages.expectedAfter(),
line: 1,
column: 5
},
{
code: "a, b, c {}",
fixed: "a, b, c {}",
message: messages.expectedAfter(),
line: 1,
column: 5
},
{
code: "a/*comment*/,/*comment*/b {}",
fixed: "a/*comment*/, /*comment*/b {}",
message: messages.expectedAfter(),
line: 1,
column: 13
},
{
code: "a,b,c {}",
fixed: "a, b, c {}",
message: messages.expectedAfter(),
line: 1,
column: 2
}
]
});

testRule(rule, {
ruleName,
config: ["never"],
fix: true,

accept: [
{
Expand Down Expand Up @@ -153,59 +170,75 @@ testRule(rule, {
reject: [
{
code: "a, b {}",
fixed: "a,b {}",
message: messages.rejectedAfter(),
line: 1,
column: 2
},
{
code: "a, b {}",
fixed: "a,b {}",
message: messages.rejectedAfter(),
line: 1,
column: 2
},
{
code: "a,\nb {}",
fixed: "a,b {}",
message: messages.rejectedAfter(),
line: 1,
column: 2
},
{
code: "a,\r\nb {}",
fixed: "a,b {}",
description: "CRLF",
message: messages.rejectedAfter(),
line: 1,
column: 2
},
{
code: "a,\tb {}",
fixed: "a,b {}",
message: messages.rejectedAfter(),
line: 1,
column: 2
},
{
code: "a,b, c {}",
fixed: "a,b,c {}",
message: messages.rejectedAfter(),
line: 1,
column: 4
},
{
code: "a,b, c {}",
fixed: "a,b,c {}",
message: messages.rejectedAfter(),
line: 1,
column: 4
},
{
code: "a/*comment*/, /*comment*/b {}",
fixed: "a/*comment*/,/*comment*/b {}",
message: messages.rejectedAfter(),
line: 1,
column: 13
},
{
code: "a, b, c {}",
fixed: "a,b,c {}",
message: messages.rejectedAfter(),
line: 1,
column: 2
}
]
});

testRule(rule, {
ruleName,
config: ["always-single-line"],
fix: true,

accept: [
{
Expand All @@ -224,18 +257,21 @@ testRule(rule, {
reject: [
{
code: "a,b {}",
fixed: "a, b {}",
message: messages.expectedAfterSingleLine(),
line: 1,
column: 2
},
{
code: "a,b {\n}",
fixed: "a, b {\n}",
message: messages.expectedAfterSingleLine(),
line: 1,
column: 2
},
{
code: "a,b {\r\n}",
fixed: "a, b {\r\n}",
description: "CRLF",
message: messages.expectedAfterSingleLine(),
line: 1,
Expand All @@ -247,6 +283,7 @@ testRule(rule, {
testRule(rule, {
ruleName,
config: ["never-single-line"],
fix: true,

accept: [
{
Expand All @@ -265,18 +302,21 @@ testRule(rule, {
reject: [
{
code: "a, b {}",
fixed: "a,b {}",
message: messages.rejectedAfterSingleLine(),
line: 1,
column: 2
},
{
code: "a, b {\n}",
fixed: "a,b {\n}",
message: messages.rejectedAfterSingleLine(),
line: 1,
column: 2
},
{
code: "a, b {\r\n}",
fixed: "a,b {\r\n}",
description: "CRLF",
message: messages.rejectedAfterSingleLine(),
line: 1,
Expand Down
40 changes: 38 additions & 2 deletions lib/rules/selector-list-comma-space-after/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const messages = ruleMessages(ruleName, {
'Unexpected whitespace after "," in a single-line list'
});

const rule = function(expectation) {
const rule = function(expectation, options, context) {
const checker = whitespaceChecker("space", expectation, messages);
return (root, result) => {
const validOptions = validateOptions(result, ruleName, {
Expand All @@ -27,12 +27,48 @@ const rule = function(expectation) {
return;
}

let fixData;

selectorListCommaWhitespaceChecker({
root,
result,
locationChecker: checker.after,
checkedRuleName: ruleName
checkedRuleName: ruleName,
fix: context.fix
? (ruleNode, index) => {
fixData = fixData || new Map();
const commaIndices = fixData.get(ruleNode) || [];
commaIndices.push(index);
fixData.set(ruleNode, commaIndices);
return true;
}
: null
});
if (fixData) {
fixData.forEach((commaIndices, ruleNode) => {
let selector = ruleNode.raws.selector
? ruleNode.raws.selector.raw
: ruleNode.selector;
commaIndices
.sort()
.reverse()
.forEach(index => {
const beforeSelector = selector.slice(0, index + 1);
let afterSelector = selector.slice(index + 1);
if (expectation.indexOf("always") === 0) {
afterSelector = afterSelector.replace(/^\s*/, " ");
} else if (expectation.indexOf("never") === 0) {
afterSelector = afterSelector.replace(/^\s*/, "");
}
selector = beforeSelector + afterSelector;
});
if (ruleNode.raws.selector) {
ruleNode.raws.selector.raw = selector;
} else {
ruleNode.selector = selector;
}
});
}
};
};

Expand Down

0 comments on commit 7a2f199

Please sign in to comment.