diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..eccda34 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,157 @@ +function* range(min, max) { + for (let num = min; num < max; num++) { + yield num + } +} + +module.exports = { + env: { + es2021: true, + node: true, + }, + extends: ["eslint:recommended", "plugin:@typescript-eslint/eslint-recommended"], + parser: "@typescript-eslint/parser", + globals: { + Atomics: "readonly", + SharedArrayBuffer: "readonly", + }, + parserOptions: { + ecmaVersion: 2021, + sourceType: "module", + project: ["./tsconfig.json"], + }, + plugins: ["@typescript-eslint", "prefer-arrow"], + rules: { + // General ESLint rules + "arrow-body-style": ["warn", "as-needed"], + "default-case-last": "warn", + "dot-location": ["warn", "property"], + eqeqeq: "error", + "id-length": ["error", {exceptions: ["_", "$"]}], + "max-len": "off", + "max-lines": ["warn", 500], + "max-statements": ["warn", {max: 25}], + "no-else-return": "warn", + "no-empty": ["warn", {allowEmptyCatch: true}], + "no-extra-semi": "off", + "no-negated-condition": "warn", + "no-nested-ternary": "warn", + "no-unused-vars": "off", + "no-var": "warn", + "object-shorthand": "warn", + "one-var": ["warn", "never"], + "padding-line-between-statements": [ + "warn", + {blankLine: "always", prev: "*", next: "return"}, + {blankLine: "always", prev: ["const", "let", "var"], next: "*"}, + {blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]}, + {blankLine: "always", prev: "function", next: "*"}, + ], + "prefer-const": "warn", + "prefer-destructuring": [ + "error", + { + array: false, + object: true, + }, + ], + "prefer-exponentiation-operator": "warn", + "prefer-object-spread": "warn", + "prefer-template": "warn", + "require-await": "warn", + "require-unicode-regexp": "warn", + "sort-imports": ["warn"], + + // Typescript Rules + "@typescript-eslint/array-type": "warn", + "@typescript-eslint/consistent-indexed-object-style": ["warn", "index-signature"], + "@typescript-eslint/consistent-type-assertions": ["warn", {assertionStyle: "as"}], + "@typescript-eslint/member-ordering": "warn", + "@typescript-eslint/naming-convention": [ + "error", + { + selector: "default", + format: ["camelCase"], + }, + { + selector: "variableLike", + format: ["camelCase"], + leadingUnderscore: "allow", + }, + { + selector: "memberLike", + modifiers: ["private"], + format: ["camelCase"], + leadingUnderscore: "require", + }, + { + selector: "property", + modifiers: ["private"], + format: ["camelCase"], + leadingUnderscore: "require", + }, + { + selector: "typeLike", + format: ["PascalCase"], + }, + { + selector: "variable", + types: ["boolean"], + format: ["PascalCase"], + prefix: ["is", "should", "has", "can", "did", "will"], + }, + { + selector: "parameter", + format: ["camelCase"], + leadingUnderscore: "allow", + }, + { + selector: "property", + format: ["camelCase", "PascalCase", "snake_case", "UPPER_CASE"], + }, + { + selector: "enumMember", + format: ["camelCase", "PascalCase", "snake_case", "UPPER_CASE"], + }, + ], + "@typescript-eslint/no-magic-numbers": [ + "warn", + { + ignoreEnums: true, + ignoreNumericLiteralTypes: true, + ignoreReadonlyClassProperties: true, + ignoreArrayIndexes: true, + ignore: [...Array.from(range(-10, 11)), 16, 32, 64, 128, 256, 512], + }, + ], + "@typescript-eslint/no-unnecessary-boolean-literal-compare": "warn", + "@typescript-eslint/prefer-for-of": "warn", + "@typescript-eslint/prefer-function-type": "warn", + "@typescript-eslint/prefer-optional-chain": "warn", + + // Typescript extension rules + "@typescript-eslint/default-param-last": "warn", + "@typescript-eslint/dot-notation": "warn", + "@typescript-eslint/lines-between-class-members": ["warn", "always"], + "@typescript-eslint/no-dupe-class-members": "warn", + "no-duplicate-imports": "warn", + "@typescript-eslint/no-extra-semi": "off", + "@typescript-eslint/no-shadow": "warn", + "@typescript-eslint/no-unused-expressions": "warn", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "warn", + "@typescript-eslint/no-use-before-define": "warn", + + // Preter arrow rules + "prefer-arrow-callback": "warn", + "prefer-arrow/prefer-arrow-functions": [ + "warn", + { + disallowPrototype: true, + singleReturnOnly: false, + classPropertiesAllowed: true, + allowStandaloneDeclarations: false, + }, + ], + }, +} diff --git a/__tests__/index.ts b/__tests__/index.ts new file mode 100644 index 0000000..f9aebf1 --- /dev/null +++ b/__tests__/index.ts @@ -0,0 +1,63 @@ +import {escapeExecutablePath} from "../src/utils/escapePath" + +describe("test path escape", () => { + it("should escape Windows path with space", () => { + const originalPath = "C:\\Program Files\\processing\\processing-java" + + expect(escapeExecutablePath(originalPath)).toBe( + "C:\\Program` Files\\processing\\processing-java", + ) + }) + + it("should escape Unix path with space", () => { + const originalPath = "/usr/bin/something else/processing-java" + + expect(escapeExecutablePath(originalPath)).toBe( + "/usr/bin/something\\ else/processing-java", + ) + }) + + it("should leave Windows path without spaces as is", () => { + const originalPath = ".\\processing\\processing-java" + + expect(escapeExecutablePath(originalPath)).toBe(".\\processing\\processing-java") + }) + + it("should leave Unix path without spaces as is", () => { + const originalPath = "/usr/bin/processing-java" + + expect(escapeExecutablePath(originalPath)).toBe("/usr/bin/processing-java") + }) + + it("should not escape already escaped spaces on Windows", () => { + const originalPath = "C:\\Program` Files\\processing\\processing java" + + expect(escapeExecutablePath(originalPath)).toBe( + "C:\\Program` Files\\processing\\processing` java", + ) + }) + + it("should not escape already escaped spaces on Unix", () => { + const originalPath = "/usr/bin/something else/processing\\ java" + + expect(escapeExecutablePath(originalPath)).toBe( + "/usr/bin/something\\ else/processing\\ java", + ) + }) + + it("should detect platform if no path seperators available", () => { + const originalPath = "processing java" + + if (process.platform === "win32") { + expect(escapeExecutablePath(originalPath)).toBe("processing` java") + } else { + expect(escapeExecutablePath(originalPath)).toBe("processing\\ java") + } + }) + + it("should leave single path as is", () => { + const originalPath = "processing-java" + + expect(escapeExecutablePath(originalPath)).toBe("processing-java") + }) +}) diff --git a/jest.config.mjs b/jest.config.mjs new file mode 100644 index 0000000..7e72d9d --- /dev/null +++ b/jest.config.mjs @@ -0,0 +1,21 @@ +/** @type {import("ts-jest/dist/types").InitialOptionsTsJest} */ +export default { + preset: "ts-jest", + testEnvironment: "node", + // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module + moduleNameMapper: { + // https://github.com/kulshekhar/ts-jest/issues/1057#issuecomment-1303376233 + "^(\\.{1,2}/.*)\\.[jt]s$": "$1", + }, + + // A map from regular expressions to paths to transformers + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + tsconfig: "/tsconfig.json", + useESM: true, + }, + ], + }, +}