From e816ee4a6ef16bb5fc7b1c56d72807d99c11620a Mon Sep 17 00:00:00 2001 From: coffeebeats <108542400+coffeebeats@users.noreply.github.com> Date: Fri, 13 Jan 2023 18:30:57 -0800 Subject: [PATCH 1/3] fix(jest-transform): ensure correct config is passed to preprocessors specified multiple times in `transform` --- .../jest-transform/src/ScriptTransformer.ts | 52 ++++++++++++++----- .../src/__tests__/ScriptTransformer.test.ts | 41 ++++++++++++++- 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index c1d12d8deef9..17b3ce1f4a47 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -134,6 +134,10 @@ class ScriptTransformer { .substring(0, 32); } + private _buildTransformCacheKey(pattern: string, filepath: string) { + return pattern + filepath; + } + private _getCacheKey( fileData: string, filename: string, @@ -243,25 +247,35 @@ class ScriptTransformer { return this._createCachedFilename(filename, cacheKey); } - private _getTransformPath(filename: string) { - const transformRegExp = this._cache.transformRegExp; - if (!transformRegExp) { + private _getTransformPatternAndPath(filename: string) { + const transformEntry = this._cache.transformRegExp; + if (transformEntry == null) { return undefined; } - for (let i = 0; i < transformRegExp.length; i++) { - if (transformRegExp[i][0].test(filename)) { - return transformRegExp[i][1]; + for (let i = 0; i < transformEntry.length; i++) { + const [transformRegExp, transformPath] = transformEntry[i]; + if (transformRegExp.test(filename)) { + return [transformRegExp.source, transformPath]; } } return undefined; } + private _getTransformPath(filename: string) { + const transformInfo = this._getTransformPatternAndPath(filename); + if (!Array.isArray(transformInfo)) { + return undefined; + } + + return transformInfo[1]; + } + async loadTransformers(): Promise { await Promise.all( this._config.transform.map( - async ([, transformPath, transformerConfig]) => { + async ([transformPattern, transformPath, transformerConfig], i) => { let transformer: Transformer | TransformerFactory = await requireOrImportModule(transformPath); @@ -278,7 +292,13 @@ class ScriptTransformer { throw new Error(makeInvalidTransformerError(transformPath)); } const res = {transformer, transformerConfig}; - this._transformCache.set(transformPath, res); + const transformCacheKey = this._buildTransformCacheKey( + this._cache.transformRegExp && this._cache.transformRegExp[i] + ? this._cache.transformRegExp[i][0].source + : new RegExp(transformPattern).source, + transformPath, + ); + this._transformCache.set(transformCacheKey, res); }, ), ); @@ -297,15 +317,19 @@ class ScriptTransformer { return null; } - const transformPath = this._getTransformPath(filename); - - if (transformPath == null) { + const transformPatternAndPath = this._getTransformPatternAndPath(filename); + if (!Array.isArray(transformPatternAndPath)) { return null; } - const cached = this._transformCache.get(transformPath); - if (cached != null) { - return cached; + const [transformPattern, transformPath] = transformPatternAndPath; + const transformCacheKey = this._buildTransformCacheKey( + transformPattern, + transformPath, + ); + const transformer = this._transformCache.get(transformCacheKey); + if (transformer !== undefined) { + return transformer; } throw new Error( diff --git a/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts b/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts index 7da15d4723f7..3a6807de86f7 100644 --- a/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts +++ b/packages/jest-transform/src/__tests__/ScriptTransformer.test.ts @@ -1558,6 +1558,45 @@ describe('ScriptTransformer', () => { ).toHaveBeenCalledWith(transformerConfig); }); + it('passes correct config to a preprocessor used multiple times', async () => { + const transformerConfig1 = {}; + const transformerConfig2 = {}; + + config = Object.assign(config, { + transform: [ + // same preprocessor + [ + // *only* /fruits/banana.js + '/fruits/banana\\.js$', + 'configureable-preprocessor', + transformerConfig1, + ], + [ + // *not* /fruits/banana.js + '/fruits/(?!banana)\\w+\\.js$', + 'configureable-preprocessor', + transformerConfig2, + ], + ], + }); + + const scriptTransformer = await createScriptTransformer(config); + + scriptTransformer.transform('/fruits/banana.js', getCoverageOptions()); + expect( + ( + require('configureable-preprocessor') as TransformerFactory + ).createTransformer, + ).toHaveBeenLastCalledWith(transformerConfig1); + + scriptTransformer.transform('/fruits/kiwi.js', getCoverageOptions()); + expect( + ( + require('configureable-preprocessor') as TransformerFactory + ).createTransformer, + ).toHaveBeenLastCalledWith(transformerConfig2); + }); + it('reads values from the cache', async () => { const transformConfig: Config.ProjectConfig = { ...config, @@ -2001,7 +2040,7 @@ describe('ScriptTransformer', () => { // @ts-expect-error - private property expect(Array.from(scriptTransformer._transformCache.entries())).toEqual([ - ['test_preprocessor', expect.any(Object)], + ['\\.js$test_preprocessor', expect.any(Object)], ]); }); }); From 410a1e10ce5bb3eda8b57b467e9c74c7644eb08a Mon Sep 17 00:00:00 2001 From: coffeebeats <108542400+coffeebeats@users.noreply.github.com> Date: Fri, 13 Jan 2023 18:49:44 -0800 Subject: [PATCH 2/3] update the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 067791482e22..820088836f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - `[jest-runtime]` Support Wasm files that import JS resources ([#13608](https://github.com/facebook/jest/pull/13608)) - `[jest-runtime]` Using the scriptTransformer cache in jest-runner ([#13735](https://github.com/facebook/jest/pull/13735)) - `[jest-snapshot]` Make sure to import `babel` outside of the sandbox ([#13694](https://github.com/facebook/jest/pull/13694)) +- `[jest-transform]` Ensure the correct configuration is passed to preprocessors specified multiple times in the `transform` option ([#13770](https://github.com/facebook/jest/pull/13770)) ### Chore & Maintenance From 1f84b38eb08721fcc1444703d80272de99e813de Mon Sep 17 00:00:00 2001 From: coffeebeats <108542400+coffeebeats@users.noreply.github.com> Date: Sat, 14 Jan 2023 10:01:07 -0800 Subject: [PATCH 3/3] fix linter error by improving _cache.transformRegExp validity check --- packages/jest-transform/src/ScriptTransformer.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index 17b3ce1f4a47..19230b04e355 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -293,9 +293,8 @@ class ScriptTransformer { } const res = {transformer, transformerConfig}; const transformCacheKey = this._buildTransformCacheKey( - this._cache.transformRegExp && this._cache.transformRegExp[i] - ? this._cache.transformRegExp[i][0].source - : new RegExp(transformPattern).source, + this._cache.transformRegExp?.[i]?.[0].source ?? + new RegExp(transformPattern).source, transformPath, ); this._transformCache.set(transformCacheKey, res);