From 9cfcdf9d0375a336e53a56cbd99eef46d8d8903b Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 22 Dec 2019 20:29:51 -0500 Subject: [PATCH 1/2] Stopped erroring when .vscode/settings.json doesn't exist --- src/cli/main.ts | 1 + src/cli/runCli.ts | 2 +- src/conversion/convertEditorConfig.test.ts | 15 ++++++++++++ src/conversion/convertEditorConfig.ts | 9 ++++++- src/input/findEditorConfiguration.test.ts | 28 +++++++++++++--------- src/input/findEditorConfiguration.ts | 18 +++++++------- 6 files changed, 52 insertions(+), 21 deletions(-) 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..1f3ffd7b0 100644 --- a/src/cli/runCli.ts +++ b/src/cli/runCli.ts @@ -27,7 +27,7 @@ export const runCli = async ( .option("--typescript [typescript]", "typescript configuration file to convert using") .option( "--editor [editor]", - "editor configuration file to convert using", + "editor configuration file to convert", DEFAULT_VSCODE_SETTINGS_PATH, ) .option("-V --version", "output the package version"); diff --git a/src/conversion/convertEditorConfig.test.ts b/src/conversion/convertEditorConfig.test.ts index c6493256f..5c1102667 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(); diff --git a/src/conversion/convertEditorConfig.ts b/src/conversion/convertEditorConfig.ts index 2d78ba630..456549321 100644 --- a/src/conversion/convertEditorConfig.ts +++ b/src/conversion/convertEditorConfig.ts @@ -20,10 +20,17 @@ export const convertEditorConfig = async ( dependencies: ConvertEditorConfigDependencies, settings: TSLintToESLintSettings, ): Promise => { - const editorConfigPath = settings.editor ? settings.editor : DEFAULT_VSCODE_SETTINGS_PATH; + const editorConfigPath = settings.editor ?? DEFAULT_VSCODE_SETTINGS_PATH; const originalEditorConfiguration = await dependencies.findEditorConfiguration( editorConfigPath, ); + + if (originalEditorConfiguration === undefined) { + return { + status: ResultStatus.Succeeded, + }; + } + if (originalEditorConfiguration instanceof Error) { return { errors: [originalEditorConfiguration], diff --git a/src/input/findEditorConfiguration.test.ts b/src/input/findEditorConfiguration.test.ts index 2e6617b8a..7b5712d97 100644 --- a/src/input/findEditorConfiguration.test.ts +++ b/src/input/findEditorConfiguration.test.ts @@ -1,3 +1,4 @@ +import { createStubFileSystem } from "../adapters/fileSystem.stub"; import { findEditorConfiguration, FindEditorConfigurationDependencies, @@ -10,10 +11,26 @@ export const createStubImporter = (filePath = "") => const createStubDependencies = (overrides: Partial = {}) => ({ importer: createStubImporter(stubConfigPath), + fileSystem: createStubFileSystem(), ...overrides, }); describe("findEditorConfiguration", () => { + it("returns undefined when the file does not exist", async () => { + // Arrange + const dependencies = createStubDependencies({ + fileSystem: { + fileExists: async () => false, + }, + }); + + // Act + const result = await findEditorConfiguration(dependencies, stubConfigPath); + + // Assert + expect(result).toEqual(undefined); + }); + it("returns an error when importer returns one", async () => { // Arrange const message = "error"; @@ -46,17 +63,6 @@ describe("findEditorConfiguration", () => { expect(dependencies.importer).toHaveBeenLastCalledWith(configPath); }); - it("defaults to VS Code editor settings path when config path isn't provided", async () => { - // Arrange - const dependencies = createStubDependencies(); - - // Act - await findEditorConfiguration(dependencies, undefined); - - // Assert - expect(dependencies.importer).toHaveBeenLastCalledWith(".vscode/settings.json"); - }); - it("parses object from configuration path when read successfully", async () => { // Arrange const originalConfig = { diff --git a/src/input/findEditorConfiguration.ts b/src/input/findEditorConfiguration.ts index dee2e078e..6898c1a71 100644 --- a/src/input/findEditorConfiguration.ts +++ b/src/input/findEditorConfiguration.ts @@ -3,21 +3,23 @@ import { EditorConfiguration } from "./editorConfiguration"; import { findRawConfiguration } from "./findRawConfiguration"; import { DeepPartial } from "./findReportedConfiguration"; import { importer } from "./importer"; -import { DEFAULT_VSCODE_SETTINGS_PATH } from "./vsCodeSettings"; +import { FileSystem } from "../adapters/fileSystem"; 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>( + config: string, +): Promise | Error | undefined> => { + if (!(await dependencies.fileSystem.fileExists(config))) { + return undefined; + } + + return await findRawConfiguration>( dependencies.importer, - filePath, + config, ); - - return rawConfiguration; }; From 92741271fc52d180692d9239963bc32270efb259 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 23 Dec 2019 08:34:09 -0500 Subject: [PATCH 2/2] Still error if the file is specified --- src/cli/runCli.ts | 7 +-- src/conversion/convertEditorConfig.test.ts | 29 +++------- src/conversion/convertEditorConfig.ts | 22 +++----- src/input/findEditorConfiguration.test.ts | 63 ++++++++++++++++++---- src/input/findEditorConfiguration.ts | 29 +++++++--- 5 files changed, 89 insertions(+), 61 deletions(-) diff --git a/src/cli/runCli.ts b/src/cli/runCli.ts index 1f3ffd7b0..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", - 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 5c1102667..d734e48a8 100644 --- a/src/conversion/convertEditorConfig.test.ts +++ b/src/conversion/convertEditorConfig.test.ts @@ -43,7 +43,10 @@ describe("convertEditorConfig", () => { }; const dependencies = createStubDependencies({ - findEditorConfiguration: async () => error, + findEditorConfiguration: async () => ({ + configPath: "", + result: error, + }), }); // Act @@ -74,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 @@ -128,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 456549321..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,33 +19,26 @@ export const convertEditorConfig = async ( dependencies: ConvertEditorConfigDependencies, settings: TSLintToESLintSettings, ): Promise => { - const editorConfigPath = settings.editor ?? DEFAULT_VSCODE_SETTINGS_PATH; - const originalEditorConfiguration = await dependencies.findEditorConfiguration( - editorConfigPath, - ); - - if (originalEditorConfiguration === undefined) { + const conversion = await dependencies.findEditorConfiguration(settings.editor); + if (conversion === undefined) { return { status: ResultStatus.Succeeded, }; } - if (originalEditorConfiguration instanceof Error) { + 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 7b5712d97..734395ca1 100644 --- a/src/input/findEditorConfiguration.test.ts +++ b/src/input/findEditorConfiguration.test.ts @@ -3,6 +3,7 @@ import { findEditorConfiguration, FindEditorConfigurationDependencies, } from "./findEditorConfiguration"; +import { DEFAULT_VSCODE_SETTINGS_PATH } from "./vsCodeSettings"; const stubConfigPath = "temp/"; @@ -16,7 +17,7 @@ const createStubDependencies = (overrides: Partial { - it("returns undefined when the file does not exist", async () => { + it("returns undefined when the file is not specified and does not exist", async () => { // Arrange const dependencies = createStubDependencies({ fileSystem: { @@ -25,12 +26,32 @@ describe("findEditorConfiguration", () => { }); // Act - const result = await findEditorConfiguration(dependencies, stubConfigPath); + 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"; @@ -44,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 () => { @@ -63,14 +85,30 @@ describe("findEditorConfiguration", () => { expect(dependencies.importer).toHaveBeenLastCalledWith(configPath); }); - it("parses object from configuration path when read successfully", async () => { + it("parses object from the default VS Code configuration path when the file is not specified and read successfully", async () => { + // Arrange + const originalConfig = { + "typescript.tsdk": "node_modules/typescript/lib", + }; + + const dependencies = createStubDependencies({ + importer: async () => originalConfig, + }); + + // Act + const result = await findEditorConfiguration(dependencies, undefined); + + // Assert + expect(result).toEqual({ + configPath: DEFAULT_VSCODE_SETTINGS_PATH, + result: originalConfig, + }); + }); + + 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({ @@ -81,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 6898c1a71..b02c0df96 100644 --- a/src/input/findEditorConfiguration.ts +++ b/src/input/findEditorConfiguration.ts @@ -1,9 +1,10 @@ +import { FileSystem } from "../adapters/fileSystem"; import { SansDependencies } from "../binding"; import { EditorConfiguration } from "./editorConfiguration"; import { findRawConfiguration } from "./findRawConfiguration"; import { DeepPartial } from "./findReportedConfiguration"; import { importer } from "./importer"; -import { FileSystem } from "../adapters/fileSystem"; +import { DEFAULT_VSCODE_SETTINGS_PATH } from "./vsCodeSettings"; export type FindEditorConfigurationDependencies = { fileSystem: Pick; @@ -12,14 +13,28 @@ export type FindEditorConfigurationDependencies = { export const findEditorConfiguration = async ( dependencies: FindEditorConfigurationDependencies, - config: string, -): Promise | Error | undefined> => { - if (!(await dependencies.fileSystem.fileExists(config))) { - return undefined; + 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}'.`, + ), + }; } - return await findRawConfiguration>( + const result = await findRawConfiguration>( dependencies.importer, - config, + attemptingConfigPath, ); + + return { + configPath: attemptingConfigPath, + result, + }; };