react/scripts/jest/preprocessor.js
Ruslan Lesiutin c8deb5db66
fix[ci]: fixed jest configuration not to skip too many devtools tests (#26955)
## Summary
Running `yarn test --project devtools --build` currently skips all
non-gated (without `@reactVersion` directives) devtools tests. This is
not expected behaviour, these changes are fixing it.

There were multiple related PRs to it:
- https://github.com/facebook/react/pull/26742
- https://github.com/facebook/react/pull/25712
- https://github.com/facebook/react/pull/24555

With these changes, the resulting behaviour will be:
- If `REACT_VERSION` env variable is specified:
    - jest will not include all non-gated test cases in the test run
- jest will run only a specific test case, when specified
`REACT_VERSION` value satisfies the range defined by `@reactVersion`
directives for this test case

- If `REACT_VERSION` env variable is not specified, jest will run all
non-gated tests:
   - jest will include all non-gated test cases in the test run
- jest will run all non-gated test cases, the only skipped test cases
will be those, which specified the range that does not include the next
stable version of react, which will be imported from `ReactVersions.js`

## How did you test this change?
Running `profilingCache` test suite without specifying `reactVersion`
now skips gated (>= 17 & < 18) test
<img width="1447" alt="Screenshot 2023-06-15 at 11 18 22"
src="https://github.com/facebook/react/assets/28902667/cad58994-2cb3-44b3-9eb2-1699c01a1eb3">

Running `profilingCache` test suite with specifying `reactVersion` to
`17` now runs this test case and skips others correctly
<img width="1447" alt="Screenshot 2023-06-15 at 11 20 11"
src="https://github.com/facebook/react/assets/28902667/d308960a-c172-4422-ba6f-9c0dbcd6f7d5">

Running `yarn test --project devtools ...` without specifying
`reactVersion` now runs all non-gated test cases
<img width="398" alt="Screenshot 2023-06-15 at 12 25 12"
src="https://github.com/facebook/react/assets/28902667/2b329634-0efd-4c4c-b460-889696bbc9e1">

Running `yarn test --project devtools ...` with specifying
`reactVersion` (to `17` in this example) now includes only gated tests
<img width="414" alt="Screenshot 2023-06-15 at 12 26 31"
src="https://github.com/facebook/react/assets/28902667/a702c27e-4c35-4b12-834c-e5bb06728997">
2023-06-22 09:33:05 +01:00

129 lines
4.1 KiB
JavaScript

'use strict';
const path = require('path');
const babel = require('@babel/core');
const coffee = require('coffee-script');
const hermesParser = require('hermes-parser');
const tsPreprocessor = require('./typescript/preprocessor');
const createCacheKeyFunction = require('fbjs-scripts/jest/createCacheKeyFunction');
const pathToBabel = path.join(
require.resolve('@babel/core'),
'../..',
'package.json'
);
const pathToBabelPluginReplaceConsoleCalls = require.resolve(
'../babel/transform-replace-console-calls'
);
const pathToBabelPluginAsyncToGenerator = require.resolve(
'@babel/plugin-transform-async-to-generator'
);
const pathToTransformInfiniteLoops = require.resolve(
'../babel/transform-prevent-infinite-loops'
);
const pathToTransformTestGatePragma = require.resolve(
'../babel/transform-test-gate-pragma'
);
const pathToTransformReactVersionPragma = require.resolve(
'../babel/transform-react-version-pragma'
);
const pathToBabelrc = path.join(__dirname, '..', '..', 'babel.config.js');
const pathToErrorCodes = require.resolve('../error-codes/codes.json');
const babelOptions = {
plugins: [
// For Node environment only. For builds, Rollup takes care of ESM.
require.resolve('@babel/plugin-transform-modules-commonjs'),
// Keep stacks detailed in tests.
// Don't put this in .babelrc so that we don't embed filenames
// into ReactART builds that include JSX.
// TODO: I have not verified that this actually works.
require.resolve('@babel/plugin-transform-react-jsx-source'),
pathToTransformInfiniteLoops,
pathToTransformTestGatePragma,
// This optimization is important for extremely performance-sensitive (e.g. React source).
// It's okay to disable it for tests.
[
require.resolve('@babel/plugin-transform-block-scoping'),
{throwIfClosureRequired: false},
],
],
retainLines: true,
};
module.exports = {
process: function (src, filePath) {
if (filePath.match(/\.css$/)) {
// Don't try to parse CSS modules; they aren't needed for tests anyway.
return {code: ''};
}
if (filePath.match(/\.coffee$/)) {
return {code: coffee.compile(src, {bare: true})};
}
if (filePath.match(/\.ts$/) && !filePath.match(/\.d\.ts$/)) {
return {code: tsPreprocessor.compile(src, filePath)};
}
if (filePath.match(/\.json$/)) {
return {code: src};
}
if (!filePath.match(/\/third_party\//)) {
// for test files, we also apply the async-await transform, but we want to
// make sure we don't accidentally apply that transform to product code.
const isTestFile = !!filePath.match(/\/__tests__\//);
const isInDevToolsPackages = !!filePath.match(
/\/packages\/react-devtools.*\//
);
const testOnlyPlugins = [pathToBabelPluginAsyncToGenerator];
const sourceOnlyPlugins = [];
if (process.env.NODE_ENV === 'development' && !isInDevToolsPackages) {
sourceOnlyPlugins.push(pathToBabelPluginReplaceConsoleCalls);
}
const plugins = (isTestFile ? testOnlyPlugins : sourceOnlyPlugins).concat(
babelOptions.plugins
);
if (isTestFile && isInDevToolsPackages) {
plugins.push(pathToTransformReactVersionPragma);
}
let sourceAst = hermesParser.parse(src, {babel: true});
return {
code: babel.transformFromAstSync(
sourceAst,
src,
Object.assign(
{filename: path.relative(process.cwd(), filePath)},
babelOptions,
{
plugins,
sourceMaps: process.env.JEST_ENABLE_SOURCE_MAPS
? process.env.JEST_ENABLE_SOURCE_MAPS
: false,
}
)
).code,
};
}
return {code: src};
},
getCacheKey: createCacheKeyFunction(
[
__filename,
pathToBabel,
pathToBabelrc,
pathToTransformInfiniteLoops,
pathToTransformTestGatePragma,
pathToTransformReactVersionPragma,
pathToErrorCodes,
],
[
(process.env.REACT_VERSION != null).toString(),
(process.env.NODE_ENV === 'development').toString(),
]
),
};