Skip to content

Commit

Permalink
fix(jest-transform): ensure correct config is passed to preprocessors…
Browse files Browse the repository at this point in the history
… specified multiple times in `transform` (#13770)
  • Loading branch information
coffeebeats committed Jan 15, 2023
1 parent 928f6cc commit 49204ac
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,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

Expand Down
51 changes: 37 additions & 14 deletions packages/jest-transform/src/ScriptTransformer.ts
Expand Up @@ -134,6 +134,10 @@ class ScriptTransformer {
.substring(0, 32);
}

private _buildTransformCacheKey(pattern: string, filepath: string) {
return pattern + filepath;
}

private _getCacheKey(
fileData: string,
filename: string,
Expand Down Expand Up @@ -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<void> {
await Promise.all(
this._config.transform.map(
async ([, transformPath, transformerConfig]) => {
async ([transformPattern, transformPath, transformerConfig], i) => {
let transformer: Transformer | TransformerFactory<Transformer> =
await requireOrImportModule(transformPath);

Expand All @@ -278,7 +292,12 @@ class ScriptTransformer {
throw new Error(makeInvalidTransformerError(transformPath));
}
const res = {transformer, transformerConfig};
this._transformCache.set(transformPath, res);
const transformCacheKey = this._buildTransformCacheKey(
this._cache.transformRegExp?.[i]?.[0].source ??
new RegExp(transformPattern).source,
transformPath,
);
this._transformCache.set(transformCacheKey, res);
},
),
);
Expand All @@ -297,15 +316,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(
Expand Down
41 changes: 40 additions & 1 deletion packages/jest-transform/src/__tests__/ScriptTransformer.test.ts
Expand Up @@ -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<SyncTransformer>
).createTransformer,
).toHaveBeenLastCalledWith(transformerConfig1);

scriptTransformer.transform('/fruits/kiwi.js', getCoverageOptions());
expect(
(
require('configureable-preprocessor') as TransformerFactory<SyncTransformer>
).createTransformer,
).toHaveBeenLastCalledWith(transformerConfig2);
});

it('reads values from the cache', async () => {
const transformConfig: Config.ProjectConfig = {
...config,
Expand Down Expand Up @@ -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)],
]);
});
});
Expand Down

0 comments on commit 49204ac

Please sign in to comment.