main
js 128 lines 3.98 KB
Raw
1 'use strict';
2
3 // These flags can be in a @gate pragma to declare that a test depends on
4 // certain conditions. They're like GKs.
5 //
6 // Examples:
7 // // @gate enableSomeAPI
8 // test('uses an unstable API', () => {/*...*/})
9 //
10 // // @gate __DEV__
11 // test('only passes in development', () => {/*...*/})
12 //
13 // Most flags are defined in ReactFeatureFlags. If it's defined there, you don't
14 // have to do anything extra here.
15 //
16 // There are also flags based on the environment, like __DEV__. Feel free to
17 // add new flags and aliases below.
18 //
19 // You can also combine flags using multiple gates:
20 //
21 // // @gate enableSomeAPI
22 // // @gate __DEV__
23 // test('both conditions must pass', () => {/*...*/})
24 //
25 // Or using logical operators
26 // // @gate enableSomeAPI && __DEV__
27 // test('both conditions must pass', () => {/*...*/})
28 //
29 // Negation also works:
30 // // @gate !deprecateLegacyContext
31 // test('uses a deprecated feature', () => {/*...*/})
32
33 // These flags are based on the environment and don't change for the entire
34 // test run.
35 const environmentFlags = {
36 __DEV__,
37 build: __DEV__ ? 'development' : 'production',
38
39 // TODO: Should "experimental" also imply "modern"? Maybe we should
40 // always compare to the channel?
41 experimental: __EXPERIMENTAL__,
42 // Similarly, should stable imply "classic"?
43 stable: !__EXPERIMENTAL__,
44
45 variant: __VARIANT__,
46
47 persistent: global.__PERSISTENT__ === true,
48
49 // Use this for tests that are known to be broken.
50 FIXME: false,
51 TODO: false,
52
53 enableUseJSStackToTrackPassiveDurations: false,
54 };
55
56 function getTestFlags() {
57 // These are required on demand because some of our tests mutate them. We try
58 // not to but there are exceptions.
59 const featureFlags = require('shared/ReactFeatureFlags');
60 const schedulerFeatureFlags = require('scheduler/src/SchedulerFeatureFlags');
61
62 const www = global.__WWW__ === true;
63 const xplat = global.__XPLAT__ === true;
64 const releaseChannel = www
65 ? __EXPERIMENTAL__
66 ? 'modern'
67 : 'classic'
68 : __EXPERIMENTAL__
69 ? 'experimental'
70 : 'stable';
71
72 // Return a proxy so we can throw if you attempt to access a flag that
73 // doesn't exist.
74 return new Proxy(
75 {
76 channel: releaseChannel,
77 modern: releaseChannel === 'modern',
78 classic: releaseChannel === 'classic',
79 source: !process.env.IS_BUILD,
80 www,
81 fb: www || xplat,
82
83 // These aren't flags, just a useful aliases for tests.
84 enableSuspenseList: releaseChannel === 'experimental' || www || xplat,
85 enableLegacyHidden: www,
86 // TODO: Suspending the work loop during the render phase is currently
87 // not compatible with sibling prerendering. We will add this optimization
88 // back in a later step.
89 enableSuspendingDuringWorkLoop: false,
90
91 // This flag is used to determine whether we should run Fizz tests using
92 // the external runtime or the inline script runtime.
93 // For Meta we use variant to gate the feature. For OSS we use experimental
94 shouldUseFizzExternalRuntime: !featureFlags.enableFizzExternalRuntime
95 ? false
96 : www
97 ? __VARIANT__
98 : __EXPERIMENTAL__,
99
100 // This is used by useSyncExternalStoresShared-test.js to decide whether
101 // to test the shim or the native implementation of useSES.
102
103 enableUseSyncExternalStoreShim: !__VARIANT__,
104
105 // If there's a naming conflict between scheduler and React feature flags, the
106 // React ones take precedence.
107 // TODO: Maybe we should error on conflicts? Or we could namespace
108 // the flags
109 ...schedulerFeatureFlags,
110 ...featureFlags,
111 ...environmentFlags,
112 },
113 {
114 get(flags, flagName) {
115 const flagValue = flags[flagName];
116 if (flagValue === undefined && typeof flagName === 'string') {
117 throw Error(
118 `Feature flag "${flagName}" does not exist. See TestFlags.js ` +
119 'for more details.'
120 );
121 }
122 return flagValue;
123 },
124 }
125 );
126 }
127
128 exports.getTestFlags = getTestFlags;