Repository: typescript-eslint/tslint-to-eslint-config (ts)

Issue:
Missing converter: no-trailing-whitespace
### 💥 Missing Converter

-   `tslint-to-eslint-config` version: 1.2.0
-   `typescript-eslint` version: 2.3.2

#### TSLint Rule Name

`no-trailing-whitespace`


Pull request:
added no-trailing-whitespace converter and unit tests
<!--
👋 Hi, thanks for sending a PR to tslint-to-eslint-config! 💖
Please fill out all fields below to ensure your PR is reviewed quickly.
-->

## PR Checklist

-   [x] Addresses an existing issue: fixes #176 
-   [x] That issue was marked as [`status: accepting prs`](https://github.com/typescript-eslint/tslint-to-eslint-config/labels/status%3A%20accepting%20prs)

## Overview
Added converter and unit tests for no-trailing-whitespace.

<!-- Brief description of what is changed and how the code change does that. -->


Patch:
diff --git a/src/rules/converters.ts b/src/rules/converters.ts
index f98b219..34aa4f8 100644
--- a/src/rules/converters.ts
+++ b/src/rules/converters.ts
@@ -45,6 +45,7 @@ import { convertNoEmptyInterface } from "./converters/no-empty-interface";
 import { convertNoEval } from "./converters/no-eval";
 import { convertNoExplicitAny } from "./converters/no-explicit-any";
 import { convertNoFloatingPromises } from "./converters/no-floating-promises";
+import { convertNoForIn } from "./converters/no-for-in";
 import { convertNoForInArray } from "./converters/no-for-in-array";
 import { convertNoInferrableTypes } from "./converters/no-inferrable-types";
 import { convertNoInternalModule } from "./converters/no-internal-module";
@@ -70,6 +71,7 @@ import { convertNoStringLiteral } from "./converters/no-string-literal";
 import { convertNoStringThrow } from "./converters/no-string-throw";
 import { convertNoSwitchCaseFallThrough } from "./converters/no-switch-case-fall-through";
 import { convertNoThisAssignment } from "./converters/no-this-assignment";
+import { convertNoTrailingWhitespace } from "./converters/no-trailing-whitespace";
 import { convertNoUnboundMethod } from "./converters/no-unbound-method";
 import { convertNoUnnecessaryClass } from "./converters/no-unnecessary-class";
 import { convertNoUnnecessaryInitializer } from "./converters/no-unnecessary-initializer";
@@ -80,6 +82,7 @@ import { convertNoUnsafeFinally } from "./converters/no-unsafe-finally";
 import { convertNoUseBeforeDeclare } from "./converters/no-use-before-declare";
 import { convertNoVarKeyword } from "./converters/no-var-keyword";
 import { convertNoVarRequires } from "./converters/no-var-requires";
+import { convertNoVoidExpression } from "./converters/no-void-expression";
 import { convertObjectLiteralKeyQuotes } from "./converters/object-literal-key-quotes";
 import { convertObjectLiteralShorthand } from "./converters/object-literal-shorthand";
 import { convertOneVariablePerDeclaration } from "./converters/one-variable-per-declaration";
@@ -141,6 +144,7 @@ export const converters = new Map([
     ["no-empty-interface", convertNoEmptyInterface],
     ["no-eval", convertNoEval],
     ["no-floating-promises", convertNoFloatingPromises],
+    ["no-for-in", convertNoForIn],
     ["no-for-in-array", convertNoForInArray],
     ["no-inferrable-types", convertNoInferrableTypes],
     ["no-internal-module", convertNoInternalModule],
@@ -158,6 +162,7 @@ export const converters = new Map([
     ["no-string-literal", convertNoStringLiteral],
     ["no-string-throw", convertNoStringThrow],
     ["no-switch-case-fall-through", convertNoSwitchCaseFallThrough],
+    ["no-trailing-whitespace", convertNoTrailingWhitespace],
     ["no-this-assignment", convertNoThisAssignment],
     ["no-unbound-method", convertNoUnboundMethod],
     ["no-unnecessary-class", convertNoUnnecessaryClass],
@@ -168,6 +173,7 @@ export const converters = new Map([
     ["no-use-before-declare", convertNoUseBeforeDeclare],
     ["no-var-keyword", convertNoVarKeyword],
     ["no-var-requires", convertNoVarRequires],
+    ["no-void-expression", convertNoVoidExpression],
     ["prefer-for-of", convertPreferForOf],
     ["prefer-object-spread", convertPreferObjectSpread],
     ["promise-function-async", convertPromiseFunctionAsync],
@@ -234,7 +240,6 @@ export const converters = new Map([
     // tslint-microsoft-contrib rules:
     // ["max-func-body-length", convertMaxFuncBodyLength],
     // ["no-empty-line-after-opening-brace", convertNoEmptyLineAfterOpeningBrace], // padded-blocks
-    // ["no-for-in", convertNoForIn], // no-restricted-syntax config
     // ["no-function-expression", convertNoFunctionExpression], // ban-syntax config
     // ["no-suspicious-comment", convertNoSuspiciousComment],
     // ["no-with-statement", convertNoWithStatement],
diff --git a/src/rules/converters/no-for-in.ts b/src/rules/converters/no-for-in.ts
new file mode 100644
index 0000000..ed32259
--- /dev/null
+++ b/src/rules/converters/no-for-in.ts
@@ -0,0 +1,12 @@
+import { RuleConverter } from "../converter";
+
+export const convertNoForIn: RuleConverter = () => {
+    return {
+        rules: [
+            {
+                ruleArguments: ["ForInStatement"],
+                ruleName: "no-restricted-syntax",
+            },
+        ],
+    };
+};
diff --git a/src/rules/converters/no-trailing-whitespace.ts b/src/rules/converters/no-trailing-whitespace.ts
new file mode 100644
index 0000000..ddf7b07
--- /dev/null
+++ b/src/rules/converters/no-trailing-whitespace.ts
@@ -0,0 +1,32 @@
+import { RuleConverter } from "../converter";
+
+export const convertNoTrailingWhitespace: RuleConverter = tslintRule => {
+    const ruleArguments: { [eslintOption in "ignoreComments" | "skipBlankLines"]?: true }[] = [];
+    const notices: string[] = [];
+
+    if (tslintRule.ruleArguments.includes("ignore-comments")) {
+        ruleArguments.push({ ignoreComments: true });
+    }
+
+    if (tslintRule.ruleArguments.includes("ignore-blank-lines")) {
+        ruleArguments.push({ skipBlankLines: true });
+    }
+
+    if (tslintRule.ruleArguments.includes("ignore-template-strings")) {
+        notices.push("ESLint does not support ignoring template strings.");
+    }
+
+    if (tslintRule.ruleArguments.includes("ignore-jsdoc")) {
+        notices.push("ESLint does not support ignoring JSDoc.");
+    }
+
+    return {
+        rules: [
+            {
+                ...(notices.length > 0 && { notices }),
+                ...(ruleArguments.length > 0 && { ruleArguments }),
+                ruleName: "no-trailing-spaces",
+            },
+        ],
+    };
+};
diff --git a/src/rules/converters/no-void-expression.ts b/src/rules/converters/no-void-expression.ts
new file mode 100644
index 0000000..55a1467
--- /dev/null
+++ b/src/rules/converters/no-void-expression.ts
@@ -0,0 +1,15 @@
+import { RuleConverter } from "../converter";
+
+export const convertNoVoidExpression: RuleConverter = tslintRule => {
+    return {
+        rules: [
+            {
+                ...(tslintRule.ruleArguments.length > 0 &&
+                    tslintRule.ruleArguments.includes("ignore-arrow-function-shorthand") && {
+                        notices: ["ESLint does not support ignoring arrow function shorthand."],
+                    }),
+                ruleName: "no-void",
+            },
+        ],
+    };
+};


Test patch:
diff --git a/src/rules/converters/tests/no-for-in.test.ts b/src/rules/converters/tests/no-for-in.test.ts
new file mode 100644
index 0000000..af31320
--- /dev/null
+++ b/src/rules/converters/tests/no-for-in.test.ts
@@ -0,0 +1,18 @@
+import { convertNoForIn } from "../no-for-in";
+
+describe(convertNoForIn, () => {
+    test("conversion without arguments", () => {
+        const result = convertNoForIn({
+            ruleArguments: [],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "no-restricted-syntax",
+                    ruleArguments: ["ForInStatement"],
+                },
+            ],
+        });
+    });
+});
diff --git a/src/rules/converters/tests/no-trailing-whitespace.test.ts b/src/rules/converters/tests/no-trailing-whitespace.test.ts
new file mode 100644
index 0000000..4743a28
--- /dev/null
+++ b/src/rules/converters/tests/no-trailing-whitespace.test.ts
@@ -0,0 +1,101 @@
+import { convertNoTrailingWhitespace } from "../no-trailing-whitespace";
+
+describe(convertNoTrailingWhitespace, () => {
+    test("conversion without arguments", () => {
+        const result = convertNoTrailingWhitespace({
+            ruleArguments: [],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "no-trailing-spaces",
+                },
+            ],
+        });
+    });
+
+    test("conversion with ignore-template-strings argument", () => {
+        const result = convertNoTrailingWhitespace({
+            ruleArguments: ["ignore-template-strings"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    notices: ["ESLint does not support ignoring template strings."],
+                    ruleName: "no-trailing-spaces",
+                },
+            ],
+        });
+    });
+
+    test("conversion with ignore-comments argument", () => {
+        const result = convertNoTrailingWhitespace({
+            ruleArguments: ["ignore-comments"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleArguments: [{ ignoreComments: true }],
+                    ruleName: "no-trailing-spaces",
+                },
+            ],
+        });
+    });
+
+    test("conversion with ignore-jsdoc argument", () => {
+        const result = convertNoTrailingWhitespace({
+            ruleArguments: ["ignore-jsdoc"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    notices: ["ESLint does not support ignoring JSDoc."],
+                    ruleName: "no-trailing-spaces",
+                },
+            ],
+        });
+    });
+
+    test("conversion with ignore-blank-lines argument", () => {
+        const result = convertNoTrailingWhitespace({
+            ruleArguments: ["ignore-blank-lines"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleArguments: [{ skipBlankLines: true }],
+                    ruleName: "no-trailing-spaces",
+                },
+            ],
+        });
+    });
+
+    test("conversion with all arguments", () => {
+        const result = convertNoTrailingWhitespace({
+            ruleArguments: [
+                "ignore-template-strings",
+                "ignore-comments",
+                "ignore-jsdoc",
+                "ignore-blank-lines",
+            ],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    notices: [
+                        "ESLint does not support ignoring template strings.",
+                        "ESLint does not support ignoring JSDoc.",
+                    ],
+                    ruleArguments: [{ ignoreComments: true }, { skipBlankLines: true }],
+                    ruleName: "no-trailing-spaces",
+                },
+            ],
+        });
+    });
+});
diff --git a/src/rules/converters/tests/no-void-expression.test.ts b/src/rules/converters/tests/no-void-expression.test.ts
new file mode 100644
index 0000000..84a03ad
--- /dev/null
+++ b/src/rules/converters/tests/no-void-expression.test.ts
@@ -0,0 +1,32 @@
+import { convertNoVoidExpression } from "../no-void-expression";
+
+describe(convertNoVoidExpression, () => {
+    test("conversion without arguments", () => {
+        const result = convertNoVoidExpression({
+            ruleArguments: [],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "no-void",
+                },
+            ],
+        });
+    });
+
+    test("conversion with ignore-arrow-function-shorthand argument", () => {
+        const result = convertNoVoidExpression({
+            ruleArguments: ["ignore-arrow-function-shorthand"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    notices: ["ESLint does not support ignoring arrow function shorthand."],
+                    ruleName: "no-void",
+                },
+            ],
+        });
+    });
+});