From aadd18aa59c57644888b4ce674c956b8523bc58d Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 24 Jun 2019 20:43:41 -0500 Subject: [PATCH] Stubbed out and tested createNewConfiguration --- .gitignore | 3 - src/cli/main.ts | 10 ++- src/convertConfig.test.ts | 78 +++++++++++---------- src/convertConfig.ts | 28 +++++--- src/creation/createNewConfiguration.test.ts | 68 ++++++++++++++++++ src/creation/createNewConfiguration.ts | 11 +-- 6 files changed, 145 insertions(+), 53 deletions(-) create mode 100644 src/creation/createNewConfiguration.test.ts diff --git a/.gitignore b/.gitignore index cd964e9e2..14a0e6a33 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,3 @@ coverage/ node_modules/ src/**/*.js - -# https://github.com/JoshuaKGoldberg/tslint-to-eslint-config/issues/9 -.eslintrc.json diff --git a/src/cli/main.ts b/src/cli/main.ts index 5c93a7d6a..94e023f67 100644 --- a/src/cli/main.ts +++ b/src/cli/main.ts @@ -4,6 +4,7 @@ import { EOL } from "os"; import { promisify } from "util"; import { convertConfig } from "../convertConfig"; +import { createNewConfiguration } from "../creation/createNewConfiguration"; import { findTslintRules } from "../input/findTslintRules"; import { TSLintToESLintSettings } from "../types"; import { runCli } from "./runCli"; @@ -23,7 +24,14 @@ const fileExists = (filePath: string) => Promise.resolve(fs.existsSync(filePath) const runtime = { convertConfig: (settings: TSLintToESLintSettings) => - convertConfig(settings, logger, ruleFinder, fileExists), + convertConfig({ + createNewConfiguration: configConversionResults => + createNewConfiguration(configConversionResults, fs.promises.writeFile), + fileExists, + logger, + ruleFinder, + settings, + }), logger, ruleFinder, }; diff --git a/src/convertConfig.test.ts b/src/convertConfig.test.ts index 0e8740cbb..a089bd565 100644 --- a/src/convertConfig.test.ts +++ b/src/convertConfig.test.ts @@ -2,66 +2,72 @@ import { createStubLogger } from "./stubs"; import { convertConfig } from "./convertConfig"; import { ResultStatus } from "./types"; +const defaultRequest = { + settings: {}, + logger: createStubLogger(), + ruleFinder: jest.fn().mockReturnValue(Promise.resolve(new Error())), + fileExists: jest.fn().mockReturnValue(Promise.resolve(true)), + createNewConfiguration: jest.fn().mockReturnValue(Promise.resolve()), +}; + describe("convertConfig", () => { it("complains when the provided config file does not exist", async () => { // Arrange - const settings = { - config: "./stub/tslint.json", + const request = { + ...defaultRequest, + fileExists: jest.fn().mockReturnValue(Promise.resolve(false)), }; - const logger = createStubLogger(); - const ruleFinder = jest.fn().mockReturnValue(Promise.resolve(new Error())); - const fileExists = jest.fn().mockReturnValue(Promise.resolve(false)); // Act - const result = await convertConfig(settings, logger, ruleFinder, fileExists); + const result = await convertConfig(request); // Assert expect(result).toEqual({ - complaint: `${settings.config} does not seem to exist.`, + complaint: `./tslint.json does not seem to exist.`, status: ResultStatus.ConfigurationError, }); }); it("searches for settings.config when settings.config is provided", async () => { // Arrange - const settings = { - config: "./stub/tslint.json", + const request = { + ...defaultRequest, + settings: { + config: "./stub/tslint.json", + }, }; - const logger = createStubLogger(); - const ruleFinder = jest.fn().mockReturnValue(Promise.resolve(new Error())); - const fileExists = jest.fn().mockReturnValue(Promise.resolve(true)); // Act - await convertConfig(settings, logger, ruleFinder, fileExists); + await convertConfig(request); // Assert - expect(ruleFinder).toHaveBeenLastCalledWith(settings.config); + expect(request.ruleFinder).toHaveBeenLastCalledWith(request.settings.config); }); it("searches for ./tslint.json by default when no settings.config is provided", async () => { // Arrange - const settings = {}; - const logger = createStubLogger(); - const ruleFinder = jest.fn().mockReturnValue(Promise.resolve(new Error())); - const fileExists = jest.fn().mockReturnValue(Promise.resolve(true)); + const request = { + ...defaultRequest, + settings: {}, + }; // Act - await convertConfig(settings, logger, ruleFinder, fileExists); + await convertConfig(request); // Assert - expect(ruleFinder).toHaveBeenLastCalledWith("./tslint.json"); + expect(request.ruleFinder).toHaveBeenLastCalledWith("./tslint.json"); }); it("returns a failure result when ruleFinder returns an error", async () => { // Arrange - const settings = {}; - const logger = createStubLogger(); const error = new Error("oh no"); - const ruleFinder = jest.fn().mockReturnValue(Promise.resolve(error)); - const fileExists = jest.fn().mockReturnValue(Promise.resolve(true)); + const request = { + ...defaultRequest, + ruleFinder: jest.fn().mockReturnValue(Promise.resolve(error)), + }; // Act - const result = await convertConfig(settings, logger, ruleFinder, fileExists); + const result = await convertConfig(request); // Assert expect(result).toEqual({ @@ -72,20 +78,20 @@ describe("convertConfig", () => { it("creates a new configuration when ruleFinder returns rules", async () => { // Arrange - const settings = {}; - const logger = createStubLogger(); - const ruleFinder = jest.fn().mockReturnValue({ - rules: { - "sample-rule": { - ruleArguments: ["one", "two"], - ruleName: "sample-rule", + const request = { + ...defaultRequest, + ruleFinder: jest.fn().mockReturnValue({ + rules: { + "sample-rule": { + ruleArguments: ["one", "two"], + ruleName: "sample-rule", + }, }, - }, - }); - const fileExists = jest.fn().mockReturnValue(Promise.resolve(true)); + }), + }; // Act - const result = await convertConfig(settings, logger, ruleFinder, fileExists); + const result = await convertConfig(request); // Assert expect(result).toEqual({ diff --git a/src/convertConfig.ts b/src/convertConfig.ts index 18df7ee0c..15e9b3030 100644 --- a/src/convertConfig.ts +++ b/src/convertConfig.ts @@ -1,21 +1,31 @@ -import { createNewConfiguration } from "./creation/createNewConfiguration"; import { FoundTSLintRules } from "./input/findTslintRules"; import { ProcessLogger } from "./logger"; import { reportConversionResults } from "./reportConversionResults"; -import { convertRules } from "./rules/convertRules"; +import { convertRules, ConfigConversionResults } from "./rules/convertRules"; import { converters } from "./rules/converters"; import { TSLintToESLintSettings, TSLintToESLintResult, ResultStatus } from "./types"; -export type RuleFinder = (config: string) => Promise; +export type CreateNewConfiguration = (conversionResults: ConfigConversionResults) => Promise; export type FileExists = (filePath: string) => Promise; -export const convertConfig = async ( - settings: TSLintToESLintSettings, - logger: ProcessLogger, - ruleFinder: RuleFinder, - fileExists: FileExists, -): Promise => { +export type RuleFinder = (config: string) => Promise; + +export type ConvertConfigRequest = { + createNewConfiguration: CreateNewConfiguration; + fileExists: FileExists; + logger: ProcessLogger; + ruleFinder: RuleFinder; + settings: TSLintToESLintSettings; +}; + +export const convertConfig = async ({ + createNewConfiguration, + fileExists, + logger, + ruleFinder, + settings, +}: ConvertConfigRequest): Promise => { const { config = "./tslint.json" } = settings; if (!(await fileExists(config))) { return { diff --git a/src/creation/createNewConfiguration.test.ts b/src/creation/createNewConfiguration.test.ts new file mode 100644 index 000000000..c6843057d --- /dev/null +++ b/src/creation/createNewConfiguration.test.ts @@ -0,0 +1,68 @@ +import { emptyConversionResults } from "../stubs"; +import { createNewConfiguration } from "./createNewConfiguration"; +import { ConfigConversionResults } from "../rules/convertRules"; + +describe("createNewConfiguration", () => { + it("writes only formatted rules when there are no missing rules", async () => { + // Arrange + const conversionResults: ConfigConversionResults = { + ...emptyConversionResults, + converted: new Map(), + }; + const writeFile = jest.fn().mockReturnValue(Promise.resolve()); + + // Act + await createNewConfiguration(conversionResults, writeFile); + + // Assert + expect(writeFile).toHaveBeenLastCalledWith( + ".eslintrc.json", + JSON.stringify({ rules: {} }, undefined, 4), + ); + }); + + it("includes typescript-eslint plugin settings when there are missing rules", async () => { + // Arrange + const conversionResults: ConfigConversionResults = { + ...emptyConversionResults, + converted: new Map(), + missing: [ + { + ruleArguments: [], + ruleName: "tslint-rule-one", + ruleSeverity: "error", + }, + ], + }; + const writeFile = jest.fn().mockReturnValue(Promise.resolve()); + + // Act + await createNewConfiguration(conversionResults, writeFile); + + // Assert + expect(writeFile).toHaveBeenLastCalledWith( + ".eslintrc.json", + JSON.stringify( + { + plugins: ["@typescript-eslint/tslint"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: "tsconfig.json", + }, + rules: { + "@typescript-eslint/tslint/config": [ + "error", + { + rules: { + "tslint-rule-one": true, + }, + }, + ], + }, + }, + undefined, + 4, + ), + ); + }); +}); diff --git a/src/creation/createNewConfiguration.ts b/src/creation/createNewConfiguration.ts index 50b3ab28d..e637dcefc 100644 --- a/src/creation/createNewConfiguration.ts +++ b/src/creation/createNewConfiguration.ts @@ -1,9 +1,12 @@ -import * as fs from "fs"; - import { ConfigConversionResults } from "../rules/convertRules"; import { formatConvertedRules } from "./formatConvertedRules"; -export const createNewConfiguration = async (conversionResults: ConfigConversionResults) => { +export type WriteFile = (filePath: string, contents: string) => Promise; + +export const createNewConfiguration = async ( + conversionResults: ConfigConversionResults, + writeFile: WriteFile, +) => { const output = { ...(conversionResults.missing.length && { plugins: ["@typescript-eslint/tslint"], @@ -15,5 +18,5 @@ export const createNewConfiguration = async (conversionResults: ConfigConversion rules: formatConvertedRules(conversionResults), }; - await fs.promises.writeFile(".eslintrc.json", JSON.stringify(output, undefined, 4)); + await writeFile(".eslintrc.json", JSON.stringify(output, undefined, 4)); };