diff --git a/CHANGELOG.md b/CHANGELOG.md index 00c2bcf8e278..6e1f311f5e10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - `[expect]`: Improve report when matcher fails, part 7 ([#7866](https://github.com/facebook/jest/pull/7866)) - `[expect]`: Improve report when matcher fails, part 8 ([#7876](https://github.com/facebook/jest/pull/7876)) - `[pretty-format]` Support `React.memo` ([#7891](https://github.com/facebook/jest/pull/7891)) +- `[jest-config]` Print error information on preset normalization error ([#7935](https://github.com/facebook/jest/pull/7935)) ### Fixes diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index e1e24827dade..795d6b32aba9 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -934,6 +934,10 @@ describe('preset', () => { return '/node_modules/react-native/jest-preset.json'; } + if (name === 'react-native-js-preset/jest-preset') { + return '/node_modules/react-native-js-preset/jest-preset.js'; + } + if (name === 'doesnt-exist') { return null; } @@ -951,6 +955,15 @@ describe('preset', () => { }), {virtual: true}, ); + jest.doMock( + '/node_modules/react-native-js-preset/jest-preset.js', + () => ({ + moduleNameMapper: { + json: true, + }, + }), + {virtual: true}, + ); jest.mock( '/node_modules/with-json-ext/jest-preset.json', () => ({ @@ -1021,7 +1034,31 @@ describe('preset', () => { }, {}, ); - }).toThrowError(/Unexpected token }/); + }).toThrowError( + /Unexpected token } in JSON at position 104[\s\S]*at JSON.parse/, + ); + }); + + test('throws when preset evaluation throws type error', () => { + jest.doMock( + '/node_modules/react-native-js-preset/jest-preset.js', + () => ({ + transform: {}.nonExistingProp.call(), + }), + {virtual: true}, + ); + + expect(() => { + normalize( + { + preset: 'react-native-js-preset', + rootDir: '/root/path/foo', + }, + {}, + ); + }).toThrowError( + /TypeError: Cannot read property 'call' of undefined[\s\S]*at Object.call/, + ); }); test('works with "react-native"', () => { diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 4c2bee56f3cc..f938d520e03d 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -95,9 +95,11 @@ const setupPreset = ( // $FlowFixMe preset = (require(presetModule): InitialOptions); } catch (error) { - if (error instanceof SyntaxError) { + if (error instanceof SyntaxError || error instanceof TypeError) { throw createConfigError( - ` Preset ${chalk.bold(presetPath)} is invalid:\n ${error.message}`, + ` Preset ${chalk.bold(presetPath)} is invalid:\n\n ${ + error.message + }\n ${error.stack}`, ); }