diff --git a/CHANGELOG.md b/CHANGELOG.md index f2b7eb21d189..1173fdfe4ff2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - `[jest-fake-timers]` `getTimerCount` not taking immediates and ticks into account ([#8139](https://github.com/facebook/jest/pull/8139)) - `[jest-runtime]` Allow json file as manual mock ([#8159](https://github.com/facebook/jest/pull/8159)) - `[pretty-format]` Print `BigInt` as a readable number instead of `{}` ([#8138](https://github.com/facebook/jest/pull/8138)) +- `[jest-core]` Fix ability to transform dependencies required from globalSetup script [#8143](https://github.com/facebook/jest/pull/8143) ### Chore & Maintenance diff --git a/e2e/__tests__/globalSetup.test.ts b/e2e/__tests__/globalSetup.test.ts index 4ed55175c4b2..021f6c4e5719 100644 --- a/e2e/__tests__/globalSetup.test.ts +++ b/e2e/__tests__/globalSetup.test.ts @@ -19,18 +19,21 @@ const customTransformDIR = path.join( os.tmpdir(), 'jest-global-setup-custom-transform', ); +const nodeModulesDIR = path.join(os.tmpdir(), 'jest-global-setup-node-modules'); beforeEach(() => { cleanup(DIR); cleanup(project1DIR); cleanup(project2DIR); cleanup(customTransformDIR); + cleanup(nodeModulesDIR); }); afterAll(() => { cleanup(DIR); cleanup(project1DIR); cleanup(project2DIR); cleanup(customTransformDIR); + cleanup(nodeModulesDIR); }); test('globalSetup is triggered once before all test suites', () => { @@ -166,3 +169,9 @@ test('should not transpile the transformer', () => { expect(status).toBe(0); }); + +test('should transform node_modules if configured by transformIgnorePatterns', () => { + const {status} = runJest('global-setup-node-modules', [`--no-cache`]); + + expect(status).toBe(0); +}); diff --git a/e2e/global-setup-node-modules/.gitignore b/e2e/global-setup-node-modules/.gitignore new file mode 100644 index 000000000000..cf4bab9ddde9 --- /dev/null +++ b/e2e/global-setup-node-modules/.gitignore @@ -0,0 +1 @@ +!node_modules diff --git a/e2e/global-setup-node-modules/__tests__/test.js b/e2e/global-setup-node-modules/__tests__/test.js new file mode 100644 index 000000000000..059e2e2483e4 --- /dev/null +++ b/e2e/global-setup-node-modules/__tests__/test.js @@ -0,0 +1,20 @@ +/** + * 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'; + +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +const DIR = path.join(os.tmpdir(), 'jest-global-setup-node-modules'); + +test('should exist setup file', () => { + const files = fs.readdirSync(DIR); + expect(files).toHaveLength(1); + const setup = fs.readFileSync(path.join(DIR, files[0]), 'utf8'); + expect(setup).toBe('hello world!'); +}); diff --git a/e2e/global-setup-node-modules/babel.config.js b/e2e/global-setup-node-modules/babel.config.js new file mode 100644 index 000000000000..c3f9e017c09b --- /dev/null +++ b/e2e/global-setup-node-modules/babel.config.js @@ -0,0 +1,18 @@ +/** + * 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. + */ +module.exports = { + presets: [ + [ + '@babel/preset-env', + { + targets: { + node: 'current', + }, + }, + ], + ], +}; diff --git a/e2e/global-setup-node-modules/node_modules/example/index.js b/e2e/global-setup-node-modules/node_modules/example/index.js new file mode 100644 index 000000000000..61bb580e9ce0 --- /dev/null +++ b/e2e/global-setup-node-modules/node_modules/example/index.js @@ -0,0 +1,9 @@ +/** + * 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. + */ +export default function example() { + return 'world!'; +} diff --git a/e2e/global-setup-node-modules/package.json b/e2e/global-setup-node-modules/package.json new file mode 100644 index 000000000000..dd05160ee540 --- /dev/null +++ b/e2e/global-setup-node-modules/package.json @@ -0,0 +1,8 @@ +{ + "jest": { + "testEnvironment": "node", + "globalSetup": "/setup.js", + "transformIgnorePatterns": [ + ] + } +} diff --git a/e2e/global-setup-node-modules/setup.js b/e2e/global-setup-node-modules/setup.js new file mode 100644 index 000000000000..edea4d43a008 --- /dev/null +++ b/e2e/global-setup-node-modules/setup.js @@ -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 example from './node_modules/example'; +const crypto = require('crypto'); +const fs = require('fs'); +const {createDirectory} = require('jest-util'); +const os = require('os'); +const path = require('path'); + +const DIR = path.join(os.tmpdir(), 'jest-global-setup-node-modules'); + +module.exports = function() { + return new Promise(resolve => { + createDirectory(DIR); + const fileId = crypto.randomBytes(20).toString('hex'); + fs.writeFileSync(path.join(DIR, fileId), `hello ${example()}`); + resolve(); + }); +}; diff --git a/e2e/global-setup-node-modules/yarn.lock b/e2e/global-setup-node-modules/yarn.lock new file mode 100644 index 000000000000..6febeb67c34b --- /dev/null +++ b/e2e/global-setup-node-modules/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +lodash-es@^4.17.11: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.11.tgz#145ab4a7ac5c5e52a3531fb4f310255a152b4be0" + integrity sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q== diff --git a/packages/jest-core/src/runGlobalHook.ts b/packages/jest-core/src/runGlobalHook.ts index 7b81a588d521..6b20792ba019 100644 --- a/packages/jest-core/src/runGlobalHook.ts +++ b/packages/jest-core/src/runGlobalHook.ts @@ -51,12 +51,28 @@ export default async ({ // transformer in order to transform it in the require hooks transformer.preloadTransformer(modulePath); + let transforming = false; const revertHook = addHook( - (code, filename) => - transformer.transformSource(filename, code, false).code || code, + (code, filename) => { + try { + transforming = true; + return ( + transformer.transformSource(filename, code, false).code || code + ); + } finally { + transforming = false; + } + }, { exts: [extname(modulePath)], - matcher: transformer.shouldTransform.bind(transformer), + ignoreNodeModules: false, + matcher: (...args) => { + if (transforming) { + // Don't transform any dependency required by the transformer itself + return false; + } + return transformer.shouldTransform(...args); + }, }, );