From 382df360f23ecb15bd77d9062e7556ddc2a485e6 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 30 Aug 2019 09:31:06 +0200 Subject: [PATCH 1/2] fix: cache transforms within a worker --- CHANGELOG.md | 1 + e2e/__tests__/transform.test.ts | 22 +++++++++++++++++++ e2e/transform/cache/__tests__/aTests.js | 12 ++++++++++ e2e/transform/cache/__tests__/bTests.js | 12 ++++++++++ e2e/transform/cache/__tests__/cTests.js | 12 ++++++++++ e2e/transform/cache/__tests__/dTests.js | 12 ++++++++++ e2e/transform/cache/common-file.js | 8 +++++++ e2e/transform/cache/package.json | 10 +++++++++ e2e/transform/cache/transformer.js | 16 ++++++++++++++ .../jest-transform/src/ScriptTransformer.ts | 12 +++++----- 10 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 e2e/transform/cache/__tests__/aTests.js create mode 100644 e2e/transform/cache/__tests__/bTests.js create mode 100644 e2e/transform/cache/__tests__/cTests.js create mode 100644 e2e/transform/cache/__tests__/dTests.js create mode 100644 e2e/transform/cache/common-file.js create mode 100644 e2e/transform/cache/package.json create mode 100644 e2e/transform/cache/transformer.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 84bcead3d743..4ac2c0d1f3a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - `[jest-mock]` Fix for mockReturnValue overriding mockImplementationOnce ([#8398](https://github.com/facebook/jest/pull/8398)) - `[jest-snapshot]` Remove only the added newlines in multiline snapshots ([#8859](https://github.com/facebook/jest/pull/8859)) - `[jest-snapshot]` Distinguish empty string from external snapshot not written ([#8880](https://github.com/facebook/jest/pull/8880)) +- `[jest-transform]` Properly cache transformed files across tests ([#8890](https://github.com/facebook/jest/pull/8890)) ### Chore & Maintenance diff --git a/e2e/__tests__/transform.test.ts b/e2e/__tests__/transform.test.ts index a62524d3640a..d297ef3960ab 100644 --- a/e2e/__tests__/transform.test.ts +++ b/e2e/__tests__/transform.test.ts @@ -185,3 +185,25 @@ describe('transformer-config', () => { expect(stdout).toMatchSnapshot(); }); }); + +describe('transformer caching', () => { + const dir = path.resolve(__dirname, '..', 'transform/cache'); + const dirRegexp = new RegExp('^' + dir); + + it('does not rerun transform within worker', () => { + // --no-cache because babel can cache stuff and result in false green + const {stdout} = runJest(dir, ['--no-cache', '-w=2']); + + const loggedFiles = stdout.split('\n').map(line => { + expect(line).toMatch(dirRegexp); + + return line.replace(dirRegexp, ''); + }); + + // We run with 2 workers, so the file should be transformed twice + expect(loggedFiles).toEqual([ + '/common-file.js', + '/common-file.js', + ]); + }); +}); diff --git a/e2e/transform/cache/__tests__/aTests.js b/e2e/transform/cache/__tests__/aTests.js new file mode 100644 index 000000000000..2f8f32a8b022 --- /dev/null +++ b/e2e/transform/cache/__tests__/aTests.js @@ -0,0 +1,12 @@ +/** + * 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. + */ + +const phrase = require('../common-file'); + +test('A', () => { + expect(phrase).toBe('hello'); +}); diff --git a/e2e/transform/cache/__tests__/bTests.js b/e2e/transform/cache/__tests__/bTests.js new file mode 100644 index 000000000000..c896f74c4967 --- /dev/null +++ b/e2e/transform/cache/__tests__/bTests.js @@ -0,0 +1,12 @@ +/** + * 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. + */ + +const phrase = require('../common-file'); + +test('B', () => { + expect(phrase).toBe('hello'); +}); diff --git a/e2e/transform/cache/__tests__/cTests.js b/e2e/transform/cache/__tests__/cTests.js new file mode 100644 index 000000000000..55827295d0af --- /dev/null +++ b/e2e/transform/cache/__tests__/cTests.js @@ -0,0 +1,12 @@ +/** + * 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. + */ + +const phrase = require('../common-file'); + +test('C', () => { + expect(phrase).toBe('hello'); +}); diff --git a/e2e/transform/cache/__tests__/dTests.js b/e2e/transform/cache/__tests__/dTests.js new file mode 100644 index 000000000000..74716a8e9aa3 --- /dev/null +++ b/e2e/transform/cache/__tests__/dTests.js @@ -0,0 +1,12 @@ +/** + * 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. + */ + +const phrase = require('../common-file'); + +test('D', () => { + expect(phrase).toBe('hello'); +}); diff --git a/e2e/transform/cache/common-file.js b/e2e/transform/cache/common-file.js new file mode 100644 index 000000000000..798c701db1fa --- /dev/null +++ b/e2e/transform/cache/common-file.js @@ -0,0 +1,8 @@ +/** + * 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 = 'hello'; diff --git a/e2e/transform/cache/package.json b/e2e/transform/cache/package.json new file mode 100644 index 000000000000..d75bca46c3ba --- /dev/null +++ b/e2e/transform/cache/package.json @@ -0,0 +1,10 @@ +{ + "name": "cache", + "version": "1.0.0", + "jest": { + "testEnvironment": "node", + "transform": { + "^.+\\.js$": "/transformer.js" + } + } +} diff --git a/e2e/transform/cache/transformer.js b/e2e/transform/cache/transformer.js new file mode 100644 index 000000000000..10d02e637f80 --- /dev/null +++ b/e2e/transform/cache/transformer.js @@ -0,0 +1,16 @@ +/** + * 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 = { + process(src, path) { + if (path.includes('common')) { + console.log(path); + } + + return src; + }, +}; diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index 3057dbe6586e..9079e9f90efd 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -43,10 +43,7 @@ const {version: VERSION} = require('../package.json'); // This data structure is used to avoid recalculating some data every time that // we need to transform a file. Since ScriptTransformer is instantiated for each // file we need to keep this object in the local scope of this module. -const projectCaches: WeakMap< - Config.ProjectConfig, - ProjectCache -> = new WeakMap(); +const projectCaches = new Map(); // To reset the cache for specific changesets (rather than package version). const CACHE_VERSION = '1'; @@ -74,17 +71,18 @@ export default class ScriptTransformer { this._transformCache = new Map(); this._transformConfigCache = new Map(); - let projectCache = projectCaches.get(config); + const configString = stableStringify(this._config); + let projectCache = projectCaches.get(configString); if (!projectCache) { projectCache = { - configString: stableStringify(this._config), + configString, ignorePatternsRegExp: calcIgnorePatternRegExp(this._config), transformRegExp: calcTransformRegExp(this._config), transformedFiles: new Map(), }; - projectCaches.set(config, projectCache); + projectCaches.set(configString, projectCache); } this._cache = projectCache; From 0b9d35c313312047d8b270bc306dc5df71c44b62 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 30 Aug 2019 09:58:40 +0200 Subject: [PATCH 2/2] windows test fix --- e2e/__tests__/transform.test.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/e2e/__tests__/transform.test.ts b/e2e/__tests__/transform.test.ts index d297ef3960ab..d00f6189af49 100644 --- a/e2e/__tests__/transform.test.ts +++ b/e2e/__tests__/transform.test.ts @@ -187,23 +187,21 @@ describe('transformer-config', () => { }); describe('transformer caching', () => { - const dir = path.resolve(__dirname, '..', 'transform/cache'); - const dirRegexp = new RegExp('^' + dir); + const dir = path.resolve(__dirname, '../transform/cache'); + const transformedFile = path.resolve(dir, './common-file.js'); it('does not rerun transform within worker', () => { // --no-cache because babel can cache stuff and result in false green const {stdout} = runJest(dir, ['--no-cache', '-w=2']); - const loggedFiles = stdout.split('\n').map(line => { - expect(line).toMatch(dirRegexp); + const loggedFiles = stdout.split('\n'); - return line.replace(dirRegexp, ''); + // Verify any lines logged are _just_ the file we care about + loggedFiles.forEach(line => { + expect(line).toBe(transformedFile); }); // We run with 2 workers, so the file should be transformed twice - expect(loggedFiles).toEqual([ - '/common-file.js', - '/common-file.js', - ]); + expect(loggedFiles).toHaveLength(2); }); });