1111
1212let React ;
1313let ReactDOM ;
14+ let ReactDOMClient ;
1415let ReactTestUtils ;
1516let JSXRuntime ;
1617let JSXDEVRuntime ;
18+ let act ;
1719
1820// NOTE: We're explicitly not using JSX here. This is intended to test
1921// a new React.jsx api which does not have a JSX transformer yet.
@@ -27,7 +29,9 @@ describe('ReactElement.jsx', () => {
2729 JSXRuntime = require ( 'react/jsx-runtime' ) ;
2830 JSXDEVRuntime = require ( 'react/jsx-dev-runtime' ) ;
2931 ReactDOM = require ( 'react-dom' ) ;
32+ ReactDOMClient = require ( 'react-dom/client' ) ;
3033 ReactTestUtils = require ( 'react-dom/test-utils' ) ;
34+ act = require ( 'internal-test-utils' ) . act ;
3135 } ) ;
3236
3337 it ( 'allows static methods to be called using the type property' , ( ) => {
@@ -48,23 +52,25 @@ describe('ReactElement.jsx', () => {
4852 expect ( element . constructor ) . toBe ( object . constructor ) ;
4953 } ) ;
5054
51- it ( 'should use default prop value when removing a prop' , ( ) => {
55+ it ( 'should use default prop value when removing a prop' , async ( ) => {
5256 class Component extends React . Component {
5357 render ( ) {
54- return JSXRuntime . jsx ( 'span' , { } ) ;
58+ return JSXRuntime . jsx ( 'span' , { children : [ this . props . fruit ] } ) ;
5559 }
5660 }
5761 Component . defaultProps = { fruit : 'persimmon' } ;
5862
5963 const container = document . createElement ( 'div' ) ;
60- const instance = ReactDOM . render (
61- JSXRuntime . jsx ( Component , { fruit : 'mango' } ) ,
62- container ,
63- ) ;
64- expect ( instance . props . fruit ) . toBe ( 'mango' ) ;
64+ const root = ReactDOMClient . createRoot ( container ) ;
65+ await act ( ( ) => {
66+ root . render ( JSXRuntime . jsx ( Component , { fruit : 'mango' } ) ) ;
67+ } ) ;
68+ expect ( container . firstChild . textContent ) . toBe ( 'mango' ) ;
6569
66- ReactDOM . render ( JSXRuntime . jsx ( Component , { } ) , container ) ;
67- expect ( instance . props . fruit ) . toBe ( 'persimmon' ) ;
70+ await act ( ( ) => {
71+ root . render ( JSXRuntime . jsx ( Component , { } ) ) ;
72+ } ) ;
73+ expect ( container . firstChild . textContent ) . toBe ( 'persimmon' ) ;
6874 } ) ;
6975
7076 it ( 'should normalize props with default values' , ( ) => {
@@ -114,7 +120,7 @@ describe('ReactElement.jsx', () => {
114120 }
115121 } ) ;
116122
117- it ( 'throws when adding a prop (in dev) after element creation' , ( ) => {
123+ it ( 'throws when adding a prop (in dev) after element creation' , async ( ) => {
118124 const container = document . createElement ( 'div' ) ;
119125 class Outer extends React . Component {
120126 render ( ) {
@@ -134,12 +140,15 @@ describe('ReactElement.jsx', () => {
134140 }
135141 }
136142 Outer . defaultProps = { sound : 'meow' } ;
137- const outer = ReactDOM . render ( JSXRuntime . jsx ( Outer , { } ) , container ) ;
138- expect ( ReactDOM . findDOMNode ( outer ) . textContent ) . toBe ( 'meow' ) ;
143+ const root = ReactDOMClient . createRoot ( container ) ;
144+ await act ( ( ) => {
145+ root . render ( JSXRuntime . jsx ( Outer , { } ) ) ;
146+ } ) ;
147+ expect ( container . firstChild . textContent ) . toBe ( 'meow' ) ;
139148 if ( __DEV__ ) {
140- expect ( ReactDOM . findDOMNode ( outer ) . className ) . toBe ( '' ) ;
149+ expect ( container . firstChild . className ) . toBe ( '' ) ;
141150 } else {
142- expect ( ReactDOM . findDOMNode ( outer ) . className ) . toBe ( 'quack' ) ;
151+ expect ( container . firstChild . className ) . toBe ( 'quack' ) ;
143152 }
144153 } ) ;
145154
@@ -155,7 +164,7 @@ describe('ReactElement.jsx', () => {
155164 expect ( test . props . value ) . toBeNaN ( ) ;
156165 } ) ;
157166
158- it ( 'should warn when `key` is being accessed on composite element' , ( ) => {
167+ it ( 'should warn when `key` is being accessed on composite element' , async ( ) => {
159168 const container = document . createElement ( 'div' ) ;
160169 class Child extends React . Component {
161170 render ( ) {
@@ -173,24 +182,27 @@ describe('ReactElement.jsx', () => {
173182 } ) ;
174183 }
175184 }
176- expect ( ( ) =>
177- ReactDOM . render ( JSXRuntime . jsx ( Parent , { } ) , container ) ,
178- ) . toErrorDev (
185+ await expect ( async ( ) => {
186+ const root = ReactDOMClient . createRoot ( container ) ;
187+ await act ( ( ) => {
188+ root . render ( JSXRuntime . jsx ( Parent , { } ) ) ;
189+ } ) ;
190+ } ) . toErrorDev (
179191 'Child: `key` is not a prop. Trying to access it will result ' +
180192 'in `undefined` being returned. If you need to access the same ' +
181193 'value within the child component, you should pass it as a different ' +
182194 'prop. (https://reactjs.org/link/special-props)' ,
183195 ) ;
184196 } ) ;
185197
186- it ( 'warns when a jsxs is passed something that is not an array' , ( ) => {
198+ it ( 'warns when a jsxs is passed something that is not an array' , async ( ) => {
187199 const container = document . createElement ( 'div' ) ;
188- expect ( ( ) =>
189- ReactDOM . render (
190- JSXRuntime . jsxs ( 'div' , { children : 'foo' } , null ) ,
191- container ,
192- ) ,
193- ) . toErrorDev (
200+ await expect ( async ( ) => {
201+ const root = ReactDOMClient . createRoot ( container ) ;
202+ await act ( ( ) => {
203+ root . render ( JSXRuntime . jsxs ( 'div' , { children : 'foo' } , null ) ) ;
204+ } ) ;
205+ } ) . toErrorDev (
194206 'React.jsx: Static children should always be an array. ' +
195207 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' +
196208 'Use the Babel transform instead.' ,
@@ -209,7 +221,7 @@ describe('ReactElement.jsx', () => {
209221 ) ;
210222 } ) ;
211223
212- it ( 'should warn when `ref` is being accessed' , ( ) => {
224+ it ( 'should warn when `ref` is being accessed' , async ( ) => {
213225 const container = document . createElement ( 'div' ) ;
214226 class Child extends React . Component {
215227 render ( ) {
@@ -223,17 +235,20 @@ describe('ReactElement.jsx', () => {
223235 } ) ;
224236 }
225237 }
226- expect ( ( ) =>
227- ReactDOM . render ( JSXRuntime . jsx ( Parent , { } ) , container ) ,
228- ) . toErrorDev (
238+ await expect ( async ( ) => {
239+ const root = ReactDOMClient . createRoot ( container ) ;
240+ await act ( ( ) => {
241+ root . render ( JSXRuntime . jsx ( Parent , { } ) ) ;
242+ } ) ;
243+ } ) . toErrorDev (
229244 'Child: `ref` is not a prop. Trying to access it will result ' +
230245 'in `undefined` being returned. If you need to access the same ' +
231246 'value within the child component, you should pass it as a different ' +
232247 'prop. (https://reactjs.org/link/special-props)' ,
233248 ) ;
234249 } ) ;
235250
236- it ( 'should warn when unkeyed children are passed to jsx' , ( ) => {
251+ it ( 'should warn when unkeyed children are passed to jsx' , async ( ) => {
237252 const container = document . createElement ( 'div' ) ;
238253
239254 class Child extends React . Component {
@@ -252,17 +267,20 @@ describe('ReactElement.jsx', () => {
252267 } ) ;
253268 }
254269 }
255- expect ( ( ) =>
256- ReactDOM . render ( JSXRuntime . jsx ( Parent , { } ) , container ) ,
257- ) . toErrorDev (
270+ await expect ( async ( ) => {
271+ const root = ReactDOMClient . createRoot ( container ) ;
272+ await act ( ( ) => {
273+ root . render ( JSXRuntime . jsx ( Parent , { } ) ) ;
274+ } ) ;
275+ } ) . toErrorDev (
258276 'Warning: Each child in a list should have a unique "key" prop.\n\n' +
259277 'Check the render method of `Parent`. See https://reactjs.org/link/warning-keys for more information.\n' +
260278 ' in Child (at **)\n' +
261279 ' in Parent (at **)' ,
262280 ) ;
263281 } ) ;
264282
265- it ( 'should warn when keys are passed as part of props' , ( ) => {
283+ it ( 'should warn when keys are passed as part of props' , async ( ) => {
266284 const container = document . createElement ( 'div' ) ;
267285 class Child extends React . Component {
268286 render ( ) {
@@ -276,9 +294,12 @@ describe('ReactElement.jsx', () => {
276294 } ) ;
277295 }
278296 }
279- expect ( ( ) =>
280- ReactDOM . render ( JSXRuntime . jsx ( Parent , { } ) , container ) ,
281- ) . toErrorDev (
297+ await expect ( async ( ) => {
298+ const root = ReactDOMClient . createRoot ( container ) ;
299+ await act ( ( ) => {
300+ root . render ( JSXRuntime . jsx ( Parent , { } ) ) ;
301+ } ) ;
302+ } ) . toErrorDev (
282303 'Warning: A props object containing a "key" prop is being spread into JSX:\n' +
283304 ' let props = {key: someKey, prop: ...};\n' +
284305 ' <Child {...props} />\n' +
@@ -288,7 +309,7 @@ describe('ReactElement.jsx', () => {
288309 ) ;
289310 } ) ;
290311
291- it ( 'should not warn when unkeyed children are passed to jsxs' , ( ) => {
312+ it ( 'should not warn when unkeyed children are passed to jsxs' , async ( ) => {
292313 const container = document . createElement ( 'div' ) ;
293314 class Child extends React . Component {
294315 render ( ) {
@@ -306,8 +327,14 @@ describe('ReactElement.jsx', () => {
306327 } ) ;
307328 }
308329 }
309- // TODO: an explicit expect for no warning?
310- ReactDOM . render ( JSXRuntime . jsx ( Parent , { } ) , container ) ;
330+
331+ const root = ReactDOMClient . createRoot ( container ) ;
332+ await act ( ( ) => {
333+ root . render ( JSXRuntime . jsx ( Parent , { } ) ) ;
334+ } ) ;
335+
336+ // Test shouldn't throw any errors.
337+ expect ( true ) . toBe ( true ) ;
311338 } ) ;
312339
313340 it ( 'does not call lazy initializers eagerly' , ( ) => {
0 commit comments