main
js 166 lines 4.08 KB
Raw
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 ReactDOMClient;
17 let ReactFeatureFlags;
18 let ReactDOMServer;
19
20 function initModules() {
21 // Reset warning cache.
22 jest.resetModules();
23 React = require('react');
24 ReactDOMClient = require('react-dom/client');
25 ReactDOMServer = require('react-dom/server');
26
27 ReactFeatureFlags = require('shared/ReactFeatureFlags');
28 ReactFeatureFlags.disableLegacyContext = true;
29
30 // Make them available to the helpers.
31 return {
32 ReactDOMClient,
33 ReactDOMServer,
34 };
35 }
36
37 const {resetModules, itRenders} = ReactDOMServerIntegrationUtils(initModules);
38
39 function formatValue(val) {
40 if (val === null) {
41 return 'null';
42 }
43 if (val === undefined) {
44 return 'undefined';
45 }
46 if (typeof val === 'string') {
47 return val;
48 }
49 return JSON.stringify(val);
50 }
51
52 describe('ReactDOMServerIntegrationLegacyContextDisabled', () => {
53 beforeEach(() => {
54 resetModules();
55 });
56
57 itRenders('undefined legacy context with warning', async render => {
58 class LegacyProvider extends React.Component {
59 static childContextTypes = {
60 foo() {},
61 };
62 getChildContext() {
63 return {foo: 10};
64 }
65 render() {
66 return this.props.children;
67 }
68 }
69
70 const lifecycleContextLog = [];
71 class LegacyClsConsumer extends React.Component {
72 static contextTypes = {
73 foo() {},
74 };
75 shouldComponentUpdate(nextProps, nextState, nextContext) {
76 lifecycleContextLog.push(nextContext);
77 return true;
78 }
79 UNSAFE_componentWillReceiveProps(nextProps, nextContext) {
80 lifecycleContextLog.push(nextContext);
81 }
82 UNSAFE_componentWillUpdate(nextProps, nextState, nextContext) {
83 lifecycleContextLog.push(nextContext);
84 }
85 render() {
86 return formatValue(this.context);
87 }
88 }
89
90 function LegacyFnConsumer(props, context) {
91 return formatValue(context);
92 }
93 LegacyFnConsumer.contextTypes = {foo() {}};
94
95 function RegularFn(props, context) {
96 return formatValue(context);
97 }
98
99 const e = await render(
100 <LegacyProvider>
101 <span>
102 <LegacyClsConsumer />
103 <LegacyFnConsumer />
104 <RegularFn />
105 </span>
106 </LegacyProvider>,
107 3,
108 );
109 expect(e.textContent).toBe('{}undefinedundefined');
110 expect(lifecycleContextLog).toEqual([]);
111 });
112
113 itRenders('modern context', async render => {
114 const Ctx = React.createContext();
115
116 class Provider extends React.Component {
117 render() {
118 return (
119 <Ctx.Provider value={this.props.value}>
120 {this.props.children}
121 </Ctx.Provider>
122 );
123 }
124 }
125
126 class RenderPropConsumer extends React.Component {
127 render() {
128 return <Ctx.Consumer>{value => formatValue(value)}</Ctx.Consumer>;
129 }
130 }
131
132 const lifecycleContextLog = [];
133 class ContextTypeConsumer extends React.Component {
134 static contextType = Ctx;
135 shouldComponentUpdate(nextProps, nextState, nextContext) {
136 lifecycleContextLog.push(nextContext);
137 return true;
138 }
139 UNSAFE_componentWillReceiveProps(nextProps, nextContext) {
140 lifecycleContextLog.push(nextContext);
141 }
142 UNSAFE_componentWillUpdate(nextProps, nextState, nextContext) {
143 lifecycleContextLog.push(nextContext);
144 }
145 render() {
146 return formatValue(this.context);
147 }
148 }
149
150 function FnConsumer() {
151 return formatValue(React.useContext(Ctx));
152 }
153
154 const e = await render(
155 <Provider value="a">
156 <span>
157 <RenderPropConsumer />
158 <ContextTypeConsumer />
159 <FnConsumer />
160 </span>
161 </Provider>,
162 );
163 expect(e.textContent).toBe('aaa');
164 expect(lifecycleContextLog).toEqual([]);
165 });
166 });