From 2a1a8bae883eb4f3ec7a651338ffa9bf6ee280a5 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 17 Jul 2019 14:02:00 +0200 Subject: [PATCH] fix: improve error on module not found --- CHANGELOG.md | 1 + .../moduleNameMapper.test.ts.snap | 6 +- .../requireMissingExt.test.ts.snap | 32 +++++++ .../resolveNoFileExtensions.test.ts.snap | 3 +- e2e/__tests__/requireMissingExt.test.ts | 23 +++++ e2e/require-missing-ext/__tests__/test.js | 14 +++ e2e/require-missing-ext/package.json | 10 ++ e2e/require-missing-ext/yarn.lock | 94 +++++++++++++++++++ packages/jest-environment-node/src/index.ts | 4 + packages/jest-runner/src/runTest.ts | 3 + 10 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 e2e/__tests__/__snapshots__/requireMissingExt.test.ts.snap create mode 100644 e2e/__tests__/requireMissingExt.test.ts create mode 100644 e2e/require-missing-ext/__tests__/test.js create mode 100644 e2e/require-missing-ext/package.json create mode 100644 e2e/require-missing-ext/yarn.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index fec173370b0c..f68c0effabdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Fixes - `[jest-core]` Capture execError during `TestScheduler.scheduleTests` and dispatch to reporters ([#13203](https://github.com/facebook/jest/pull/13203)) +- `[jest-resolve]` Improve error on module not found deep in the `require` stack ([#8704](https://github.com/facebook/jest/pull/8704) ### Chore & Maintenance diff --git a/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap b/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap index 62553cf7f7aa..c7eb02d6cfe1 100644 --- a/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap +++ b/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap @@ -42,7 +42,8 @@ exports[`moduleNameMapper wrong array configuration 1`] = ` 13 | at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:896:17) - at Object.require (index.js:10:1)" + at Object.require (index.js:10:1) + at Object.require (__tests__/index.js:10:20)" `; exports[`moduleNameMapper wrong configuration 1`] = ` @@ -71,5 +72,6 @@ exports[`moduleNameMapper wrong configuration 1`] = ` 13 | at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:896:17) - at Object.require (index.js:10:1)" + at Object.require (index.js:10:1) + at Object.require (__tests__/index.js:10:20)" `; diff --git a/e2e/__tests__/__snapshots__/requireMissingExt.test.ts.snap b/e2e/__tests__/__snapshots__/requireMissingExt.test.ts.snap new file mode 100644 index 000000000000..b3a529188daa --- /dev/null +++ b/e2e/__tests__/__snapshots__/requireMissingExt.test.ts.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`shows a proper error from deep requires 1`] = ` +"FAIL __tests__/test.js + ● Test suite failed to run + + Cannot find module '../package' from 'node_modules/discord.js/src/index.js' + + Require stack: + node_modules/discord.js/src/index.js + __tests__/test.js + + + However, Jest was able to find: + '../package.json' + + You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js']. + + See https://jestjs.io/docs/configuration#modulefileextensions-arraystring + + 8 | 'use strict'; + 9 | + > 10 | require('discord.js'); + | ^ + 11 | + 12 | test('dummy', () => { + 13 | expect(1).toBe(1); + + at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/resolver.js:487:11) + at Object. (node_modules/discord.js/src/index.js:21:12) + at Object.require (__tests__/test.js:10:1)" +`; diff --git a/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap b/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap index 62ed2a7e4489..b906b0cf9d7d 100644 --- a/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap +++ b/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap @@ -38,5 +38,6 @@ exports[`show error message with matching files 1`] = ` 9 | at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/resolver.js:487:11) - at Object.require (index.js:8:18)" + at Object.require (index.js:8:18) + at Object.require (__tests__/test.js:8:11)" `; diff --git a/e2e/__tests__/requireMissingExt.test.ts b/e2e/__tests__/requireMissingExt.test.ts new file mode 100644 index 000000000000..3421e13af9da --- /dev/null +++ b/e2e/__tests__/requireMissingExt.test.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import * as path from 'path'; +import {extractSummary, runYarnInstall} from '../Utils'; +import runJest from '../runJest'; + +const dir = path.resolve(__dirname, '../require-missing-ext'); + +beforeEach(() => { + runYarnInstall(dir); +}); + +test('shows a proper error from deep requires', () => { + const {stderr} = runJest(dir); + const {rest} = extractSummary(stderr); + + expect(rest).toMatchSnapshot(); +}); diff --git a/e2e/require-missing-ext/__tests__/test.js b/e2e/require-missing-ext/__tests__/test.js new file mode 100644 index 000000000000..55370ccafe8f --- /dev/null +++ b/e2e/require-missing-ext/__tests__/test.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +require('discord.js'); + +test('dummy', () => { + expect(1).toBe(1); +}); diff --git a/e2e/require-missing-ext/package.json b/e2e/require-missing-ext/package.json new file mode 100644 index 000000000000..b560faa1f460 --- /dev/null +++ b/e2e/require-missing-ext/package.json @@ -0,0 +1,10 @@ +{ + "jest": { + "moduleFileExtensions": [ + "js" + ] + }, + "dependencies": { + "discord.js": "11.5.1" + } +} diff --git a/e2e/require-missing-ext/yarn.lock b/e2e/require-missing-ext/yarn.lock new file mode 100644 index 000000000000..bc174f12123f --- /dev/null +++ b/e2e/require-missing-ext/yarn.lock @@ -0,0 +1,94 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 6 + cacheKey: 8 + +"async-limiter@npm:~1.0.0": + version: 1.0.1 + resolution: "async-limiter@npm:1.0.1" + checksum: 2b849695b465d93ad44c116220dee29a5aeb63adac16c1088983c339b0de57d76e82533e8e364a93a9f997f28bbfc6a92948cefc120652bd07f3b59f8d75cf2b + languageName: node + linkType: hard + +"discord.js@npm:11.5.1": + version: 11.5.1 + resolution: "discord.js@npm:11.5.1" + dependencies: + long: ^4.0.0 + prism-media: ^0.0.3 + snekfetch: ^3.6.4 + tweetnacl: ^1.0.0 + ws: ^6.0.0 + peerDependencies: + "@discordjs/uws": ^10.149.0 + bufferutil: ^4.0.0 + erlpack: "*" + libsodium-wrappers: ^0.7.3 + node-opus: ^0.2.7 + opusscript: ^0.0.6 + sodium: ^2.0.3 + peerDependenciesMeta: + bufferutil: + optional: true + erlpack: + optional: true + libsodium-wrappers: + optional: true + node-opus: + optional: true + opusscript: + optional: true + sodium: + optional: true + uws: + optional: true + checksum: fdd210b1a63bff6d39eae8c79beb2f1035d16b029a361142f9148e3ba6819e685872af2435e8cfef0b71b4871f14d4bcb7a4ce9f4c957c7a4aca1a347b3229f0 + languageName: node + linkType: hard + +"long@npm:^4.0.0": + version: 4.0.0 + resolution: "long@npm:4.0.0" + checksum: 16afbe8f749c7c849db1f4de4e2e6a31ac6e617cead3bdc4f9605cb703cd20e1e9fc1a7baba674ffcca57d660a6e5b53a9e236d7b25a295d3855cca79cc06744 + languageName: node + linkType: hard + +"prism-media@npm:^0.0.3": + version: 0.0.3 + resolution: "prism-media@npm:0.0.3" + checksum: 45d56138bd48616d78ec2f09b77e3700c88a4e08fb159949ee0b47fe5ce9db2d68ceac4729faebada4a23b640a9f984e7dd9b4bc72b2f52666307ca9d559fcfb + languageName: node + linkType: hard + +"root-workspace-0b6124@workspace:.": + version: 0.0.0-use.local + resolution: "root-workspace-0b6124@workspace:." + dependencies: + discord.js: 11.5.1 + languageName: unknown + linkType: soft + +"snekfetch@npm:^3.6.4": + version: 3.6.4 + resolution: "snekfetch@npm:3.6.4" + checksum: e64b383a19ced759f061ecd43bc9a75bcc9b996d1909f9b94e6aaf66b6579024340c904af05aeba6261a8dd4ad9f71763f47e134c8089707d4be10fcfc682ed9 + languageName: node + linkType: hard + +"tweetnacl@npm:^1.0.0": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: e4a57cac188f0c53f24c7a33279e223618a2bfb5fea426231991652a13247bea06b081fd745d71291fcae0f4428d29beba1b984b1f1ce6f66b06a6d1ab90645c + languageName: node + linkType: hard + +"ws@npm:^6.0.0": + version: 6.2.2 + resolution: "ws@npm:6.2.2" + dependencies: + async-limiter: ~1.0.0 + checksum: aec3154ec51477c094ac2cb5946a156e17561a581fa27005cbf22c53ac57f8d4e5f791dd4bbba6a488602cb28778c8ab7df06251d590507c3c550fd8ebeee949 + languageName: node + linkType: hard diff --git a/packages/jest-environment-node/src/index.ts b/packages/jest-environment-node/src/index.ts index 96c5db2acffa..97f8e319f7ba 100644 --- a/packages/jest-environment-node/src/index.ts +++ b/packages/jest-environment-node/src/index.ts @@ -112,6 +112,10 @@ export default class NodeEnvironment implements JestEnvironment { installCommonGlobals(global, projectConfig.globals); + // Node's error-message stack size is limited at 10, but it's pretty useful + // to see more than that when a test fails. + global.Error.stackTraceLimit = 100; + if ('customExportConditions' in projectConfig.testEnvironmentOptions) { const {customExportConditions} = projectConfig.testEnvironmentOptions; if ( diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index f743d3b76f6d..40b69f771207 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -273,6 +273,9 @@ async function runTestInternal( globalConfig.coverageProvider === 'v8' && typeof environment.getVmContext === 'function'; + // Node's error-message stack size is limited at 10, but it's pretty useful + // to see more than that when a test fails. + Error.stackTraceLimit = 100; try { await environment.setup();