1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @emails react-core
    
  8.  * @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
    
  9.  */
    
  10. 
    
  11. 'use strict';
    
  12. 
    
  13. const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils');
    
  14. 
    
  15. let React;
    
  16. let ReactDOM;
    
  17. let ReactFeatureFlags;
    
  18. let ReactDOMServer;
    
  19. let ReactTestUtils;
    
  20. 
    
  21. function initModules() {
    
  22.   // Reset warning cache.
    
  23.   jest.resetModules();
    
  24.   React = require('react');
    
  25.   ReactDOM = require('react-dom');
    
  26.   ReactDOMServer = require('react-dom/server');
    
  27.   ReactTestUtils = require('react-dom/test-utils');
    
  28. 
    
  29.   ReactFeatureFlags = require('shared/ReactFeatureFlags');
    
  30.   ReactFeatureFlags.disableLegacyContext = true;
    
  31. 
    
  32.   // Make them available to the helpers.
    
  33.   return {
    
  34.     ReactDOM,
    
  35.     ReactDOMServer,
    
  36.     ReactTestUtils,
    
  37.   };
    
  38. }
    
  39. 
    
  40. const {resetModules, itRenders} = ReactDOMServerIntegrationUtils(initModules);
    
  41. 
    
  42. function formatValue(val) {
    
  43.   if (val === null) {
    
  44.     return 'null';
    
  45.   }
    
  46.   if (val === undefined) {
    
  47.     return 'undefined';
    
  48.   }
    
  49.   if (typeof val === 'string') {
    
  50.     return val;
    
  51.   }
    
  52.   return JSON.stringify(val);
    
  53. }
    
  54. 
    
  55. describe('ReactDOMServerIntegrationLegacyContextDisabled', () => {
    
  56.   beforeEach(() => {
    
  57.     resetModules();
    
  58.   });
    
  59. 
    
  60.   itRenders('undefined legacy context with warning', async render => {
    
  61.     class LegacyProvider extends React.Component {
    
  62.       static childContextTypes = {
    
  63.         foo() {},
    
  64.       };
    
  65.       getChildContext() {
    
  66.         return {foo: 10};
    
  67.       }
    
  68.       render() {
    
  69.         return this.props.children;
    
  70.       }
    
  71.     }
    
  72. 
    
  73.     const lifecycleContextLog = [];
    
  74.     class LegacyClsConsumer extends React.Component {
    
  75.       static contextTypes = {
    
  76.         foo() {},
    
  77.       };
    
  78.       shouldComponentUpdate(nextProps, nextState, nextContext) {
    
  79.         lifecycleContextLog.push(nextContext);
    
  80.         return true;
    
  81.       }
    
  82.       UNSAFE_componentWillReceiveProps(nextProps, nextContext) {
    
  83.         lifecycleContextLog.push(nextContext);
    
  84.       }
    
  85.       UNSAFE_componentWillUpdate(nextProps, nextState, nextContext) {
    
  86.         lifecycleContextLog.push(nextContext);
    
  87.       }
    
  88.       render() {
    
  89.         return formatValue(this.context);
    
  90.       }
    
  91.     }
    
  92. 
    
  93.     function LegacyFnConsumer(props, context) {
    
  94.       return formatValue(context);
    
  95.     }
    
  96.     LegacyFnConsumer.contextTypes = {foo() {}};
    
  97. 
    
  98.     function RegularFn(props, context) {
    
  99.       return formatValue(context);
    
  100.     }
    
  101. 
    
  102.     const e = await render(
    
  103.       <LegacyProvider>
    
  104.         <span>
    
  105.           <LegacyClsConsumer />
    
  106.           <LegacyFnConsumer />
    
  107.           <RegularFn />
    
  108.         </span>
    
  109.       </LegacyProvider>,
    
  110.       3,
    
  111.     );
    
  112.     expect(e.textContent).toBe('{}undefinedundefined');
    
  113.     expect(lifecycleContextLog).toEqual([]);
    
  114.   });
    
  115. 
    
  116.   itRenders('modern context', async render => {
    
  117.     const Ctx = React.createContext();
    
  118. 
    
  119.     class Provider extends React.Component {
    
  120.       render() {
    
  121.         return (
    
  122.           <Ctx.Provider value={this.props.value}>
    
  123.             {this.props.children}
    
  124.           </Ctx.Provider>
    
  125.         );
    
  126.       }
    
  127.     }
    
  128. 
    
  129.     class RenderPropConsumer extends React.Component {
    
  130.       render() {
    
  131.         return <Ctx.Consumer>{value => formatValue(value)}</Ctx.Consumer>;
    
  132.       }
    
  133.     }
    
  134. 
    
  135.     const lifecycleContextLog = [];
    
  136.     class ContextTypeConsumer extends React.Component {
    
  137.       static contextType = Ctx;
    
  138.       shouldComponentUpdate(nextProps, nextState, nextContext) {
    
  139.         lifecycleContextLog.push(nextContext);
    
  140.         return true;
    
  141.       }
    
  142.       UNSAFE_componentWillReceiveProps(nextProps, nextContext) {
    
  143.         lifecycleContextLog.push(nextContext);
    
  144.       }
    
  145.       UNSAFE_componentWillUpdate(nextProps, nextState, nextContext) {
    
  146.         lifecycleContextLog.push(nextContext);
    
  147.       }
    
  148.       render() {
    
  149.         return formatValue(this.context);
    
  150.       }
    
  151.     }
    
  152. 
    
  153.     function FnConsumer() {
    
  154.       return formatValue(React.useContext(Ctx));
    
  155.     }
    
  156. 
    
  157.     const e = await render(
    
  158.       <Provider value="a">
    
  159.         <span>
    
  160.           <RenderPropConsumer />
    
  161.           <ContextTypeConsumer />
    
  162.           <FnConsumer />
    
  163.         </span>
    
  164.       </Provider>,
    
  165.     );
    
  166.     expect(e.textContent).toBe('aaa');
    
  167.     expect(lifecycleContextLog).toEqual([]);
    
  168.   });
    
  169. });