Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#2829] add autofix for number-no-trailing-zeros #2947

Merged
merged 1 commit into from
Oct 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/rules/number-no-trailing-zeros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ a { top: 0.5000px; bottom: 1.0px; }
* These trailing zeros */
```

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

## Options

### `true`
Expand Down
20 changes: 12 additions & 8 deletions lib/rules/number-no-trailing-zeros/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const rule = rules[ruleName];
testRule(rule, {
ruleName,
config: [true],

fix: true,
accept: [
{
code: "a { padding: 1px; }"
Expand Down Expand Up @@ -73,66 +73,70 @@ testRule(rule, {
reject: [
{
code: "a { padding: 1.0px; }",
fixed: "a { padding: 1px; }",
message: messages.rejected,
line: 1,
column: 16
},
{
code: "a { padding: 1.000px; }",
fixed: "a { padding: 1px; }",
message: messages.rejected,
line: 1,
column: 18
column: 16
},
{
code: "a { padding: 10.0px; }",
fixed: "a { padding: 10px; }",
message: messages.rejected,
line: 1,
column: 17
},
{
code: "a { padding: 10.010px; }",
message: messages.rejected,
line: 1,
column: 19
},
{
code: "a { padding: 10.010px; }",
fixed: "a { padding: 10.01px; }",
message: messages.rejected,
line: 1,
column: 19
},
{
code: "a { padding: 0.010px; }",
fixed: "a { padding: 0.01px; }",
message: messages.rejected,
line: 1,
column: 18
},
{
code: "a { padding: .010px; }",
fixed: "a { padding: .01px; }",
message: messages.rejected,
line: 1,
column: 17
},
{
code: "a { transform: translate(2px, 0.40px); }",
fixed: "a { transform: translate(2px, 0.4px); }",
message: messages.rejected,
line: 1,
column: 34
},
{
code: "a { padding: 10px 1px 10.010px 3.00003em; }",
fixed: "a { padding: 10px 1px 10.01px 3.00003em; }",
message: messages.rejected,
line: 1,
column: 28
},
{
code: "a { padding: 10px 1px 10.01px 3.000030em; }",
fixed: "a { padding: 10px 1px 10.01px 3.00003em; }",
message: messages.rejected,
line: 1,
column: 38
},
{
code: "@media (min-width: 100.0px) {}",
fixed: "@media (min-width: 100px) {}",
message: messages.rejected,
line: 1,
column: 24
Expand Down
71 changes: 57 additions & 14 deletions lib/rules/number-no-trailing-zeros/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const messages = ruleMessages(ruleName, {
rejected: "Unexpected trailing zero(s)"
});

const rule = function(actual) {
const rule = function(actual, secondary, context) {
return (root, result) => {
const validOptions = validateOptions(result, ruleName, { actual });
if (!validOptions) {
Expand All @@ -31,6 +31,8 @@ const rule = function(actual) {
root.walkDecls(decl => check(decl, decl.value, declarationValueIndex));

function check(node, value, getIndex) {
const fixPositions = [];

// Get out quickly if there are no periods
if (value.indexOf(".") === -1) {
return;
Expand All @@ -50,28 +52,69 @@ const rule = function(actual) {
return;
}

const match = /(\.\d*)0+(?:\D|$)/.exec(valueNode.value);

const match = /\.(\d*?)(0+)(?:\D|$)/.exec(valueNode.value);
// match[1] is any numbers between the decimal and our trailing zero, could be empty
// match[2] is our trailing zero(s)
if (match === null) {
return;
}

report({
message: messages.rejected,
node,
index:
getIndex(node) +
valueNode.sourceIndex +
match.index +
match[1].length,
result,
ruleName
});
// our index is:
// the index of our valueNode +
// the index of our match +
// 1 for our decimal +
// the length of our potential non-zero number match (match[1])
const index = valueNode.sourceIndex + match.index + 1 + match[1].length;

// our startIndex is identical to our index except when we have only
// trailing zeros after our decimal. in that case we don't need the decimal
// either so we move our index back by 1.
const startIndex = match[1].length > 0 ? index : index - 1;

// our end index is our original index + the length of our trailing zeros
const endIndex = index + match[2].length;

if (context.fix) {
fixPositions.unshift({
startIndex,
endIndex
});
return;
} else {
report({
message: messages.rejected,
node,
// this is the index of the _first_ trailing zero
index: getIndex(node) + index,
result,
ruleName
});
}
});

if (fixPositions.length) {
fixPositions.forEach(function(fixPosition) {
const startIndex = fixPosition.startIndex;
const endIndex = fixPosition.endIndex;
if (node.type === "atrule") {
node.params = removeTrailingZeros(
node.params,
startIndex,
endIndex
);
} else {
node.value = removeTrailingZeros(node.value, startIndex, endIndex);
}
});
}
}
};
};

function removeTrailingZeros(input, startIndex, endIndex) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe best place utils?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it used by more than rule? If so, then yes I agree. Otherwise, it's probably more helpful to maintainers to keep it here.

return input.slice(0, startIndex) + input.slice(endIndex);
}

rule.ruleName = ruleName;
rule.messages = messages;
module.exports = rule;