From 7dcbb044440fcf8cb6a977051dd9f8f7104afd30 Mon Sep 17 00:00:00 2001 From: Jeremy Yap Date: Mon, 21 Oct 2019 15:24:13 +0800 Subject: [PATCH 1/2] Add converter for align rule --- src/rules/converters.ts | 2 + src/rules/converters/align.ts | 38 +++++++ src/rules/converters/tests/align.test.ts | 122 +++++++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 src/rules/converters/align.ts create mode 100644 src/rules/converters/tests/align.test.ts diff --git a/src/rules/converters.ts b/src/rules/converters.ts index db936a773..5f05562dd 100644 --- a/src/rules/converters.ts +++ b/src/rules/converters.ts @@ -1,4 +1,5 @@ import { convertAdjacentOverloadSignatures } from "./converters/adjacent-overload-signatures"; +import { convertAlign } from "./converters/align"; import { convertArrayType } from "./converters/array-type"; import { convertArrowParens } from "./converters/arrow-parens"; import { convertArrowReturnShorthand } from "./converters/arrow-return-shorthand"; @@ -130,6 +131,7 @@ import { convertVariableName } from "./converters/variable-name"; */ export const converters = new Map([ ["adjacent-overload-signatures", convertAdjacentOverloadSignatures], + ["align", convertAlign], ["array-type", convertArrayType], ["arrow-parens", convertArrowParens], ["arrow-return-shorthand", convertArrowReturnShorthand], diff --git a/src/rules/converters/align.ts b/src/rules/converters/align.ts new file mode 100644 index 000000000..84f387f1a --- /dev/null +++ b/src/rules/converters/align.ts @@ -0,0 +1,38 @@ +import { RuleConverter } from "../converter"; + +export const convertAlign: RuleConverter = tslintRule => { + const alignArguments = tslintRule.ruleArguments.includes("arguments"); + const alignElements = tslintRule.ruleArguments.includes("elements"); + const alignMembers = tslintRule.ruleArguments.includes("members"); + const alignParameters = tslintRule.ruleArguments.includes("parameters"); + // "statements" alignment is enforced by base indent rule + + const objectOption = { + ...(alignArguments && { + CallExpression: { arguments: "first" }, + }), + ...(alignElements && { + ArrayExpression: "first", + }), + ...(alignMembers && { + ObjectExpression: "first", + }), + ...(alignParameters && { + FunctionDeclaration: { parameters: "first" }, + FunctionExpression: { parameters: "first" }, + }), + }; + + // TSLint's "align" rule doesn't care about indent size but "indent" rule requires + // specifying the indent size before the object option. Use the default value of 4. + const ruleArguments = tslintRule.ruleArguments.length === 0 ? undefined : [4, objectOption]; + + return { + rules: [ + { + ruleName: "@typescript-eslint/indent", + ...{ ruleArguments }, + }, + ], + }; +}; diff --git a/src/rules/converters/tests/align.test.ts b/src/rules/converters/tests/align.test.ts new file mode 100644 index 000000000..eeabe3abe --- /dev/null +++ b/src/rules/converters/tests/align.test.ts @@ -0,0 +1,122 @@ +import { convertAlign } from "../align"; + +describe(convertAlign, () => { + test("conversion without arguments", () => { + const result = convertAlign({ + ruleArguments: [], + }); + + expect(result).toEqual({ + rules: [ + { + ruleName: "@typescript-eslint/indent", + }, + ], + }); + }); + + test("conversion with align arguments", () => { + const result = convertAlign({ + ruleArguments: ["arguments"], + }); + + expect(result).toEqual({ + rules: [ + { + ruleName: "@typescript-eslint/indent", + ruleArguments: [ + 4, + { + CallExpression: { arguments: "first" }, + }, + ], + }, + ], + }); + }); + + test("conversion with align elements", () => { + const result = convertAlign({ + ruleArguments: ["elements"], + }); + + expect(result).toEqual({ + rules: [ + { + ruleName: "@typescript-eslint/indent", + ruleArguments: [ + 4, + { + ArrayExpression: "first", + }, + ], + }, + ], + }); + }); + + test("conversion with align members", () => { + const result = convertAlign({ + ruleArguments: ["members"], + }); + + expect(result).toEqual({ + rules: [ + { + ruleName: "@typescript-eslint/indent", + ruleArguments: [ + 4, + { + ObjectExpression: "first", + }, + ], + }, + ], + }); + }); + + test("conversion with align parameters", () => { + const result = convertAlign({ + ruleArguments: ["parameters"], + }); + + expect(result).toEqual({ + rules: [ + { + ruleName: "@typescript-eslint/indent", + ruleArguments: [ + 4, + { + FunctionDeclaration: { parameters: "first" }, + FunctionExpression: { parameters: "first" }, + }, + ], + }, + ], + }); + }); + + test("conversion with align all", () => { + const result = convertAlign({ + ruleArguments: ["parameters", "elements", "arguments", "members"], + }); + + expect(result).toEqual({ + rules: [ + { + ruleName: "@typescript-eslint/indent", + ruleArguments: [ + 4, + { + ArrayExpression: "first", + CallExpression: { arguments: "first" }, + FunctionDeclaration: { parameters: "first" }, + FunctionExpression: { parameters: "first" }, + ObjectExpression: "first", + }, + ], + }, + ], + }); + }); +}); From 13ea4746f67b30057105f01f57dd5e8939d5ca6d Mon Sep 17 00:00:00 2001 From: Jeremy Yap Date: Mon, 21 Oct 2019 16:21:25 +0800 Subject: [PATCH 2/2] Add merger for indent rule --- src/rules/mergers.ts | 2 + src/rules/mergers/indent.ts | 42 ++++++++++++++++++ src/rules/mergers/tests/indent.test.ts | 60 ++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 src/rules/mergers/indent.ts create mode 100644 src/rules/mergers/tests/indent.test.ts diff --git a/src/rules/mergers.ts b/src/rules/mergers.ts index d32322498..446d68615 100644 --- a/src/rules/mergers.ts +++ b/src/rules/mergers.ts @@ -1,10 +1,12 @@ import { mergeBanTypes } from "./mergers/ban-types"; +import { mergeIndent } from "./mergers/indent"; import { mergeNoCaller } from "./mergers/no-caller"; import { mergeNoEval } from "./mergers/no-eval"; import { mergeNoUnnecessaryTypeAssertion } from "./mergers/no-unnecessary-type-assertion"; export const mergers = new Map([ ["@typescript-eslint/ban-types", mergeBanTypes], + ["@typescript-eslint/indent", mergeIndent], ["@typescript-eslint/no-unnecessary-type-assertion", mergeNoUnnecessaryTypeAssertion], ["no-caller", mergeNoCaller], ["no-eval", mergeNoEval], diff --git a/src/rules/mergers/indent.ts b/src/rules/mergers/indent.ts new file mode 100644 index 000000000..c9b8ae69c --- /dev/null +++ b/src/rules/mergers/indent.ts @@ -0,0 +1,42 @@ +import { RuleMerger } from "../merger"; + +const ESLINT_INDENT_DEFAULT = 4; + +export const mergeIndent: RuleMerger = (existingOptions, newOptions) => { + if (existingOptions === undefined && newOptions === undefined) { + return []; + } + + // Resolve indent size + let indentSize = ESLINT_INDENT_DEFAULT; // default + for (const options of [existingOptions, newOptions]) { + if ( + options === undefined || + options.length === 0 || + options[0] === ESLINT_INDENT_DEFAULT // ignore default + ) { + continue; + } + indentSize = options[0]; + } + + // Resolve object option + let objectOption = null; + for (const options of [existingOptions, newOptions]) { + if (options === undefined || options.length < 2 || options[1] === undefined) { + continue; + } + objectOption = { + ...(objectOption || {}), + ...options[1], + }; + } + + if (indentSize === ESLINT_INDENT_DEFAULT && objectOption === null) { + return []; + } else if (objectOption === null) { + return [indentSize]; + } + + return [indentSize, objectOption]; +}; diff --git a/src/rules/mergers/tests/indent.test.ts b/src/rules/mergers/tests/indent.test.ts new file mode 100644 index 000000000..db54aea63 --- /dev/null +++ b/src/rules/mergers/tests/indent.test.ts @@ -0,0 +1,60 @@ +import { mergeIndent } from "../indent"; + +describe(mergeIndent, () => { + test("neither options existing", () => { + const result = mergeIndent(undefined, undefined); + + expect(result).toEqual([]); + }); + + test("original indent size existing", () => { + const result = mergeIndent([2], undefined); + + expect(result).toEqual([2]); + }); + + test("new indent size existing", () => { + const result = mergeIndent(undefined, [2]); + + expect(result).toEqual([2]); + }); + + test("both indent sizes existing", () => { + const result = mergeIndent([1], [2]); + + expect(result).toEqual([2]); + }); + + test("default indent sizes existing", () => { + const result = mergeIndent([4], [4]); + + expect(result).toEqual([]); + }); + + test("original object option existing", () => { + const result = mergeIndent([4, { ArrayExpression: "first" }], [2]); + + expect(result).toEqual([2, { ArrayExpression: "first" }]); + }); + + test("new object option existing", () => { + const result = mergeIndent([2], [4, { ArrayExpression: "first" }]); + + expect(result).toEqual([2, { ArrayExpression: "first" }]); + }); + + test("both object option existing", () => { + const result = mergeIndent( + [4, { ObjectExpression: "first" }], + [4, { ArrayExpression: "first" }], + ); + + expect(result).toEqual([ + 4, + { + ArrayExpression: "first", + ObjectExpression: "first", + }, + ]); + }); +});