Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore rootDir to determine the cache key of transformed files in babel-jest #7947

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- `[expect]`: Improve report when matcher fails, part 9 ([#7940](https://github.com/facebook/jest/pull/7940))
- `[pretty-format]` Support `React.memo` ([#7891](https://github.com/facebook/jest/pull/7891))
- `[jest-config]` Print error information on preset normalization error ([#7935](https://github.com/facebook/jest/pull/7935))
- `[babel-jest]` Ignore `rootDir` to determine the cache key of transformed files ([#7947](https://github.com/facebook/jest/pull/7947))

### Fixes

Expand Down
2 changes: 1 addition & 1 deletion e2e/__tests__/__snapshots__/transform.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FAIL __tests__/ignoredFile.test.js

babel-jest: Babel ignores __tests__/ignoredFile.test.js - make sure to include the file in Jest's transformIgnorePatterns as well.

at loadBabelConfig (../../../packages/babel-jest/build/index.js:132:13)
at loadBabelConfig (../../../packages/babel-jest/build/index.js:142:13)
`;

exports[`babel-jest instruments only specific files and collects coverage 1`] = `
Expand Down
1 change: 1 addition & 0 deletions packages/babel-jest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"babel-plugin-istanbul": "^5.1.0",
"babel-preset-jest": "^24.1.0",
"chalk": "^2.4.2",
"jest-regex-util": "^24.0.0",
SimenB marked this conversation as resolved.
Show resolved Hide resolved
"slash": "^2.0.0"
},
"devDependencies": {
Expand Down
40 changes: 40 additions & 0 deletions packages/babel-jest/src/__tests__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const mockConfig = {
moduleFileExtensions: [],
};

afterEach(() => {
jest.unmock('@babel/core');
});

test(`Returns source string with inline maps when no transformOptions is passed`, () => {
const result = babelJest.process(
sourceString,
Expand All @@ -39,3 +43,39 @@ test(`Returns source string with inline maps when no transformOptions is passed`
expect(result.map.sources).toEqual(['dummy_path.js']);
expect(JSON.stringify(result.map.sourcesContent)).toMatch('customMultiply');
});

test('getCacheKey does not depend on the rootDir', () => {
const getCacheKeyArgs = rootDir => {
const config = {
cwd: rootDir,
rootDir,
};

return [
'// Some code',
`${rootDir}/foo/bar.js`,
JSON.stringify(config),
{config, instrument: true, rootDir: config.rootDir},
];
};

jest.mock('@babel/core');
SimenB marked this conversation as resolved.
Show resolved Hide resolved

require('@babel/core').loadPartialConfig = options => ({
babelrc: `${options.cwd}/foo/.babelrc`,
config: `${options.cwd}/babel.config.js`,
options: {
cwd: options.cwd,
someOtherOption: `${options.cwd}/foo`,
},
});

const cacheKeyForRoot1 = babelJest.getCacheKey(
...getCacheKeyArgs('/root1/dir'),
);
const cacheKeyForRoot2 = babelJest.getCacheKey(
...getCacheKeyArgs('/root2/dir'),
);

expect(cacheKeyForRoot1).toEqual(cacheKeyForRoot2);
});
42 changes: 34 additions & 8 deletions packages/babel-jest/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
transformSync as babelTransform,
} from '@babel/core';
import chalk from 'chalk';
import {escapeStrForRegex} from 'jest-regex-util';
import slash from 'slash';

const THIS_FILE = fs.readFileSync(__filename);
Expand Down Expand Up @@ -63,32 +64,57 @@ const createTransformer = (
return babelConfig;
}

const rootDirRegExpCache: {[rootDir: string]: RegExp} = Object.create(null);

function getRootDirRegExp(rootDir: Config.Path): RegExp {
if (!rootDirRegExpCache[rootDir]) {
rootDirRegExpCache[rootDir] = new RegExp(
`^${escapeStrForRegex(rootDir)}(?=${escapeStrForRegex(path.sep)}|$)`,
);
}

return rootDirRegExpCache[rootDir];
}

function getCacheKeyForBabelOptions(
babelOptions: PartialConfig,
rootDir: Config.Path,
) {
const rootDirRegExp = getRootDirRegExp(rootDir);

// Not pretty but not coupled to a specific signature of the
// babel options to relativize paths
return JSON.stringify(babelOptions.options, (_key, value) => {
if (typeof value === 'string') {
return value.replace(rootDirRegExp, '<rootDir>');
}
return value;
});
}

return {
canInstrument: true,
getCacheKey(
fileData,
filename,
configString,
_configString,
{config, instrument, rootDir},
) {
const babelOptions = loadBabelConfig(config.cwd, filename);
const configPath = [
babelOptions.config || '',
babelOptions.babelrc || '',
];
const configPath = [babelOptions.config, babelOptions.babelrc].map(
configPath => configPath && path.relative(rootDir, configPath),
);

return crypto
.createHash('md5')
.update(THIS_FILE)
.update('\0', 'utf8')
.update(JSON.stringify(babelOptions.options))
.update(getCacheKeyForBabelOptions(babelOptions, rootDir))
.update('\0', 'utf8')
.update(fileData)
.update('\0', 'utf8')
.update(path.relative(rootDir, filename))
.update('\0', 'utf8')
.update(configString)
.update('\0', 'utf8')
thymikee marked this conversation as resolved.
Show resolved Hide resolved
.update(configPath.join(''))
.update('\0', 'utf8')
.update(instrument ? 'instrument' : '')
Expand Down
3 changes: 2 additions & 1 deletion packages/babel-jest/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// TODO: include `babel-preset-jest` if it's ever in TS even though we don't care about its types
"references": [
{"path": "../jest-transform"},
{"path": "../jest-types"}
{"path": "../jest-types"},
{"path": "../jest-regex-util"}
]
}