Skip to content

Commit

Permalink
feat: add no-trailing-zeros rule (#236)
Browse files Browse the repository at this point in the history
* feat: add `no-trailing-zeros` rule

* docs: add `no-trailing-zeros` doc

* chore: lint

* chore: remove unused schema

* fix: test

* docs: fix

* fix: revert to fix tests temporarily

* Revert "fix: revert to fix tests temporarily"

This reverts commit 9582fd1.

* Create sixty-cougars-ring.md

* add more tests & update docs

---------

Co-authored-by: Yosuke Ota <otameshiyo23@gmail.com>
  • Loading branch information
sxyazi and ota-meshi committed May 7, 2023
1 parent dc9edb1 commit 7e34b77
Show file tree
Hide file tree
Showing 12 changed files with 248 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/sixty-cougars-ring.md
@@ -0,0 +1,5 @@
---
"eslint-plugin-yml": minor
---

feat: add `yml/no-trailing-zeros` rule
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -207,6 +207,7 @@ The rules with the following star :star: are included in the config.
| [yml/no-empty-mapping-value](https://ota-meshi.github.io/eslint-plugin-yml/rules/no-empty-mapping-value.html) | disallow empty mapping values | | :star: | :star: |
| [yml/no-empty-sequence-entry](https://ota-meshi.github.io/eslint-plugin-yml/rules/no-empty-sequence-entry.html) | disallow empty sequence entries | | :star: | :star: |
| [yml/no-tab-indent](https://ota-meshi.github.io/eslint-plugin-yml/rules/no-tab-indent.html) | disallow tabs for indentation. | | :star: | :star: |
| [yml/no-trailing-zeros](https://ota-meshi.github.io/eslint-plugin-yml/rules/no-trailing-zeros.html) | disallow trailing zeros for floats | :wrench: | | |
| [yml/plain-scalar](https://ota-meshi.github.io/eslint-plugin-yml/rules/plain-scalar.html) | require or disallow plain style scalar. | :wrench: | | :star: |
| [yml/quotes](https://ota-meshi.github.io/eslint-plugin-yml/rules/quotes.html) | enforce the consistent use of either double, or single quotes | :wrench: | | :star: |
| [yml/require-string-key](https://ota-meshi.github.io/eslint-plugin-yml/rules/require-string-key.html) | disallow mapping keys other than strings | | | |
Expand Down
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -26,6 +26,7 @@ The rules with the following star :star: are included in the `plugin:yml/recomme
| [yml/no-empty-mapping-value](./no-empty-mapping-value.md) | disallow empty mapping values | | :star: | :star: |
| [yml/no-empty-sequence-entry](./no-empty-sequence-entry.md) | disallow empty sequence entries | | :star: | :star: |
| [yml/no-tab-indent](./no-tab-indent.md) | disallow tabs for indentation. | | :star: | :star: |
| [yml/no-trailing-zeros](./no-trailing-zeros.md) | disallow trailing zeros for floats | :wrench: | | |
| [yml/plain-scalar](./plain-scalar.md) | require or disallow plain style scalar. | :wrench: | | :star: |
| [yml/quotes](./quotes.md) | enforce the consistent use of either double, or single quotes | :wrench: | | :star: |
| [yml/require-string-key](./require-string-key.md) | disallow mapping keys other than strings | | | |
Expand Down
43 changes: 43 additions & 0 deletions docs/rules/no-trailing-zeros.md
@@ -0,0 +1,43 @@
---
pageClass: "rule-details"
sidebarDepth: 0
title: "yml/no-trailing-zeros"
description: "disallow trailing zeros for floats"
---

# yml/no-trailing-zeros

> disallow trailing zeros for floats
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge>
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.

## :book: Rule Details

This rule enforces the removal of unnecessary trailing zeros from floats.

<eslint-code-block fix>

<!-- eslint-skip -->

```yaml
# eslint yml/no-trailing-zeros: 'error'

# ✓ GOOD
"GOOD": 1.2

# ✗ BAD
'BAD': 1.20
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :mag: Implementation

- [Rule source](https://github.com/ota-meshi/eslint-plugin-yml/blob/master/src/rules/no-trailing-zeros.ts)
- [Test source](https://github.com/ota-meshi/eslint-plugin-yml/blob/master/tests/src/rules/no-trailing-zeros.ts)
- [Test fixture sources](https://github.com/ota-meshi/eslint-plugin-yml/tree/master/tests/fixtures/rules/no-trailing-zeros)
1 change: 1 addition & 0 deletions src/configs/prettier.ts
Expand Up @@ -15,6 +15,7 @@ export = {
"yml/indent": "off",
"yml/key-spacing": "off",
"yml/no-multiple-empty-lines": "off",
"yml/no-trailing-zeros": "off",
"yml/quotes": "off",
},
};
57 changes: 57 additions & 0 deletions src/rules/no-trailing-zeros.ts
@@ -0,0 +1,57 @@
import type { AST } from "yaml-eslint-parser";
import { createRule } from "../utils";

export default createRule("no-trailing-zeros", {
meta: {
docs: {
description: "disallow trailing zeros for floats",
categories: null,
extensionRule: false,
layout: true,
},
fixable: "code",
schema: [],
messages: {
wrongZeros: "Trailing zeros are not allowed, fix to `{{fixed}}`.",
},
type: "layout",
},
create(context) {
if (!context.parserServices.isYAML) {
return {};
}

return {
YAMLScalar(node: AST.YAMLScalar) {
if (node.style !== "plain") {
return;
} else if (typeof node.value !== "number") {
return;
} else if (!node.strValue.endsWith("0")) {
return;
}

const parts = node.strValue.split(".");
if (parts.length !== 2) {
return;
}

while (parts[1].endsWith("0")) {
parts[1] = parts[1].slice(0, -1);
}
const fixed = parts[1] ? parts.join(".") : parts[0] || "0";

context.report({
node,
messageId: "wrongZeros",
data: {
fixed,
},
fix(fixer) {
return fixer.replaceText(node, fixed);
},
});
},
};
},
});
2 changes: 2 additions & 0 deletions src/utils/rules.ts
Expand Up @@ -19,6 +19,7 @@ import noEmptySequenceEntry from "../rules/no-empty-sequence-entry";
import noIrregularWhitespace from "../rules/no-irregular-whitespace";
import noMultipleEmptyLines from "../rules/no-multiple-empty-lines";
import noTabIndent from "../rules/no-tab-indent";
import noTrailingZeros from "../rules/no-trailing-zeros";
import plainScalar from "../rules/plain-scalar";
import quotes from "../rules/quotes";
import requireStringKey from "../rules/require-string-key";
Expand Down Expand Up @@ -48,6 +49,7 @@ export const rules = [
noIrregularWhitespace,
noMultipleEmptyLines,
noTabIndent,
noTrailingZeros,
plainScalar,
quotes,
requireStringKey,
Expand Down
62 changes: 62 additions & 0 deletions tests/fixtures/rules/no-trailing-zeros/invalid/errors.json
@@ -0,0 +1,62 @@
[
{
"message": "Trailing zeros are not allowed, fix to `1.2`.",
"line": 4,
"column": 10
},
{
"message": "Trailing zeros are not allowed, fix to `.2`.",
"line": 6,
"column": 10
},
{
"message": "Trailing zeros are not allowed, fix to `1`.",
"line": 7,
"column": 10
},
{
"message": "Trailing zeros are not allowed, fix to `0`.",
"line": 8,
"column": 10
},
{
"message": "Trailing zeros are not allowed, fix to `+1`.",
"line": 9,
"column": 10
},
{
"message": "Trailing zeros are not allowed, fix to `-1`.",
"line": 10,
"column": 10
},
{
"message": "Trailing zeros are not allowed, fix to `1.2`.",
"line": 14,
"column": 12
},
{
"message": "Trailing zeros are not allowed, fix to `.2`.",
"line": 16,
"column": 12
},
{
"message": "Trailing zeros are not allowed, fix to `1`.",
"line": 17,
"column": 12
},
{
"message": "Trailing zeros are not allowed, fix to `0`.",
"line": 18,
"column": 12
},
{
"message": "Trailing zeros are not allowed, fix to `+1`.",
"line": 19,
"column": 12
},
{
"message": "Trailing zeros are not allowed, fix to `-1`.",
"line": 20,
"column": 12
}
]
20 changes: 20 additions & 0 deletions tests/fixtures/rules/no-trailing-zeros/invalid/input.yml
@@ -0,0 +1,20 @@
# {"options": []}
- {
a: 1.23,
b: 1.20,
c: .23,
d: .20,
e: 1.0,
f: .0,
g: +1.0,
h: -1.0
}
-
- "a": 1.23
- "b": 1.20
- "c": .23
- "d": .20
- "e": 1.0
- "f": .0
- "g": +1.0
- "h": -1.0
20 changes: 20 additions & 0 deletions tests/fixtures/rules/no-trailing-zeros/invalid/output.yml
@@ -0,0 +1,20 @@
# no-trailing-zeros/invalid/input.yml
- {
a: 1.23,
b: 1.2,
c: .23,
d: .2,
e: 1,
f: 0,
g: +1,
h: -1
}
-
- "a": 1.23
- "b": 1.2
- "c": .23
- "d": .2
- "e": 1
- "f": 0
- "g": +1
- "h": -1
20 changes: 20 additions & 0 deletions tests/fixtures/rules/no-trailing-zeros/valid/input.yml
@@ -0,0 +1,20 @@
# {"options": []}
- {
a: 1.23,
b: "1.20",
c: .23,
d: .2,
e: "1.0",
f: ".0",
g: "+1.0",
h: "-1.0"
}
-
- "a": 1.23
- "b": "1.20"
- "c": .23
- "d": .2
- "e": "1.0"
- "f": ".0"
- "g": "+1.0"
- "h": "-1.0"
16 changes: 16 additions & 0 deletions tests/src/rules/no-trailing-zeros.ts
@@ -0,0 +1,16 @@
import { RuleTester } from "eslint";
import rule from "../../../src/rules/no-trailing-zeros";
import { loadTestCases } from "../../utils/utils";

const tester = new RuleTester({
parser: require.resolve("yaml-eslint-parser"),
parserOptions: {
ecmaVersion: 2020,
},
});

tester.run(
"no-trailing-zeros",
rule as any,
loadTestCases("no-trailing-zeros")
);

0 comments on commit 7e34b77

Please sign in to comment.