diff --git a/src/cli/main.ts b/src/cli/main.ts index b3adcd29b..d0747d8a0 100644 --- a/src/cli/main.ts +++ b/src/cli/main.ts @@ -74,6 +74,7 @@ const findConfigurationDependencies = { }; const findEditorConfigurationDependencies: FindEditorConfigurationDependencies = { + fileSystem: fsFileSystem, importer: boundImporter, }; diff --git a/src/cli/runCli.ts b/src/cli/runCli.ts index 0a1cba644..9829e375d 100644 --- a/src/cli/runCli.ts +++ b/src/cli/runCli.ts @@ -6,7 +6,6 @@ import { version } from "../../package.json"; import { Logger } from "../adapters/logger"; import { SansDependencies } from "../binding"; import { convertConfig } from "../conversion/convertConfig"; -import { DEFAULT_VSCODE_SETTINGS_PATH } from "../input/vsCodeSettings"; import { ResultStatus, ResultWithStatus, TSLintToESLintSettings } from "../types"; export type RunCliDependencies = { @@ -25,11 +24,7 @@ export const runCli = async ( .option("--package [package]", "package configuration file to convert using") .option("--tslint [tslint]", "tslint configuration file to convert using") .option("--typescript [typescript]", "typescript configuration file to convert using") - .option( - "--editor [editor]", - "editor configuration file to convert using", - DEFAULT_VSCODE_SETTINGS_PATH, - ) + .option("--editor [editor]", "editor configuration file to convert") .option("-V --version", "output the package version"); const parsedArgv = { diff --git a/src/conversion/convertEditorConfig.test.ts b/src/conversion/convertEditorConfig.test.ts index c6493256f..d734e48a8 100644 --- a/src/conversion/convertEditorConfig.test.ts +++ b/src/conversion/convertEditorConfig.test.ts @@ -19,6 +19,21 @@ const createStubDependencies = ( }); describe("convertEditorConfig", () => { + it("returns a success result when there is no original configuration", async () => { + // Arrange + const dependencies = createStubDependencies({ + findEditorConfiguration: async () => undefined, + }); + + // Act + const result = await convertEditorConfig(dependencies, stubSettings); + + // Assert + expect(result).toEqual({ + status: ResultStatus.Succeeded, + }); + }); + it("returns the failure result when finding the original configurations fails", async () => { // Arrange const error = new Error(); @@ -28,7 +43,10 @@ describe("convertEditorConfig", () => { }; const dependencies = createStubDependencies({ - findEditorConfiguration: async () => error, + findEditorConfiguration: async () => ({ + configPath: "", + result: error, + }), }); // Act @@ -59,14 +77,12 @@ describe("convertEditorConfig", () => { // Arrange const originalConfig = { "typescript.tsdk": "node_modules/typescript/lib", - "editor.tabSize": 4, - "editor.codeActionsOnSave": { - "source.organizeImports": false, - }, }; const dependencies = createStubDependencies({ - findEditorConfiguration: jest.fn().mockResolvedValue(originalConfig), + findEditorConfiguration: jest.fn().mockResolvedValue({ + result: originalConfig, + }), }); // Act @@ -113,20 +129,4 @@ describe("convertEditorConfig", () => { status: ResultStatus.Succeeded, }); }); - - it("uses VS Code default settings path if editor config parameter is undefined", async () => { - // Arrange - const expectedEditorPath = ".vscode/settings.json"; - const settings = { - config: "./eslintrc.js", - }; - - const dependencies = createStubDependencies(); - - // Act - await convertEditorConfig(dependencies, settings); - - // Assert - expect(dependencies.findEditorConfiguration).toHaveBeenCalledWith(expectedEditorPath); - }); }); diff --git a/src/conversion/convertEditorConfig.ts b/src/conversion/convertEditorConfig.ts index 2d78ba630..3218ffb55 100644 --- a/src/conversion/convertEditorConfig.ts +++ b/src/conversion/convertEditorConfig.ts @@ -2,7 +2,6 @@ import { SansDependencies } from "../binding"; import { writeConversionResults } from "../creation/writeEditorConfigConversionResults"; import { convertEditorSettings } from "../editorSettings/convertEditorSettings"; import { findEditorConfiguration } from "../input/findEditorConfiguration"; -import { DEFAULT_VSCODE_SETTINGS_PATH } from "../input/vsCodeSettings"; import { reportEditorSettingConversionResults } from "../reporting/reportEditorSettingConversionResults"; import { ResultStatus, ResultWithStatus, TSLintToESLintSettings } from "../types"; @@ -20,26 +19,26 @@ export const convertEditorConfig = async ( dependencies: ConvertEditorConfigDependencies, settings: TSLintToESLintSettings, ): Promise => { - const editorConfigPath = settings.editor ? settings.editor : DEFAULT_VSCODE_SETTINGS_PATH; - const originalEditorConfiguration = await dependencies.findEditorConfiguration( - editorConfigPath, - ); - if (originalEditorConfiguration instanceof Error) { + const conversion = await dependencies.findEditorConfiguration(settings.editor); + if (conversion === undefined) { + return { + status: ResultStatus.Succeeded, + }; + } + + if (conversion.result instanceof Error) { return { - errors: [originalEditorConfiguration], + errors: [conversion.result], status: ResultStatus.Failed, }; } - const settingConversionResults = dependencies.convertEditorSettings( - originalEditorConfiguration, - ); + const settingConversionResults = dependencies.convertEditorSettings(conversion.result); - const outputPath = editorConfigPath; const fileWriteError = await dependencies.writeConversionResults( - outputPath, + conversion.configPath, settingConversionResults, - originalEditorConfiguration, + conversion.result, ); if (fileWriteError !== undefined) { return { diff --git a/src/input/findEditorConfiguration.test.ts b/src/input/findEditorConfiguration.test.ts index 2e6617b8a..734395ca1 100644 --- a/src/input/findEditorConfiguration.test.ts +++ b/src/input/findEditorConfiguration.test.ts @@ -1,7 +1,9 @@ +import { createStubFileSystem } from "../adapters/fileSystem.stub"; import { findEditorConfiguration, FindEditorConfigurationDependencies, } from "./findEditorConfiguration"; +import { DEFAULT_VSCODE_SETTINGS_PATH } from "./vsCodeSettings"; const stubConfigPath = "temp/"; @@ -10,10 +12,46 @@ export const createStubImporter = (filePath = "") => const createStubDependencies = (overrides: Partial = {}) => ({ importer: createStubImporter(stubConfigPath), + fileSystem: createStubFileSystem(), ...overrides, }); describe("findEditorConfiguration", () => { + it("returns undefined when the file is not specified and does not exist", async () => { + // Arrange + const dependencies = createStubDependencies({ + fileSystem: { + fileExists: async () => false, + }, + }); + + // Act + const result = await findEditorConfiguration(dependencies, undefined); + + // Assert + expect(result).toEqual(undefined); + }); + + it("returns an error when the file is specified and does not exist", async () => { + // Arrange + const dependencies = createStubDependencies({ + fileSystem: { + fileExists: async () => false, + }, + }); + + // Act + const result = await findEditorConfiguration(dependencies, stubConfigPath); + + // Assert + expect(result).toEqual({ + configPath: stubConfigPath, + result: expect.objectContaining({ + message: `Could not find editor configuration under '${stubConfigPath}'.`, + }), + }); + }); + it("returns an error when importer returns one", async () => { // Arrange const message = "error"; @@ -27,11 +65,12 @@ describe("findEditorConfiguration", () => { const result = await findEditorConfiguration(dependencies, stubConfigPath); // Assert - expect(result).toEqual( - expect.objectContaining({ + expect(result).toEqual({ + configPath: stubConfigPath, + result: expect.objectContaining({ message, }), - ); + }); }); it("reads from the given configuration path when one is provided", async () => { @@ -46,25 +85,30 @@ describe("findEditorConfiguration", () => { expect(dependencies.importer).toHaveBeenLastCalledWith(configPath); }); - it("defaults to VS Code editor settings path when config path isn't provided", async () => { + it("parses object from the default VS Code configuration path when the file is not specified and read successfully", async () => { // Arrange - const dependencies = createStubDependencies(); + const originalConfig = { + "typescript.tsdk": "node_modules/typescript/lib", + }; + + const dependencies = createStubDependencies({ + importer: async () => originalConfig, + }); // Act - await findEditorConfiguration(dependencies, undefined); + const result = await findEditorConfiguration(dependencies, undefined); // Assert - expect(dependencies.importer).toHaveBeenLastCalledWith(".vscode/settings.json"); + expect(result).toEqual({ + configPath: DEFAULT_VSCODE_SETTINGS_PATH, + result: originalConfig, + }); }); - it("parses object from configuration path when read successfully", async () => { + it("parses object from configuration path when the file is specified and read successfully", async () => { // Arrange const originalConfig = { "typescript.tsdk": "node_modules/typescript/lib", - "editor.tabSize": 4, - "editor.codeActionsOnSave": { - "source.organizeImports": false, - }, }; const dependencies = createStubDependencies({ @@ -75,6 +119,9 @@ describe("findEditorConfiguration", () => { const result = await findEditorConfiguration(dependencies, stubConfigPath); // Assert - expect(result).toEqual(originalConfig); + expect(result).toEqual({ + configPath: stubConfigPath, + result: originalConfig, + }); }); }); diff --git a/src/input/findEditorConfiguration.ts b/src/input/findEditorConfiguration.ts index dee2e078e..b02c0df96 100644 --- a/src/input/findEditorConfiguration.ts +++ b/src/input/findEditorConfiguration.ts @@ -1,3 +1,4 @@ +import { FileSystem } from "../adapters/fileSystem"; import { SansDependencies } from "../binding"; import { EditorConfiguration } from "./editorConfiguration"; import { findRawConfiguration } from "./findRawConfiguration"; @@ -6,18 +7,34 @@ import { importer } from "./importer"; import { DEFAULT_VSCODE_SETTINGS_PATH } from "./vsCodeSettings"; export type FindEditorConfigurationDependencies = { + fileSystem: Pick; importer: SansDependencies; }; export const findEditorConfiguration = async ( dependencies: FindEditorConfigurationDependencies, - config: string | undefined, -): Promise | Error> => { - const filePath = config ?? DEFAULT_VSCODE_SETTINGS_PATH; - const rawConfiguration = await findRawConfiguration>( + specifiedConfigPath: string | undefined, +) => { + const attemptingConfigPath = specifiedConfigPath ?? DEFAULT_VSCODE_SETTINGS_PATH; + + if (!(await dependencies.fileSystem.fileExists(attemptingConfigPath))) { + return specifiedConfigPath === undefined + ? undefined + : { + configPath: attemptingConfigPath, + result: new Error( + `Could not find editor configuration under '${attemptingConfigPath}'.`, + ), + }; + } + + const result = await findRawConfiguration>( dependencies.importer, - filePath, + attemptingConfigPath, ); - return rawConfiguration; + return { + configPath: attemptingConfigPath, + result, + }; };