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.   // Turn these flags back on (or delete) once the effect list is removed in
    
  54.   // favor of a depth-first traversal using `subtreeTags`.
    
  55.   dfsEffectsRefactor: true,
    
  56.   enableUseJSStackToTrackPassiveDurations: false,
    
  57. };
    
  58. 
    
  59. function getTestFlags() {
    
  60.   // These are required on demand because some of our tests mutate them. We try
    
  61.   // not to but there are exceptions.
    
  62.   const featureFlags = require('shared/ReactFeatureFlags');
    
  63.   const schedulerFeatureFlags = require('scheduler/src/SchedulerFeatureFlags');
    
  64. 
    
  65.   const www = global.__WWW__ === true;
    
  66.   const releaseChannel = www
    
  67.     ? __EXPERIMENTAL__
    
  68.       ? 'modern'
    
  69.       : 'classic'
    
  70.     : __EXPERIMENTAL__
    
  71.     ? 'experimental'
    
  72.     : 'stable';
    
  73. 
    
  74.   // Return a proxy so we can throw if you attempt to access a flag that
    
  75.   // doesn't exist.
    
  76.   return new Proxy(
    
  77.     {
    
  78.       channel: releaseChannel,
    
  79.       modern: releaseChannel === 'modern',
    
  80.       classic: releaseChannel === 'classic',
    
  81.       source: !process.env.IS_BUILD,
    
  82.       www,
    
  83. 
    
  84.       // This isn't a flag, just a useful alias for tests.
    
  85.       enableActivity: releaseChannel === 'experimental' || www,
    
  86.       enableUseSyncExternalStoreShim: !__VARIANT__,
    
  87.       enableSuspenseList: releaseChannel === 'experimental' || www,
    
  88.       enableLegacyHidden: www,
    
  89. 
    
  90.       // If there's a naming conflict between scheduler and React feature flags, the
    
  91.       // React ones take precedence.
    
  92.       // TODO: Maybe we should error on conflicts? Or we could namespace
    
  93.       // the flags
    
  94.       ...schedulerFeatureFlags,
    
  95.       ...featureFlags,
    
  96.       ...environmentFlags,
    
  97.     },
    
  98.     {
    
  99.       get(flags, flagName) {
    
  100.         const flagValue = flags[flagName];
    
  101.         if (flagValue === undefined && typeof flagName === 'string') {
    
  102.           throw Error(
    
  103.             `Feature flag "${flagName}" does not exist. See TestFlags.js ` +
    
  104.               'for more details.'
    
  105.           );
    
  106.         }
    
  107.         return flagValue;
    
  108.       },
    
  109.     }
    
  110.   );
    
  111. }
    
  112. 
    
  113. exports.getTestFlags = getTestFlags;