From dc49660249b152dec9f6c6e498194da03fa56618 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Fri, 20 Jan 2017 12:13:43 -0700 Subject: [PATCH] fix(modules): use prettier-eslint versions of modules if needed This way you can install prettier-eslint and not have prettier or eslint installed yourself and it should still work. --- package.json | 2 +- src/__mocks__/eslint.js | 9 +++++++-- src/__mocks__/prettier.js | 1 + src/index.js | 7 ++++++- src/index.test.js | 12 ++++++++++++ tests/fixtures/paths/node_modules/eslint/index.js | 13 +++++++++++-- tests/fixtures/paths/node_modules/prettier/index.js | 13 +++++++++++-- 7 files changed, 49 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 685557c4..487045f4 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ } }, "jest": { - "testEnvironment": "node", + "testEnvironment": "jest-environment-node", "coverageThreshold": { "global": { "branches": 100, diff --git a/src/__mocks__/eslint.js b/src/__mocks__/eslint.js index fb519228..a944b8d5 100644 --- a/src/__mocks__/eslint.js +++ b/src/__mocks__/eslint.js @@ -1,5 +1,5 @@ // this mock file is so eslint doesn't attempt to actually -// search around the filesystem for stuff +// search around the file system for stuff const eslint = require.requireActual('eslint') const {CLIEngine} = eslint @@ -17,9 +17,14 @@ module.exports = Object.assign(eslint, { }) function MockCLIEngine(...args) { + global.__PRETTIER_ESLINT_TEST_STATE__.eslintPath = __filename CLIEngine.apply(this, args) + // not sure why, but in some cases, this.executeOnText is undefined... + // so we create a fakeCLIEngine to get a copy of that function + // and call it with apply :) + const fakeCLIEngine = new CLIEngine(...args) this.getConfigForFile = mockGetConfigForFileSpy - this._originalExecuteOnText = this.executeOnText + this._originalExecuteOnText = fakeCLIEngine.executeOnText this.executeOnText = mockExecuteOnTextSpy } diff --git a/src/__mocks__/prettier.js b/src/__mocks__/prettier.js index e7412083..ab323db1 100644 --- a/src/__mocks__/prettier.js +++ b/src/__mocks__/prettier.js @@ -10,6 +10,7 @@ Object.assign(prettier, { }) function mockFormat(...args) { + global.__PRETTIER_ESLINT_TEST_STATE__.prettierPath = __filename if (mockFormatSpy.throwError) { throw mockFormatSpy.throwError } diff --git a/src/index.js b/src/index.js index 4577f8cd..eef649f5 100644 --- a/src/index.js +++ b/src/index.js @@ -120,7 +120,12 @@ function getConfig(filePath, eslintPath) { } function getModulePath(filePath = __filename, moduleName) { - return requireRelative.resolve(moduleName, filePath) + try { + return requireRelative.resolve(moduleName, filePath) + } catch (error) { + logError(`There was a problem finding the ${moduleName} module. Using prettier-eslint's version`, error.stack) + return require.resolve(moduleName) + } } function getESLintCLIEngine(eslintPath, eslintOptions) { diff --git a/src/index.test.js b/src/index.test.js index d03b2a84..cd86c6bd 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -203,6 +203,18 @@ test('resolves to the eslint module relative to the given filePath', () => { }) }) +test('resolves to the local eslint module if none is found via the filePath', () => { + const filePath = '/blah-blah/default-config' + format({text: '', filePath}) + expect(global.__PRETTIER_ESLINT_TEST_STATE__).toMatchObject({ + // without Jest's mocking, these would actually resolve to the + // project modules :) The fact that jest's mocking is being + // applied is good enough for this test. + eslintPath: require.resolve('./__mocks__/eslint'), + prettierPath: require.resolve('./__mocks__/prettier'), + }) +}) + function getESLintConfigWithDefaultRules(overrides) { return { parserOptions: { diff --git a/tests/fixtures/paths/node_modules/eslint/index.js b/tests/fixtures/paths/node_modules/eslint/index.js index 811e3317..1544d74e 100644 --- a/tests/fixtures/paths/node_modules/eslint/index.js +++ b/tests/fixtures/paths/node_modules/eslint/index.js @@ -1,3 +1,12 @@ -module.exports = require('../../../../../src/__mocks__/eslint') -global.__PRETTIER_ESLINT_TEST_STATE__.eslintPath = __filename +const eslintMock = require('../../../../../src/__mocks__/eslint') +module.exports = Object.assign({}, eslintMock, { + CLIEngine: MockMockCLIEngine +}) +function MockMockCLIEngine(...args) { + try { + return eslintMock.CLIEngine.apply(this, args) + } finally { + global.__PRETTIER_ESLINT_TEST_STATE__.eslintPath = __filename + } +} diff --git a/tests/fixtures/paths/node_modules/prettier/index.js b/tests/fixtures/paths/node_modules/prettier/index.js index a857f86f..69adb190 100644 --- a/tests/fixtures/paths/node_modules/prettier/index.js +++ b/tests/fixtures/paths/node_modules/prettier/index.js @@ -1,2 +1,11 @@ -module.exports = require('../../../../../src/__mocks__/prettier') -global.__PRETTIER_ESLINT_TEST_STATE__.prettierPath = __filename +const mockPrettier = require('../../../../../src/__mocks__/prettier') + +module.exports = {format: mockMockFormat} + +function mockMockFormat(...args) { + try { + return mockPrettier.format(...args) + } finally { + global.__PRETTIER_ESLINT_TEST_STATE__.prettierPath = __filename + } +}