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

Issue:
Missing converter: strict-boolean-expressions
### 💥 Missing Converter

-   `tslint-to-eslint-config` version: 1.2.0
-   `typescript-eslint` version: 2.3.2

#### TSLint Rule Name

`strict-boolean-expressions`


Pull request:
Add strict-boolean-expression converter
<!--
👋 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 #185
-   [x] That issue was marked as [`status: accepting prs`](https://github.com/typescript-eslint/tslint-to-eslint-config/labels/status%3A%20accepting%20prs)

## Overview

<!-- Brief description of what is changed and how the code change does that. -->

- Added a rule converter for `stric-boolean-expressions` in the TSLint ruleset.
- Added proper handling for the options that come with the rule itself.
- Added tests to make sure that the right comparative rules are being output.
- Added a notice so that the user is informed of things not automatically converted or covered.
- Remove comments at `converters` file of already solved converters.


Patch:
diff --git a/src/rules/converters.ts b/src/rules/converters.ts
index d21e68b..db936a7 100644
--- a/src/rules/converters.ts
+++ b/src/rules/converters.ts
@@ -112,6 +112,7 @@ import { convertRestrictPlusOperands } from "./converters/restrict-plus-operands
 import { convertSemicolon } from "./converters/semicolon";
 import { convertSpaceBeforeFunctionParen } from "./converters/space-before-function-paren";
 import { convertSpaceWithinParens } from "./converters/space-within-parens";
+import { convertStrictBooleanExpressions } from "./converters/strict-boolean-expressions";
 import { convertSwitchDefault } from "./converters/switch-default";
 import { convertTripleEquals } from "./converters/triple-equals";
 import { convertTypedefWhitespace } from "./converters/typedef-whitespace";
@@ -242,6 +243,7 @@ export const converters = new Map([
     ["semicolon", convertSemicolon],
     ["space-before-function-paren", convertSpaceBeforeFunctionParen],
     ["space-within-parens", convertSpaceWithinParens],
+    ["strict-boolean-expressions", convertStrictBooleanExpressions],
     ["switch-default", convertSwitchDefault],
     ["triple-equals", convertTripleEquals],
     ["type-literal-delimiter", convertTypeLiteralDelimiter],
@@ -262,10 +264,6 @@ export const converters = new Map([
     // TSLint core rules:
     // ["ban", convertBan], // no-restricted-properties
     // ["import-blacklist", convertImportBlacklist], // no-restricted-imports
-    // ["no-duplicate-variable", convertNoDuplicateVariable], // no-redeclare
-    // ["no-void-expression", convertNoVoidExpression], // (no exact equivalent)
-    // ["quotemark", convertQuotemark], // quotes
-    // ["triple-equals", convertTripleEquals], // eqeqeq
 
     // tslint-microsoft-contrib rules:
     // ["max-func-body-length", convertMaxFuncBodyLength],
diff --git a/src/rules/converters/member-access.ts b/src/rules/converters/member-access.ts
index ccca098..9c85d86 100644
--- a/src/rules/converters/member-access.ts
+++ b/src/rules/converters/member-access.ts
@@ -1,15 +1,63 @@
 import { RuleConverter } from "../converter";
 
-export const convertMemberAccess: RuleConverter = () => {
+export enum AccessibilityLevel {
+    Explicit = "explicit",
+    NoPublic = "no-public",
+}
+
+export enum MemberAccessArguments {
+    NoPublic = "no-public",
+    Accessor = "check-accessor",
+    Constructor = "check-constructor",
+    ParameterProp = "check-parameter-property",
+}
+
+type MemberAccessSchema = {
+    accessibility: string;
+    overrides?: { [key: string]: string };
+};
+
+export const convertMemberAccess: RuleConverter = tslintRule => {
+    const tslintRuleArguments = tslintRule.ruleArguments;
+    const schema: MemberAccessSchema = {
+        accessibility: AccessibilityLevel.Explicit,
+    };
+
+    if (tslintRuleArguments.length >= 2 || tslintRuleArguments[0] === true) {
+        tslintRuleArguments.forEach(ruleArg => {
+            if (typeof ruleArg === "string") {
+                switch (ruleArg) {
+                    case MemberAccessArguments.NoPublic:
+                        schema.accessibility = AccessibilityLevel.NoPublic;
+                        break;
+                    case MemberAccessArguments.Accessor:
+                        schema.overrides = {
+                            ...schema.overrides,
+                            accessors: AccessibilityLevel.Explicit,
+                        };
+                        break;
+                    case MemberAccessArguments.Constructor:
+                        schema.overrides = {
+                            ...schema.overrides,
+                            constructors: AccessibilityLevel.Explicit,
+                        };
+                        break;
+                    case MemberAccessArguments.ParameterProp:
+                        schema.overrides = {
+                            ...schema.overrides,
+                            parameterProperties: AccessibilityLevel.Explicit,
+                        };
+                        break;
+                }
+            }
+        });
+    }
+
     return {
         rules: [
             {
                 ruleName: "@typescript-eslint/explicit-member-accessibility",
-                ruleArguments: [
-                    {
-                        overrides: { constructors: "off" },
-                    },
-                ],
+                ruleArguments: [schema],
             },
         ],
     };
diff --git a/src/rules/converters/strict-boolean-expressions.ts b/src/rules/converters/strict-boolean-expressions.ts
new file mode 100644
index 0000000..e3eda4d
--- /dev/null
+++ b/src/rules/converters/strict-boolean-expressions.ts
@@ -0,0 +1,37 @@
+import { RuleConverter } from "../converter";
+
+export const ForbiddenOtherNonBooleanTypes =
+    "String, number, enum, and mixed union types are now forbidden.";
+
+export const convertStrictBooleanExpressions: RuleConverter = tslintRule => {
+    const notices: string[] = [];
+    const ruleArguments: { [key: string]: boolean } = {};
+
+    if (tslintRule.ruleArguments.length >= 2 || tslintRule.ruleArguments[0] === true) {
+        notices.push(ForbiddenOtherNonBooleanTypes);
+        tslintRule.ruleArguments.forEach(ruleArgument => {
+            switch (ruleArgument) {
+                case "allow-undefined-union":
+                case "allow-boolean-or-undefined":
+                case "allow-null-union":
+                    ruleArguments["allowNullable"] = true;
+                    break;
+                case "ignore-rhs":
+                    ruleArguments["ignoreRhs"] = true;
+                    break;
+                default:
+                    break;
+            }
+        });
+    }
+
+    return {
+        rules: [
+            {
+                ruleName: "@typescript-eslint/strict-boolean-expressions",
+                ruleArguments: Object.keys(ruleArguments).length !== 0 ? [ruleArguments] : [],
+                notices,
+            },
+        ],
+    };
+};


Test patch:
diff --git a/src/rules/converters/tests/member-access.test.ts b/src/rules/converters/tests/member-access.test.ts
index b803dff..7ac840f 100644
--- a/src/rules/converters/tests/member-access.test.ts
+++ b/src/rules/converters/tests/member-access.test.ts
@@ -1,4 +1,4 @@
-import { convertMemberAccess } from "../member-access";
+import { convertMemberAccess, AccessibilityLevel } from "../member-access";
 
 describe(convertMemberAccess, () => {
     test("conversion without arguments", () => {
@@ -6,12 +6,136 @@ describe(convertMemberAccess, () => {
             ruleArguments: [],
         });
 
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/explicit-member-accessibility",
+                    ruleArguments: [{ accessibility: AccessibilityLevel.Explicit }],
+                },
+            ],
+        });
+    });
+
+    test("conversion with true argument", () => {
+        const result = convertMemberAccess({
+            ruleArguments: [true],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/explicit-member-accessibility",
+                    ruleArguments: [{ accessibility: AccessibilityLevel.Explicit }],
+                },
+            ],
+        });
+    });
+
+    test("conversion with no-public argument", () => {
+        const result = convertMemberAccess({
+            ruleArguments: [true, "no-public"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/explicit-member-accessibility",
+                    ruleArguments: [{ accessibility: AccessibilityLevel.NoPublic }],
+                },
+            ],
+        });
+    });
+
+    test("conversion with check-accessor argument", () => {
+        const result = convertMemberAccess({
+            ruleArguments: [true, "check-accessor"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/explicit-member-accessibility",
+                    ruleArguments: [
+                        {
+                            accessibility: AccessibilityLevel.Explicit,
+                            overrides: {
+                                accessors: AccessibilityLevel.Explicit,
+                            },
+                        },
+                    ],
+                },
+            ],
+        });
+    });
+
+    test("conversion with check-constructor argument", () => {
+        const result = convertMemberAccess({
+            ruleArguments: [true, "check-constructor"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/explicit-member-accessibility",
+                    ruleArguments: [
+                        {
+                            accessibility: AccessibilityLevel.Explicit,
+                            overrides: {
+                                constructors: AccessibilityLevel.Explicit,
+                            },
+                        },
+                    ],
+                },
+            ],
+        });
+    });
+
+    test("conversion with check-parameter-property argument", () => {
+        const result = convertMemberAccess({
+            ruleArguments: [true, "check-parameter-property"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/explicit-member-accessibility",
+                    ruleArguments: [
+                        {
+                            accessibility: AccessibilityLevel.Explicit,
+                            overrides: {
+                                parameterProperties: AccessibilityLevel.Explicit,
+                            },
+                        },
+                    ],
+                },
+            ],
+        });
+    });
+
+    test("conversion with all arguments", () => {
+        const result = convertMemberAccess({
+            ruleArguments: [
+                true,
+                "no-public",
+                "check-accessor",
+                "check-constructor",
+                "check-parameter-property",
+            ],
+        });
+
         expect(result).toEqual({
             rules: [
                 {
                     ruleName: "@typescript-eslint/explicit-member-accessibility",
                     ruleArguments: [
-                        { overrides: { constructors: "off" } },
+                        {
+                            accessibility: AccessibilityLevel.NoPublic,
+                            overrides: {
+                                accessors: AccessibilityLevel.Explicit,
+                                constructors: AccessibilityLevel.Explicit,
+                                parameterProperties: AccessibilityLevel.Explicit,
+                            },
+                        },
                     ],
                 },
             ],
diff --git a/src/rules/converters/tests/strict-boolean-expressions.test.ts b/src/rules/converters/tests/strict-boolean-expressions.test.ts
new file mode 100644
index 0000000..4768fa1
--- /dev/null
+++ b/src/rules/converters/tests/strict-boolean-expressions.test.ts
@@ -0,0 +1,109 @@
+import {
+    convertStrictBooleanExpressions,
+    ForbiddenOtherNonBooleanTypes,
+} from "../strict-boolean-expressions";
+
+describe(convertStrictBooleanExpressions, () => {
+    test("conversion without arguments", () => {
+        const result = convertStrictBooleanExpressions({
+            ruleArguments: [],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/strict-boolean-expressions",
+                    ruleArguments: [],
+                    notices: [],
+                },
+            ],
+        });
+    });
+
+    test("conversion with true argument", () => {
+        const result = convertStrictBooleanExpressions({
+            ruleArguments: [true],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/strict-boolean-expressions",
+                    ruleArguments: [],
+                    notices: [ForbiddenOtherNonBooleanTypes],
+                },
+            ],
+        });
+    });
+
+    test("conversion with allow-undefined-union argument", () => {
+        const result = convertStrictBooleanExpressions({
+            ruleArguments: [true, "allow-undefined-union"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/strict-boolean-expressions",
+                    ruleArguments: [
+                        {
+                            allowNullable: true,
+                        },
+                    ],
+                    notices: [ForbiddenOtherNonBooleanTypes],
+                },
+            ],
+        });
+    });
+
+    test("conversion with ignore-rhs argument", () => {
+        const result = convertStrictBooleanExpressions({
+            ruleArguments: [true, "ignore-rhs"],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/strict-boolean-expressions",
+                    ruleArguments: [
+                        {
+                            ignoreRhs: true,
+                        },
+                    ],
+                    notices: [ForbiddenOtherNonBooleanTypes],
+                },
+            ],
+        });
+    });
+
+    test("conversion with all arguments", () => {
+        const result = convertStrictBooleanExpressions({
+            ruleArguments: [
+                true,
+                "allow-undefined-union",
+                "allow-boolean-or-undefined",
+                "allow-null-union",
+                "ignore-rhs",
+                "allow-string",
+                "allow-enum",
+                "allow-number",
+                "allow-mix",
+            ],
+        });
+
+        expect(result).toEqual({
+            rules: [
+                {
+                    ruleName: "@typescript-eslint/strict-boolean-expressions",
+                    ruleArguments: [
+                        {
+                            allowNullable: true,
+                            ignoreRhs: true,
+                        },
+                    ],
+                    notices: [ForbiddenOtherNonBooleanTypes],
+                },
+            ],
+        });
+    });
+});