Repository: ota-meshi/eslint-plugin-svelte (ts)

Issue:
no-trailing-spaces "ignoreComments: true" displays error in html comments
### Before You File a Bug Report Please Confirm You Have Done The Following...

- [X] I have tried restarting my IDE and the issue persists.
- [X] I have updated to the latest version of the packages.

### What version of ESLint are you using?

8.17.0

### What version of `eslint-plugin-svelte` are you using?

2.6.0

### What did you do?

<details>
<summary>Configuration</summary>

```
{
  "extends": ["prettier", "standard"],
  "plugins": ["@typescript-eslint"],
  "parser": "@typescript-eslint/parser",
  "rules": {
    "arrow-parens": ["error", "as-needed"],
    "operator-linebreak": ["error", "before"],
    "no-trailing-spaces": [
      "error",
      {
        "ignoreComments": true
      }
    ]
  },
  "overrides": [
    {
      "files": ["*.svelte"],
      "parser": "svelte-eslint-parser",
      "rules": {
        "import/first": 0,
        "import/no-duplicates": 0,
        "import/no-mutable-exports": 0,
        "import/no-unresolved": 0,
        "import/prefer-default-export": 0,
        "eslint-plugin-html": 0,
        "no-multiple-empty-lines": 0
      }
    }
  ],
  "env": {
    "node": true
  }
}

```
</details>

In my component, I have a code comment with 2 empty spaces at the end if the first line: `...blends in with paragraph  ` in order to support line-breaks when hovering the component and viewing its description.

```svelte
<!-- @component
  InlineButton - A button that blends in with paragraph  
  styles, but is interactive.
-->
<button>
  <slot />
</button>
```


### What did you expect to happen?

I would hope ESLint would be ok with it, given my config. No errors appear in my `.js` files.

### What actually happened?

