From 3ba58db430de059e2d20754cf63bb59906f4c4ff Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 9 Oct 2023 13:05:27 -0400 Subject: [PATCH] Add React Native test configs Adds new Jest configs for running our test suite using React Native feature flags. This includes a special config for the version of RN that Meta uses for internal dogfooding, similar to the equivalent ones used for Meta's web codebase. Practically speaking, the main benefit is we can run our tests in CI with the experimental flags used at Meta without having to enable them in the open source builds. Usage: yarn test -r=native-oss yarn test -r=native-fb yarn test -r=native-fb --no-variant --- .circleci/config.yml | 11 ++++- .../__tests__/ReactFabric-test.internal.js | 4 -- .../ReactFeatureFlags.native-fb-dynamic.js | 4 -- scripts/jest/config.source-native-fb.js | 21 ++++++++++ scripts/jest/config.source-native-oss.js | 21 ++++++++++ scripts/jest/jest-cli.js | 40 +++++++++++++------ scripts/jest/setupTests.native-fb.js | 17 ++++++++ scripts/jest/setupTests.native-oss.js | 11 +++++ 8 files changed, 107 insertions(+), 22 deletions(-) create mode 100644 scripts/jest/config.source-native-fb.js create mode 100644 scripts/jest/config.source-native-oss.js create mode 100644 scripts/jest/setupTests.native-fb.js create mode 100644 scripts/jest/setupTests.native-oss.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 452cfa6feb1f8..b01a2932cf65f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -450,8 +450,15 @@ workflows: - "-r=www-modern --env=production --variant=false" - "-r=www-modern --env=development --variant=true" - "-r=www-modern --env=production --variant=true" - - # TODO: Test more persistent configurations? + - "-r=native-oss --env=development" + - "-r=native-oss --env=production" + - "-r=native-fb --env=development --variant=false" + - "-r=native-fb --env=production --variant=false" + - "-r=native-fb --env=development --variant=true" + - "-r=native-fb --env=production --variant=true" + + # TODO: Maybe we can delete these because the RN + # configurations above are sufficient? - '-r=stable --env=development --persistent' - '-r=experimental --env=development --persistent' - yarn_build: diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index 4e97cead6f349..76186dfcb5ab7 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -25,10 +25,6 @@ const SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT = "sendAccessibilityEvent was called with a ref that isn't a " + 'native component. Use React.forwardRef to get access to the underlying native component'; -jest.mock('shared/ReactFeatureFlags', () => - require('shared/forks/ReactFeatureFlags.native-oss'), -); - describe('ReactFabric', () => { beforeEach(() => { jest.resetModules(); diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js index 7ef1ef3013f17..31f96448c48a3 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js @@ -15,10 +15,6 @@ import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags'; // // Use __VARIANT__ to simulate a GK. The tests will be run twice: once // with the __VARIANT__ set to `true`, and once set to `false`. -// -// TODO: __VARIANT__ isn't supported for React Native flags yet. You can set the -// flag here but it won't be set to `true` in any of our test runs. Need to -// update the test configuration. export const enableUseRefAccessWarning = __VARIANT__; export const enableDeferRootSchedulingToMicrotask = __VARIANT__; diff --git a/scripts/jest/config.source-native-fb.js b/scripts/jest/config.source-native-fb.js new file mode 100644 index 0000000000000..3bfa0e9ce3007 --- /dev/null +++ b/scripts/jest/config.source-native-fb.js @@ -0,0 +1,21 @@ +'use strict'; + +const baseConfig = require('./config.base'); + +module.exports = Object.assign({}, baseConfig, { + modulePathIgnorePatterns: [ + ...baseConfig.modulePathIgnorePatterns, + 'packages/react-devtools-extensions', + 'packages/react-devtools-shared', + 'ReactIncrementalPerf', + 'ReactIncrementalUpdatesMinimalism', + 'ReactIncrementalTriangle', + 'ReactIncrementalReflection', + 'forwardRef', + ], + setupFiles: [ + ...baseConfig.setupFiles, + require.resolve('./setupTests.native-fb.js'), + require.resolve('./setupHostConfigs.js'), + ], +}); diff --git a/scripts/jest/config.source-native-oss.js b/scripts/jest/config.source-native-oss.js new file mode 100644 index 0000000000000..38d863597d4f6 --- /dev/null +++ b/scripts/jest/config.source-native-oss.js @@ -0,0 +1,21 @@ +'use strict'; + +const baseConfig = require('./config.base'); + +module.exports = Object.assign({}, baseConfig, { + modulePathIgnorePatterns: [ + ...baseConfig.modulePathIgnorePatterns, + 'packages/react-devtools-extensions', + 'packages/react-devtools-shared', + 'ReactIncrementalPerf', + 'ReactIncrementalUpdatesMinimalism', + 'ReactIncrementalTriangle', + 'ReactIncrementalReflection', + 'forwardRef', + ], + setupFiles: [ + ...baseConfig.setupFiles, + require.resolve('./setupTests.native-oss.js'), + require.resolve('./setupHostConfigs.js'), + ], +}); diff --git a/scripts/jest/jest-cli.js b/scripts/jest/jest-cli.js index af7bc3be77076..349817278d242 100644 --- a/scripts/jest/jest-cli.js +++ b/scripts/jest/jest-cli.js @@ -10,6 +10,8 @@ const semver = require('semver'); const ossConfig = './scripts/jest/config.source.js'; const wwwConfig = './scripts/jest/config.source-www.js'; const devToolsConfig = './scripts/jest/config.build-devtools.js'; +const nativeOssConfig = './scripts/jest/config.source-native-oss.js'; +const nativeFbConfig = './scripts/jest/config.source-native-fb.js'; // TODO: These configs are separate but should be rolled into the configs above // so that the CLI can provide them as options for any of the configs. @@ -46,7 +48,14 @@ const argv = yargs requiresArg: true, type: 'string', default: 'experimental', - choices: ['experimental', 'stable', 'www-classic', 'www-modern'], + choices: [ + 'experimental', + 'stable', + 'www-classic', + 'www-modern', + 'native-oss', + 'native-fb', + ], }, env: { alias: 'e', @@ -129,12 +138,6 @@ function isWWWConfig() { ); } -function isOSSConfig() { - return ( - argv.releaseChannel === 'stable' || argv.releaseChannel === 'experimental' - ); -} - function validateOptions() { let success = true; @@ -194,7 +197,7 @@ function validateOptions() { } } - if (isWWWConfig()) { + if (isWWWConfig() || argv.releaseChannel === 'native-fb') { if (argv.variant === undefined) { // Turn internal experiments on by default argv.variant = true; @@ -202,7 +205,7 @@ function validateOptions() { } else { if (argv.variant) { logError( - 'Variant is only supported for the www release channels. Update these options to continue.' + `Variant not supported for release channel ${argv.releaseChannel}. Update these options to continue.` ); success = false; } @@ -215,9 +218,15 @@ function validateOptions() { success = false; } - if (!isOSSConfig() && argv.persistent) { + if ( + argv.persistent === true && + argv.releaseChannel !== 'experimental' && + argv.releaseChannel !== 'stable' && + argv.releaseChannel !== 'native-oss' && + argv.releaseChannel !== 'native-fb' + ) { logError( - 'Persistence only supported for oss release channels. Update these options to continue.' + `Persistence not supported for release channel ${argv.releaseChannel}. Update these options to continue.` ); success = false; } @@ -282,8 +291,15 @@ function getCommandArgs() { args.push(persistentConfig); } else if (isWWWConfig()) { args.push(wwwConfig); - } else if (isOSSConfig()) { + } else if ( + argv.releaseChannel === 'stable' || + argv.releaseChannel === 'experimental' + ) { args.push(ossConfig); + } else if (argv.releaseChannel === 'native-oss') { + args.push(nativeOssConfig); + } else if (argv.releaseChannel === 'native-fb') { + args.push(nativeFbConfig); } else { // We should not get here. logError('Unrecognized release channel'); diff --git a/scripts/jest/setupTests.native-fb.js b/scripts/jest/setupTests.native-fb.js new file mode 100644 index 0000000000000..7a266dea94025 --- /dev/null +++ b/scripts/jest/setupTests.native-fb.js @@ -0,0 +1,17 @@ +'use strict'; + +jest.mock('shared/ReactFeatureFlags', () => { + jest.mock( + 'ReactNativeInternalFeatureFlags', + () => + jest.requireActual('shared/forks/ReactFeatureFlags.native-fb-dynamic'), + {virtual: true} + ); + return jest.requireActual('shared/forks/ReactFeatureFlags.native-fb'); +}); + +jest.mock('react-noop-renderer', () => + jest.requireActual('react-noop-renderer/persistent') +); + +global.__PERSISTENT__ = true; diff --git a/scripts/jest/setupTests.native-oss.js b/scripts/jest/setupTests.native-oss.js new file mode 100644 index 0000000000000..7c4505c908a40 --- /dev/null +++ b/scripts/jest/setupTests.native-oss.js @@ -0,0 +1,11 @@ +'use strict'; + +jest.mock('shared/ReactFeatureFlags', () => + require('shared/forks/ReactFeatureFlags.native-oss') +); + +jest.mock('react-noop-renderer', () => + jest.requireActual('react-noop-renderer/persistent') +); + +global.__PERSISTENT__ = true;