Trailing spaces not allowed. eslint([no-trailing-spaces](https://eslint.org/docs/rules/no-trailing-spaces))

### Link to Minimal Reproducible Example

[https://ota-meshi.github.io/eslint-plugin-svelte/playground/#shortenedhash](https://ota-meshi.github.io/eslint-plugin-svelte/playground/#eJx1VsuS3DYM/BVF52VclePWeivJLf8wF4qCJGYoUuZjZmSX/90N6q0ZH7ZW7AZBEGiA86NUrqbyvfz4Q4jib+X6wVmy8WKL4j9rtKV/U4zOFqL4p6imz9jJWFSGbB0KDTu2vevYFYP0svVy6IoQR0PhjXcUmq0ieamivtGfFyvE58V+LM7Ggb5eyml1KT/Z2UcwLhZf2OrLRHyWb6VPcFm+/yjDjUykmRGdDIKdlO9/vS0UrtHjEqLWnvKpe7LRPkQhY/QaLkjwJStP8ro36mJvhDIuaNuKCrFfKYowSIX1k9235CKHdoIDmWbxsSe1rRHcHunlYwsoiIF8jupgkkKUqqNXQViH3aKmKrUiyjY8czmeF1SdBhJkAgndiMo4dX1pkcspBu8QWdT0ZDNa2WsluGwCn3Ti6RG9FEhxroVQyZtnJ9paXLsmZaCiqJ09G1g4b5JVzKHqtjbkTyau+h/1hisRcaZYcnb2tEayuPutgdEsXHPmQ+d85BCOmRmFu5H3un46kYuGwkrvEjbRtyQhD93awLGulT9titK3UF1lpL2eqGSv1t3tfPwq8zWQJ/MUCMFmQOBc58+HwQDtFV7nbPDUoDgoDSxeNtVscYpnb+Fxa+DCDVH3+jstuXt5+8U4RETKSdKHftny/3L3Rr+MJIDdtduB4jrVU7vMQ+RAjyFSv0du0uiaTQdtpkMU5BR9UohcBDTPpNEGqzkYZzOC0kJbkFpMfkK4VcNoFVex1+hJepBK8LOwSgJ86hAmcmHwh9KuGGKSSKGlVnwn7zac03YytTwRnzGJGcr2eo16YqJ3BpG39FjAPHxa8tvaEKR2kxvCgwSKDgdgirynviJ/ZOapdMCuNO6NjFYSh3BaFpT6YVb/shCqk/z2LPo9koPkKqx3o8cpDdPoqpwzJC2fFI9MoF4vSCONiR1avO1WCAPm5LE1rkL3H0GNZ9efS6DtpK6c6GFFPdYJEhD3DtMpK3bh8NYE4RoIiJQOu5pBTrhAzY/Zb9LR6we35DynIJEoq5W0dBdh7CtnVsRZpyLuATnqHv8pKDmsgWAQI1nGrB6y8bKAvqPjN1tUSZuoNyF7muRNG4C7z2EtWH5Xj6kKr5opdLJ2d4DoR40b1/lt2tygPQJL0stNVbHTQVSEdqVd9+YRWlOzLVAQyi77hAusj3Xm+PXoZGV2UJANXhttkZLxhKI/5b69ZpjHpIM91wvjb37wt1luZEVbemcQ7bZB80Cv8NslD2eym1AWEv2jujN4LCX/ssvfy0weNZk6I4k7NFg5xT6Jlcvq1kShRTg57VbBnz9/AdbxqQU=)

In the playground, the `no-trailing-spaces` rule only has "on" or "off" functionality, without me able to include the `"ignoreComments": true` config.

### Additional comments

I've had good success with this linting tool while programming in Svelte. Thank you for maintaining!

Pull request:
feat: add `svelte/no-trailing-spaces` rule
This PR adds `svelte/no-trailing-spaces` rule that extends [no-trailing-spaces] rule.
close #233


[no-trailing-spaces]: https://eslint.org/docs/rules/no-trailing-spaces

Patch:
diff --git a/.changeset/curly-tigers-destroy.md b/.changeset/curly-tigers-destroy.md
new file mode 100644
index 0000000..90be91b
--- /dev/null
+++ b/.changeset/curly-tigers-destroy.md
@@ -0,0 +1,5 @@
+---
+"eslint-plugin-svelte": minor
+---
+
+feat: add `svelte/no-trailing-spaces` rule
diff --git a/docs/rules.md b/docs/rules.md
index cec9eb3..97379b6 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -79,6 +79,7 @@ These rules extend the rules provided by ESLint itself to work well in Svelte:
 | Rule ID | Description |    |
 |:--------|:------------|:---|
 | [svelte/no-inner-declarations](./rules/no-inner-declarations.md) | disallow variable or `function` declarations in nested blocks | :star: |
+| [svelte/no-trailing-spaces](./rules/no-trailing-spaces.md) | disallow trailing whitespace at the end of lines | :wrench: |
 
 ## System
 
diff --git a/docs/rules/no-trailing-spaces.md b/docs/rules/no-trailing-spaces.md
new file mode 100644
index 0000000..7a5bc25
--- /dev/null
+++ b/docs/rules/no-trailing-spaces.md
@@ -0,0 +1,83 @@
+---
+pageClass: "rule-details"
+sidebarDepth: 0
+title: "svelte/no-trailing-spaces"
+description: "disallow trailing whitespace at the end of lines"
+---
+
+# svelte/no-trailing-spaces
+
+> disallow trailing whitespace at the end of lines
+
+- :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 extends the base ESLint's [no-trailing-spaces] rule. The [no-trailing-spaces] rule does not understand HTML comments and will report trailing whitespace in HTML comments when using `ignoreComments` option.
+This rule supports HTML comments generated by [svelte-eslint-parser].
+
+[svelte-eslint-parser]: https://github.com/ota-meshi/svelte-eslint-parser
+
+<ESLintCodeBlock fix>
+
+<!-- prettier-ignore-start -->
+<!--eslint-skip-->
+
+```svelte
+<script>
+  /* eslint svelte/no-trailing-spaces: "error" */
+
+  /* ✓ GOOD */
+  var foo = 0;
+  /* ✗ BAD */
+  var foo = 0;  
+</script>
+
+<!-- ✓ GOOD -->
+<div>
+  Text
+</div>
+
+<!-- ✗ BAD -->
+<div>  
+  Text  
+</div>
+```
+
+<!-- prettier-ignore-end -->
+
+</ESLintCodeBlock>
+
+## :wrench: Options
+
+```jsonc
+{
+  "no-trailing-spaces": "off", // Don't need ESLint's no-trailing-spaces rule, so turn it off.
+  "svelte/no-trailing-spaces": [
+    "error",
+    {
+      "skipBlankLines": false,
+      "ignoreComments": false
+    }
+  ]
+}
+```
+
+- `skipBlankLines` ... If `true`, allows trailing whitespace on empty lines.
+- `ignoreComments` ... If `true`, allows trailing whitespace in comments.
+
+Same as [no-trailing-spaces] rule option. See [here](https://eslint.org/docs/rules/no-trailing-spaces#options) for details.
+
+## :couple: Related rules
+
+- [no-trailing-spaces]
+
+[no-trailing-spaces]: https://eslint.org/docs/rules/no-trailing-spaces
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-trailing-spaces.ts)
+- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/no-trailing-spaces.ts)
+
+<sup>Taken with ❤️ [from ESLint core](https://eslint.org/docs/rules/no-trailing-spaces)</sup>
diff --git a/src/configs/prettier.ts b/src/configs/prettier.ts
index 20ea0c6..f33faf0 100644
--- a/src/configs/prettier.ts
+++ b/src/configs/prettier.ts
@@ -14,6 +14,7 @@ export = {
     "svelte/max-attributes-per-line": "off",
     "svelte/mustache-spacing": "off",
     "svelte/no-spaces-around-equal-signs-in-attribute": "off",
+    "svelte/no-trailing-spaces": "off",
     "svelte/shorthand-attribute": "off",
     "svelte/shorthand-directive": "off",
   },
diff --git a/src/rules/no-trailing-spaces.ts b/src/rules/no-trailing-spaces.ts
new file mode 100644
index 0000000..367530d
--- /dev/null
+++ b/src/rules/no-trailing-spaces.ts
@@ -0,0 +1,104 @@
+import type { AST } from "svelte-eslint-parser"
+import { createRule } from "../utils"
+
+export default createRule("no-trailing-spaces", {
+  meta: {
+    type: "layout",
+    docs: {
+      description: "disallow trailing whitespace at the end of lines",
+      category: "Extension Rules",
+      recommended: false,
+      extensionRule: "no-trailing-spaces",
+      conflictWithPrettier: true,
+    },
+    fixable: "whitespace",
+    schema: [
+      {
+        type: "object",
+        properties: {
+          skipBlankLines: { type: "boolean" },
+          ignoreComments: { type: "boolean" },
+        },
+        additionalProperties: false,
+      },
+    ],
+    messages: {
+      trailingSpace: "Trailing spaces not allowed.",
+    },
+  },
+  create(context) {
+    const options:
+      | { skipBlankLines?: boolean; ignoreComments?: boolean }
+      | undefined = context.options[0]
+    const skipBlankLines = options?.skipBlankLines || false
+    const ignoreComments = options?.ignoreComments || false
+
+    const sourceCode = context.getSourceCode()
+
+    const ignoreLineNumbers = new Set<number>()
+    if (ignoreComments) {
+      for (const { type, loc } of sourceCode.getAllComments()) {
+        const endLine = type === "Block" ? loc.end.line - 1 : loc.end.line
+        for (let i = loc.start.line; i <= endLine; i++) {
+          ignoreLineNumbers.add(i)
+        }
+      }
+    }
+
+    /**
+     * Reports a given location.
+     */
+    function report(loc: AST.SourceLocation) {
+      context.report({
+        loc,
+        messageId: "trailingSpace",
+        fix(fixer) {
+          return fixer.removeRange([
+            sourceCode.getIndexFromLoc(loc.start),
+            sourceCode.getIndexFromLoc(loc.end),
+          ])
+        },
+      })
+    }
+
+    /**
+     * Collects the location of the given node as the ignore line numbers.
+     */
+    function collectIgnoreLineNumbers({ loc }: { loc: AST.SourceLocation }) {
+      const endLine = loc.end.line - 1
+      for (let i = loc.start.line; i <= endLine; i++) {
+        ignoreLineNumbers.add(i)
+      }
+    }
+
+    return {
+      TemplateElement: collectIgnoreLineNumbers,
+      ...(ignoreComments
+        ? {
+            SvelteHTMLComment: collectIgnoreLineNumbers,
+          }
+        : {}),
+      "Program:exit"() {
+        const lines = sourceCode.lines
+        for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
+          const line = lines[lineIndex]
+          if (skipBlankLines && !line.trim()) {
+            continue
+          }
+          const lineNumber = lineIndex + 1
+          if (ignoreLineNumbers.has(lineNumber)) {
+            continue
+          }
+          const trimmed = line.trimEnd()
+          if (trimmed === line) {
+            continue
+          }
+          report({
+            start: { line: lineNumber, column: trimmed.length },
+            end: { line: lineNumber, column: line.length },
+          })
+        }
+      },
+    }
+  },
+})
diff --git a/src/utils/rules.ts b/src/utils/rules.ts
index 06382d3..9efb8fc 100644
--- a/src/utils/rules.ts
+++ b/src/utils/rules.ts
@@ -23,6 +23,7 @@ import noShorthandStylePropertyOverrides from "../rules/no-shorthand-style-prope
 import noSpacesAroundEqualSignsInAttribute from "../rules/no-spaces-around-equal-signs-in-attribute"
 import noStoreAsync from "../rules/no-store-async"
 import noTargetBlank from "../rules/no-target-blank"
+import noTrailingSpaces from "../rules/no-trailing-spaces"
 import noUnknownStyleDirectiveProperty from "../rules/no-unknown-style-directive-property"
 import noUnusedSvelteIgnore from "../rules/no-unused-svelte-ignore"
 import noUselessMustaches from "../rules/no-useless-mustaches"
@@ -62,6 +63,7 @@ export const rules = [
   noSpacesAroundEqualSignsInAttribute,
   noStoreAsync,
   noTargetBlank,
+  noTrailingSpaces,
   noUnknownStyleDirectiveProperty,
   noUnusedSvelteIgnore,
   noUselessMustaches,


Test patch:
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/_config.json b/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/_config.json
new file mode 100644
index 0000000..6010186
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/_config.json
@@ -0,0 +1,7 @@
+{
+  "options": [
+    {
+      "ignoreComments": true
+    }
+  ]
+}
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-errors.yaml b/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-errors.yaml
new file mode 100644
index 0000000..efd882a
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-errors.yaml
@@ -0,0 +1,36 @@
+- message: Trailing spaces not allowed.
+  line: 5
+  column: 2
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 9
+  column: 6
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 14
+  column: 1
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 23
+  column: 12
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 26
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 27
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 30
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 33
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 34
+  column: 23
+  suggestions: null
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-input.svelte b/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-input.svelte
new file mode 100644
index 0000000..560ca02
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-input.svelte
@@ -0,0 +1,35 @@
+<!-- prettier-ignore -->
+<script>
+  const str = `
+  
+`  
+  // line comment  
+  /**  
+   * block comment  
+   */  
+  /**
+   * block comment2  
+   */ const a = 42
+  // empty line
+  
+  // empty line
+</script>
+
+<!--  
+  HTML comment  
+  -->
+
+<!-- prettier-ignore -->
+<span> Text  
+</span>
+<!-- prettier-ignore -->
+<span>  
+  Text  
+</span>
+<!-- prettier-ignore -->
+<span>  
+  Text </span>
+<!-- prettier-ignore -->
+<span>  
+    <span>Text </span>  
+  </span>
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-output.svelte b/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-output.svelte
new file mode 100644
index 0000000..fd532b4
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/ignoreComments/test01-output.svelte
@@ -0,0 +1,35 @@
+<!-- prettier-ignore -->
+<script>
+  const str = `
+  
+`
+  // line comment  
+  /**  
+   * block comment  
+   */
+  /**
+   * block comment2  
+   */ const a = 42
+  // empty line
+
+  // empty line
+</script>
+
+<!--  
+  HTML comment  
+  -->
+
+<!-- prettier-ignore -->
+<span> Text
+</span>
+<!-- prettier-ignore -->
+<span>
+  Text
+</span>
+<!-- prettier-ignore -->
+<span>
+  Text </span>
+<!-- prettier-ignore -->
+<span>
+    <span>Text </span>
+  </span>
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/_config.json b/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/_config.json
new file mode 100644
index 0000000..2d8ee36
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/_config.json
@@ -0,0 +1,7 @@
+{
+  "options": [
+    {
+      "skipBlankLines": true
+    }
+  ]
+}
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-errors.yaml b/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-errors.yaml
new file mode 100644
index 0000000..8cbaf81
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-errors.yaml
@@ -0,0 +1,56 @@
+- message: Trailing spaces not allowed.
+  line: 5
+  column: 2
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 6
+  column: 18
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 7
+  column: 6
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 8
+  column: 19
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 9
+  column: 6
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 11
+  column: 20
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 18
+  column: 5
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 19
+  column: 15
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 23
+  column: 12
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 26
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 27
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 30
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 33
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 34
+  column: 23
+  suggestions: null
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-input.svelte b/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-input.svelte
new file mode 100644
index 0000000..560ca02
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-input.svelte
@@ -0,0 +1,35 @@
+<!-- prettier-ignore -->
+<script>
+  const str = `
+  
+`  
+  // line comment  
+  /**  
+   * block comment  
+   */  
+  /**
+   * block comment2  
+   */ const a = 42
+  // empty line
+  
+  // empty line
+</script>
+
+<!--  
+  HTML comment  
+  -->
+
+<!-- prettier-ignore -->
+<span> Text  
+</span>
+<!-- prettier-ignore -->
+<span>  
+  Text  
+</span>
+<!-- prettier-ignore -->
+<span>  
+  Text </span>
+<!-- prettier-ignore -->
+<span>  
+    <span>Text </span>  
+  </span>
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-output.svelte b/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-output.svelte
new file mode 100644
index 0000000..0ffc6b7
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/skipBlankLines/test01-output.svelte
@@ -0,0 +1,35 @@
+<!-- prettier-ignore -->
+<script>
+  const str = `
+  
+`
+  // line comment
+  /**
+   * block comment
+   */
+  /**
+   * block comment2
+   */ const a = 42
+  // empty line
+  
+  // empty line
+</script>
+
+<!--
+  HTML comment
+  -->
+
+<!-- prettier-ignore -->
+<span> Text
+</span>
+<!-- prettier-ignore -->
+<span>
+  Text
+</span>
+<!-- prettier-ignore -->
+<span>
+  Text </span>
+<!-- prettier-ignore -->
+<span>
+    <span>Text </span>
+  </span>
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/test01-errors.yaml b/tests/fixtures/rules/no-trailing-spaces/invalid/test01-errors.yaml
new file mode 100644
index 0000000..5aecca0
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/test01-errors.yaml
@@ -0,0 +1,60 @@
+- message: Trailing spaces not allowed.
+  line: 5
+  column: 2
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 6
+  column: 18
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 7
+  column: 6
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 8
+  column: 19
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 9
+  column: 6
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 11
+  column: 20
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 14
+  column: 1
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 18
+  column: 5
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 19
+  column: 15
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 23
+  column: 12
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 26
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 27
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 30
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 33
+  column: 7
+  suggestions: null
+- message: Trailing spaces not allowed.
+  line: 34
+  column: 23
+  suggestions: null
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/test01-input.svelte b/tests/fixtures/rules/no-trailing-spaces/invalid/test01-input.svelte
new file mode 100644
index 0000000..560ca02
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/test01-input.svelte
@@ -0,0 +1,35 @@
+<!-- prettier-ignore -->
+<script>
+  const str = `
+  
+`  
+  // line comment  
+  /**  
+   * block comment  
+   */  
+  /**
+   * block comment2  
+   */ const a = 42
+  // empty line
+  
+  // empty line
+</script>
+
+<!--  
+  HTML comment  
+  -->
+
+<!-- prettier-ignore -->
+<span> Text  
+</span>
+<!-- prettier-ignore -->
+<span>  
+  Text  
+</span>
+<!-- prettier-ignore -->
+<span>  
+  Text </span>
+<!-- prettier-ignore -->
+<span>  
+    <span>Text </span>  
+  </span>
diff --git a/tests/fixtures/rules/no-trailing-spaces/invalid/test01-output.svelte b/tests/fixtures/rules/no-trailing-spaces/invalid/test01-output.svelte
new file mode 100644
index 0000000..ff13f70
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/invalid/test01-output.svelte
@@ -0,0 +1,35 @@
+<!-- prettier-ignore -->
+<script>
+  const str = `
+  
+`
+  // line comment
+  /**
+   * block comment
+   */
+  /**
+   * block comment2
+   */ const a = 42
+  // empty line
+
+  // empty line
+</script>
+
+<!--
+  HTML comment
+  -->
+
+<!-- prettier-ignore -->
+<span> Text
+</span>
+<!-- prettier-ignore -->
+<span>
+  Text
+</span>
+<!-- prettier-ignore -->
+<span>
+  Text </span>
+<!-- prettier-ignore -->
+<span>
+    <span>Text </span>
+  </span>
diff --git a/tests/fixtures/rules/no-trailing-spaces/valid/test01-input.svelte b/tests/fixtures/rules/no-trailing-spaces/valid/test01-input.svelte
new file mode 100644
index 0000000..0cef4d6
--- /dev/null
+++ b/tests/fixtures/rules/no-trailing-spaces/valid/test01-input.svelte
@@ -0,0 +1,30 @@
+<script>
+  const str = `
+  
+`
+  // line comment
+  /**
+   * block comment
+   */
+  /**
+   * block comment2
+   */ const a = 42
+  // empty line
+
+  // empty line
+</script>
+
+<!--
+  HTML comment
+  -->
+
+<!-- prettier-ignore -->
+<span> Text
+</span>
+<!-- prettier-ignore -->
+<span>
+  Text
+</span>
+<!-- prettier-ignore -->
+<span>
+  Text </span>
diff --git a/tests/src/rules/no-trailing-spaces.ts b/tests/src/rules/no-trailing-spaces.ts
new file mode 100644
index 0000000..a8607d3
--- /dev/null
+++ b/tests/src/rules/no-trailing-spaces.ts
@@ -0,0 +1,16 @@
+import { RuleTester } from "eslint"
+import rule from "../../../src/rules/no-trailing-spaces"
+import { loadTestCases } from "../../utils/utils"
+
+const tester = new RuleTester({
+  parserOptions: {
+    ecmaVersion: 2020,
+    sourceType: "module",
+  },
+})
+
+tester.run(
+  "no-trailing-spaces",
+  rule as any,
+  loadTestCases("no-trailing-spaces"),
+)