@samitouri / QOS-React-1 / commits / e66ef6480e

[tests] remove withoutStack from assertConsole helpers (#35498)

Stacked on https://github.com/facebook/react/pull/35497 ----- Now that the assert helpers require a component stack, we don't need the `{withoutStack: true}` option.

Ricky committed Jan 27, 2026 at 22:34 UTC e66ef6480ecd19c6885f2c06dec34fec1fdc0a98
43 files changed +874 -2055
packages/internal-test-utils/__tests__/ReactInternalTestUtils-test.js
+12 -643
@@ -568,36 +568,6 @@ describe('ReactInternalTestUtils console assertions', () => {
568 `);
569 });
570
571 - // @gate __DEV__
572 - it('fails if local withoutStack passed to assertConsoleLogDev', () => {
573 - const message = expectToThrowFailure(() => {
574 - console.log('Hello');
575 - assertConsoleLogDev([['Hello', {withoutStack: true}]]);
576 - });
577 -
578 - expect(message).toMatchInlineSnapshot(`
579 - "assertConsoleLogDev(expected)
580 -
581 - Do not pass withoutStack to assertConsoleLogDev logs, console.log does not have component stacks."
582 - `);
583 - });
584 -
585 - // @gate __DEV__
586 - it('fails if global withoutStack passed to assertConsoleLogDev', () => {
587 - const message = expectToThrowFailure(() => {
588 - console.log('Hello');
589 - assertConsoleLogDev(['Hello'], {withoutStack: true});
590 - });
591 -
592 - expect(message).toMatchInlineSnapshot(`
593 - "assertConsoleLogDev(expected)
594 -
595 - Do not pass withoutStack to assertConsoleLogDev, console.log does not have component stacks."
596 - `);
597 -
598 - assertConsoleLogDev(['Hello']);
599 - });
600 -
571 // @gate __DEV__
572 it('fails if the args is greater than %s argument number', () => {
573 const message = expectToThrowFailure(() => {
@@ -1173,23 +1143,6 @@ describe('ReactInternalTestUtils console assertions', () => {
1143 `);
1144 });
1145
1176 - // @gate __DEV__
1177 - it('fails if only warning does not contain a stack', () => {
1178 - const message = expectToThrowFailure(() => {
1179 - console.warn('Hello');
1180 - assertConsoleWarnDev(['Hello']);
1181 - });
1182 - expect(message).toMatchInlineSnapshot(`
1183 - "assertConsoleWarnDev(expected)
1184 -
1185 - Missing component stack for:
1186 - "Hello"
1187 -
1188 - If this warning should omit a component stack, pass [log, {withoutStack: true}].
1189 - If all warnings should omit the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
1190 - `);
1191 - });
1192 -
1146 // @gate __DEV__
1147 it('fails if first warning does not contain a stack', () => {
1148 const message = expectToThrowFailure(() => {
@@ -1277,287 +1230,11 @@ describe('ReactInternalTestUtils console assertions', () => {
1230 `);
1231 });
1232
1280 - describe('global withoutStack', () => {
1281 - it('passes if warnings without stack explicitly opt out', () => {
1282 - if (__DEV__) {
1283 - console.warn('Hello');
1284 - }
1285 - assertConsoleWarnDev(['Hello'], {withoutStack: true});
1286 -
1287 - if (__DEV__) {
1288 - console.warn('Hello');
1289 - console.warn('Good day');
1290 - console.warn('Bye');
1291 - }
1292 -
1293 - assertConsoleWarnDev(['Hello', 'Good day', 'Bye'], {
1294 - withoutStack: true,
1295 - });
1296 - });
1297 -
1298 - // @gate __DEV__
1299 - it('fails if withoutStack is invalid null value', () => {
1300 - const message = expectToThrowFailure(() => {
1301 - console.warn('Hi');
1302 - assertConsoleWarnDev(['Hi'], {withoutStack: null});
1303 - });
1304 - expect(message).toMatchInlineSnapshot(`
1305 - "assertConsoleWarnDev(expected)
1306 -
1307 - The second argument must be {withoutStack: true}.
1308 -
1309 - Instead received {"withoutStack":null}."
1310 - `);
1311 - assertConsoleWarnDev(['Hi'], {withoutStack: true});
1312 - });
1313 -
1314 - // @gate __DEV__
1315 - it('fails if withoutStack is invalid {} value', () => {
1316 - const message = expectToThrowFailure(() => {
1317 - console.warn('Hi');
1318 - assertConsoleWarnDev(['Hi'], {withoutStack: {}});
1319 - });
1320 - expect(message).toMatchInlineSnapshot(`
1321 - "assertConsoleWarnDev(expected)
1322 -
1323 - The second argument must be {withoutStack: true}.
1324 -
1325 - Instead received {"withoutStack":{}}."
1326 - `);
1327 - assertConsoleWarnDev(['Hi'], {withoutStack: true});
1328 - });
1329 -
1330 - // @gate __DEV__
1331 - it('fails if withoutStack is invalid string value', () => {
1332 - const message = expectToThrowFailure(() => {
1333 - console.warn('Hi');
1334 - assertConsoleWarnDev(['Hi'], {withoutStack: 'haha'});
1335 - });
1336 - expect(message).toMatchInlineSnapshot(`
1337 - "assertConsoleWarnDev(expected)
1338 -
1339 - The second argument must be {withoutStack: true}.
1340 -
1341 - Instead received {"withoutStack":"haha"}."
1342 - `);
1343 - assertConsoleWarnDev(['Hi'], {withoutStack: true});
1344 - });
1345 -
1346 - // @gate __DEV__
1347 - it('fails if only warning is not expected to have a stack, but does', () => {
1348 - const message = expectToThrowFailure(() => {
1349 - console.warn('Hello\n in div');
1350 - assertConsoleWarnDev(['Hello'], {withoutStack: true});
1351 - });
1352 - expect(message).toMatchInlineSnapshot(`
1353 - "assertConsoleWarnDev(expected)
1354 -
1355 - Unexpected warning(s) recorded.
1356 -
1357 - - Expected warnings
1358 - + Received warnings
1359 -
1360 - - Hello
1361 - + Hello in div (at **)"
1362 - `);
1363 - });
1364 -
1365 - // @gate __DEV__
1366 - it('fails if warnings are not expected to have a stack, but some do', () => {
1367 - const message = expectToThrowFailure(() => {
1368 - console.warn('Hello\n in div');
1369 - console.warn('Good day');
1370 - console.warn('Bye\n in div');
1371 - assertConsoleWarnDev(['Hello', 'Good day', 'Bye'], {
1372 - withoutStack: true,
1373 - });
1374 - });
1375 - expect(message).toMatchInlineSnapshot(`
1376 - "assertConsoleWarnDev(expected)
1377 -
1378 - Unexpected warning(s) recorded.
1379 -
1380 - - Expected warnings
1381 - + Received warnings
1382 -
1383 - - Hello
1384 - + Hello in div (at **)
1385 - Good day
1386 - - Bye
1387 - + Bye in div (at **)"
1388 - `);
1389 - });
1390 - });
1391 - describe('local withoutStack', () => {
1392 - it('passes when expected withoutStack logs matches the actual logs', () => {
1393 - if (__DEV__) {
1394 - console.warn('Hello\n in div');
1395 - console.warn('Good day');
1396 - console.warn('Bye\n in div');
1397 - }
1398 - assertConsoleWarnDev([
1399 - 'Hello\n in div',
1400 - ['Good day', {withoutStack: true}],
1401 - 'Bye\n in div',
1402 - ]);
1403 - });
1404 -
1405 - // @gate __DEV__
1406 - it('fails if withoutStack is invalid null value', () => {
1407 - const message = expectToThrowFailure(() => {
1408 - console.warn('Hi');
1409 - assertConsoleWarnDev([['Hi', {withoutStack: null}]]);
1410 - });
1411 - expect(message).toMatchInlineSnapshot(`
1412 - "assertConsoleWarnDev(expected)
1413 -
1414 - Log entries that are arrays must be of the form [string, {withoutStack: true}]
1415 -
1416 - Instead received [string, {"withoutStack":null}]."
1417 - `);
1418 - });
1419 -
1420 - // @gate __DEV__
1421 - it('fails if withoutStack is invalid {} value', () => {
1422 - const message = expectToThrowFailure(() => {
1423 - console.warn('Hi');
1424 - assertConsoleWarnDev([['Hi', {withoutStack: {}}]]);
1425 - });
1426 - expect(message).toMatchInlineSnapshot(`
1427 - "assertConsoleWarnDev(expected)
1428 -
1429 - Log entries that are arrays must be of the form [string, {withoutStack: true}]
1430 -
1431 - Instead received [string, {"withoutStack":{}}]."
1432 - `);
1433 - });
1434 -
1435 - // @gate __DEV__
1436 - it('fails if withoutStack is invalid string value', () => {
1437 - const message = expectToThrowFailure(() => {
1438 - console.warn('Hi');
1439 - assertConsoleWarnDev([['Hi', {withoutStack: 'haha'}]]);
1440 - });
1441 - expect(message).toMatchInlineSnapshot(`
1442 - "assertConsoleWarnDev(expected)
1443 -
1444 - Log entries that are arrays must be of the form [string, {withoutStack: true}]
1445 -
1446 - Instead received [string, {"withoutStack":"haha"}]."
1447 - `);
1448 - });
1449 -
1450 - // @gate __DEV__
1451 - it('fails if withoutStack is invalid number value', () => {
1452 - const message = expectToThrowFailure(() => {
1453 - console.warn('Hi');
1454 - assertConsoleWarnDev([['Hi', {withoutStack: 4}]]);
1455 - });
1456 - expect(message).toMatchInlineSnapshot(`
1457 - "assertConsoleWarnDev(expected)
1458 -
1459 - Log entries that are arrays must be of the form [string, {withoutStack: true}]
1460 -
1461 - Instead received [string, {"withoutStack":4}]."
1462 - `);
1463 - });
1464 -
1465 - // @gate __DEV__
1466 - it('fails if you forget to wrap local withoutStack in array', () => {
1467 - const message = expectToThrowFailure(() => {
1468 - console.warn('Hello\n in div');
1469 - console.warn('Bye\n in div');
1470 - assertConsoleWarnDev(['Hello', {withoutStack: true}, 'Bye']);
1471 - });
1472 - expect(message).toMatchInlineSnapshot(`
1473 - "assertConsoleWarnDev(expected)
1474 -
1475 - Did you forget to wrap a log with withoutStack in an array?
1476 -
1477 - The expected message for assertConsoleWarnDev() must be a string or an array of length 2.
1478 -
1479 - Instead received {"withoutStack":true}."
1480 - `);
1481 - });
1482 -
1483 - // @gate __DEV__
1484 - it('fails if you wrap in an array unnecessarily', () => {
1485 - const message = expectToThrowFailure(() => {
1486 - console.warn('Hello');
1487 - assertConsoleWarnDev([['Hello']]);
1488 - });
1489 - expect(message).toMatchInlineSnapshot(`
1490 - "assertConsoleWarnDev(expected)
1491 -
1492 - Did you forget to remove the array around the log?
1493 -
1494 - The expected message for assertConsoleWarnDev() must be a string or an array of length 2, but there's only one item in the array. If this is intentional, remove the extra array."
1495 - `);
1496 - });
1497 -
1498 - // @gate __DEV__
1499 - it('fails if only warning is not expected to have a stack, but does', () => {
1500 - const message = expectToThrowFailure(() => {
1501 - console.warn('Hello\n in div');
1502 - assertConsoleWarnDev([['Hello', {withoutStack: true}]]);
1503 - });
1504 - expect(message).toMatchInlineSnapshot(`
1505 - "assertConsoleWarnDev(expected)
1506 -
1507 - Unexpected warning(s) recorded.
1508 -
1509 - - Expected warnings
1510 - + Received warnings
1511 -
1512 - - Hello
1513 - + Hello in div (at **)"
1514 - `);
1515 - });
1516 -
1517 - // @gate __DEV__
1518 - it('fails if warnings are not expected to have a stack, but some do', () => {
1519 - const message = expectToThrowFailure(() => {
1520 - console.warn('Hello\n in div');
1521 - console.warn('Good day');
1522 - console.warn('Bye\n in div');
1523 - assertConsoleWarnDev([
1524 - [
1525 - 'Hello',
1526 - {
1527 - withoutStack: true,
1528 - },
1529 - ],
1530 - 'Good day',
1531 - [
1532 - 'Bye',
1533 - {
1534 - withoutStack: true,
1535 - },
1536 - ],
1537 - ]);
1538 - });
1539 - expect(message).toMatchInlineSnapshot(`
1540 - "assertConsoleWarnDev(expected)
1541 -
1542 - Unexpected warning(s) recorded.
1543 -
1544 - - Expected warnings
1545 - + Received warnings
1546 -
1547 - - Hello
1548 - + Hello in div (at **)
1549 - Good day
1550 - - Bye
1551 - + Bye in div (at **)"
1552 - `);
1553 - });
1554 - });
1555 -
1233 // @gate __DEV__
1234 it('fails if the args is greater than %s argument number', () => {
1235 const message = expectToThrowFailure(() => {
1236 console.warn('Hi %s', 'Sara', 'extra');
1560 - assertConsoleWarnDev(['Hi'], {withoutStack: true});
1237 + assertConsoleWarnDev(['Hi']);
1238 });
1239 expect(message).toMatchInlineSnapshot(`
1240 "assertConsoleWarnDev(expected)
@@ -1572,7 +1249,7 @@ describe('ReactInternalTestUtils console assertions', () => {
1249 const message = expectToThrowFailure(() => {
1250 console.warn('Hi %s', 'Sara', 'extra');
1251 console.warn('Bye %s', 'Sara', 'extra');
1575 - assertConsoleWarnDev(['Hi', 'Bye'], {withoutStack: true});
1252 + assertConsoleWarnDev(['Hi', 'Bye']);
1253 });
1254 expect(message).toMatchInlineSnapshot(`
1255 "assertConsoleWarnDev(expected)
@@ -1589,7 +1266,7 @@ describe('ReactInternalTestUtils console assertions', () => {
1266 it('fails if the %s argument number is greater than args', () => {
1267 const message = expectToThrowFailure(() => {
1268 console.warn('Hi %s');
1592 - assertConsoleWarnDev(['Hi'], {withoutStack: true});
1269 + assertConsoleWarnDev(['Hi']);
1270 });
1271 expect(message).toMatchInlineSnapshot(`
1272 "assertConsoleWarnDev(expected)
@@ -1604,7 +1281,7 @@ describe('ReactInternalTestUtils console assertions', () => {
1281 const message = expectToThrowFailure(() => {
1282 console.warn('Hi %s');
1283 console.warn('Bye %s');
1607 - assertConsoleWarnDev(['Hi', 'Bye'], {withoutStack: true});
1284 + assertConsoleWarnDev(['Hi', 'Bye']);
1285 });
1286 expect(message).toMatchInlineSnapshot(`
1287 "assertConsoleWarnDev(expected)
@@ -2217,7 +1894,7 @@ describe('ReactInternalTestUtils console assertions', () => {
1894 "TypeError: Cannot read properties of undefined (reading 'stack')\n" +
1895 ' in Foo (at **)'
1896 );
2220 - assertConsoleErrorDev([['Hi', {withoutStack: true}]]);
1897 + assertConsoleErrorDev(['Hi']);
1898 });
1899 expect(message).toMatchInlineSnapshot(`
1900 "assertConsoleErrorDev(expected)
@@ -2254,313 +1931,11 @@ describe('ReactInternalTestUtils console assertions', () => {
1931 `);
1932 });
1933
2257 - describe('global withoutStack', () => {
2258 - it('passes if errors without stack explicitly opt out', () => {
2259 - if (__DEV__) {
2260 - console.error('Hello');
2261 - }
2262 - assertConsoleErrorDev(['Hello'], {withoutStack: true});
2263 -
2264 - if (__DEV__) {
2265 - console.error('Hello');
2266 - console.error('Good day');
2267 - console.error('Bye');
2268 - }
2269 -
2270 - assertConsoleErrorDev(['Hello', 'Good day', 'Bye'], {
2271 - withoutStack: true,
2272 - });
2273 - });
2274 -
2275 - // @gate __DEV__
2276 - it('fails if withoutStack is invalid null value', () => {
2277 - const message = expectToThrowFailure(() => {
2278 - console.error('Hi');
2279 - assertConsoleErrorDev(['Hi'], {withoutStack: null});
2280 - });
2281 - expect(message).toMatchInlineSnapshot(`
2282 - "assertConsoleErrorDev(expected)
2283 -
2284 - The second argument must be {withoutStack: true}.
2285 -
2286 - Instead received {"withoutStack":null}."
2287 - `);
2288 - assertConsoleErrorDev(['Hi'], {withoutStack: true});
2289 - });
2290 -
2291 - // @gate __DEV__
2292 - it('fails if withoutStack is invalid {} value', () => {
2293 - const message = expectToThrowFailure(() => {
2294 - console.error('Hi');
2295 - assertConsoleErrorDev(['Hi'], {withoutStack: {}});
2296 - });
2297 - expect(message).toMatchInlineSnapshot(`
2298 - "assertConsoleErrorDev(expected)
2299 -
2300 - The second argument must be {withoutStack: true}.
2301 -
2302 - Instead received {"withoutStack":{}}."
2303 - `);
2304 - assertConsoleErrorDev(['Hi'], {withoutStack: true});
2305 - });
2306 -
2307 - // @gate __DEV__
2308 - it('fails if withoutStack is invalid string value', () => {
2309 - const message = expectToThrowFailure(() => {
2310 - console.error('Hi');
2311 - assertConsoleErrorDev(['Hi'], {withoutStack: 'haha'});
2312 - });
2313 - expect(message).toMatchInlineSnapshot(`
2314 - "assertConsoleErrorDev(expected)
2315 -
2316 - The second argument must be {withoutStack: true}.
2317 -
2318 - Instead received {"withoutStack":"haha"}."
2319 - `);
2320 - assertConsoleErrorDev(['Hi'], {withoutStack: true});
2321 - });
2322 -
2323 - // @gate __DEV__
2324 - it('fails if only error is not expected to have a stack, but does', () => {
2325 - const message = expectToThrowFailure(() => {
2326 - console.error('Hello\n in div');
2327 - assertConsoleErrorDev(['Hello'], {withoutStack: true});
2328 - });
2329 - expect(message).toMatchInlineSnapshot(`
2330 - "assertConsoleErrorDev(expected)
2331 -
2332 - Unexpected error(s) recorded.
2333 -
2334 - - Expected errors
2335 - + Received errors
2336 -
2337 - - Hello
2338 - + Hello in div (at **)"
2339 - `);
2340 - });
2341 -
2342 - // @gate __DEV__
2343 - it('fails if errors are not expected to have a stack, but some do', () => {
2344 - const message = expectToThrowFailure(() => {
2345 - console.error('Hello\n in div');
2346 - console.error('Good day');
2347 - console.error('Bye\n in div');
2348 - assertConsoleErrorDev(['Hello', 'Good day', 'Bye'], {
2349 - withoutStack: true,
2350 - });
2351 - });
2352 - expect(message).toMatchInlineSnapshot(`
2353 - "assertConsoleErrorDev(expected)
2354 -
2355 - Unexpected error(s) recorded.
2356 -
2357 - - Expected errors
2358 - + Received errors
2359 -
2360 - - Hello
2361 - + Hello in div (at **)
2362 - Good day
2363 - - Bye
2364 - + Bye in div (at **)"
2365 - `);
2366 - });
2367 - });
2368 - describe('local withoutStack', () => {
2369 - it('passes when expected withoutStack logs matches the actual logs', () => {
2370 - if (__DEV__) {
2371 - console.error('Hello\n in div');
2372 - console.error('Good day');
2373 - console.error('Bye\n in div');
2374 - }
2375 - assertConsoleErrorDev([
2376 - 'Hello\n in div',
2377 - ['Good day', {withoutStack: true}],
2378 - 'Bye\n in div',
2379 - ]);
2380 - });
2381 -
2382 - // @gate __DEV__
2383 - it('fails if withoutStack is invalid null value', () => {
2384 - const message = expectToThrowFailure(() => {
2385 - console.error('Hi');
2386 - assertConsoleErrorDev([['Hi', {withoutStack: null}]]);
2387 - });
2388 - expect(message).toMatchInlineSnapshot(`
2389 - "assertConsoleErrorDev(expected)
2390 -
2391 - Log entries that are arrays must be of the form [string, {withoutStack: true}]
2392 -
2393 - Instead received [string, {"withoutStack":null}]."
2394 - `);
2395 - });
2396 -
2397 - // @gate __DEV__
2398 - it('fails if withoutStack is invalid {} value', () => {
2399 - const message = expectToThrowFailure(() => {
2400 - console.error('Hi');
2401 - assertConsoleErrorDev([['Hi', {withoutStack: {}}]]);
2402 - });
2403 - expect(message).toMatchInlineSnapshot(`
2404 - "assertConsoleErrorDev(expected)
2405 -
2406 - Log entries that are arrays must be of the form [string, {withoutStack: true}]
2407 -
2408 - Instead received [string, {"withoutStack":{}}]."
2409 - `);
2410 - });
2411 -
2412 - // @gate __DEV__
2413 - it('fails if withoutStack is invalid string value', () => {
2414 - const message = expectToThrowFailure(() => {
2415 - console.error('Hi');
2416 - assertConsoleErrorDev([['Hi', {withoutStack: 'haha'}]]);
2417 - });
2418 - expect(message).toMatchInlineSnapshot(`
2419 - "assertConsoleErrorDev(expected)
2420 -
2421 - Log entries that are arrays must be of the form [string, {withoutStack: true}]
2422 -
2423 - Instead received [string, {"withoutStack":"haha"}]."
2424 - `);
2425 - });
2426 -
2427 - // @gate __DEV__
2428 - it('fails if withoutStack is invalid number value', () => {
2429 - const message = expectToThrowFailure(() => {
2430 - console.error('Hi');
2431 - assertConsoleErrorDev([['Hi', {withoutStack: 4}]]);
2432 - });
2433 - expect(message).toMatchInlineSnapshot(`
2434 - "assertConsoleErrorDev(expected)
2435 -
2436 - Log entries that are arrays must be of the form [string, {withoutStack: true}]
2437 -
2438 - Instead received [string, {"withoutStack":4}]."
2439 - `);
2440 - });
2441 -
2442 - // @gate __DEV__
2443 - it('fails if you forget to wrap local withoutStack in array', () => {
2444 - const message = expectToThrowFailure(() => {
2445 - console.error('Hello\n in div');
2446 - console.error('Bye\n in div');
2447 - assertConsoleErrorDev(['Hello', {withoutStack: true}, 'Bye']);
2448 - });
2449 - expect(message).toMatchInlineSnapshot(`
2450 - "assertConsoleErrorDev(expected)
2451 -
2452 - Did you forget to wrap a log with withoutStack in an array?
2453 -
2454 - The expected message for assertConsoleErrorDev() must be a string or an array of length 2.
2455 -
2456 - Instead received {"withoutStack":true}."
2457 - `);
2458 - });
2459 -
2460 - // @gate __DEV__
2461 - it('fails if you wrap in an array unnecessarily', () => {
2462 - const message = expectToThrowFailure(() => {
2463 - console.error('Hello');
2464 - assertConsoleErrorDev([['Hello']]);
2465 - });
2466 - expect(message).toMatchInlineSnapshot(`
2467 - "assertConsoleErrorDev(expected)
2468 -
2469 - Did you forget to remove the array around the log?
2470 -
2471 - The expected message for assertConsoleErrorDev() must be a string or an array of length 2, but there's only one item in the array. If this is intentional, remove the extra array."
2472 - `);
2473 - });
2474 -
2475 - // @gate __DEV__
2476 - it('fails if only error is not expected to have a stack, but does', () => {
2477 - const message = expectToThrowFailure(() => {
2478 - console.error('Hello\n in div');
2479 - assertConsoleErrorDev([['Hello', {withoutStack: true}]]);
2480 - });
2481 - expect(message).toMatchInlineSnapshot(`
2482 - "assertConsoleErrorDev(expected)
2483 -
2484 - Unexpected error(s) recorded.
2485 -
2486 - - Expected errors
2487 - + Received errors
2488 -
2489 - - Hello
2490 - + Hello in div (at **)"
2491 - `);
2492 - });
2493 -
2494 - // @gate __DEV__
2495 - it('fails if errors are not expected to have a stack, but some do', () => {
2496 - const message = expectToThrowFailure(() => {
2497 - console.error('Hello\n in div');
2498 - console.error('Good day');
2499 - console.error('Bye\n in div');
2500 - assertConsoleErrorDev([
2501 - [
2502 - 'Hello',
2503 - {
2504 - withoutStack: true,
2505 - },
2506 - ],
2507 - 'Good day',
2508 - [
2509 - 'Bye',
2510 - {
2511 - withoutStack: true,
2512 - },
2513 - ],
2514 - ]);
2515 - });
2516 - expect(message).toMatchInlineSnapshot(`
2517 - "assertConsoleErrorDev(expected)
2518 -
2519 - Unexpected error(s) recorded.
2520 -
2521 - - Expected errors
2522 - + Received errors
2523 -
2524 - - Hello
2525 - + Hello in div (at **)
2526 - Good day
2527 - - Bye
2528 - + Bye in div (at **)"
2529 - `);
2530 - });
2531 -
2532 - // @gate __DEV__
2533 - it('fails with a helpful error message if the expected error message mismatches', () => {
2534 - const message = expectToThrowFailure(() => {
2535 - console.error('Bye\n in div');
2536 - assertConsoleErrorDev([
2537 - [
2538 - 'Hello',
2539 - {
2540 - withoutStack: true,
2541 - },
2542 - ],
2543 - ]);
2544 - });
2545 - expect(message).toMatchInlineSnapshot(`
2546 - "assertConsoleErrorDev(expected)
2547 -
2548 - Unexpected error(s) recorded.
2549 -
2550 - - Expected errors
2551 - + Received errors
2552 -
2553 - - Hello
2554 - + Bye in div (at **)"
2555 - `);
2556 - });
2557 - });
2558 -
1934 // @gate __DEV__
1935 it('fails if the args is greater than %s argument number', () => {
1936 const message = expectToThrowFailure(() => {
1937 console.error('Hi %s', 'Sara', 'extra');
2563 - assertConsoleErrorDev(['Hi'], {withoutStack: true});
1938 + assertConsoleErrorDev(['Hi']);
1939 });
1940 expect(message).toMatchInlineSnapshot(`
1941 "assertConsoleErrorDev(expected)
@@ -2575,7 +1950,7 @@ describe('ReactInternalTestUtils console assertions', () => {
1950 const message = expectToThrowFailure(() => {
1951 console.error('Hi %s', 'Sara', 'extra');
1952 console.error('Bye %s', 'Sara', 'extra');
2578 - assertConsoleErrorDev(['Hi', 'Bye'], {withoutStack: true});
1953 + assertConsoleErrorDev(['Hi', 'Bye']);
1954 });
1955 expect(message).toMatchInlineSnapshot(`
1956 "assertConsoleErrorDev(expected)
@@ -2592,7 +1967,7 @@ describe('ReactInternalTestUtils console assertions', () => {
1967 it('fails if the %s argument number is greater than args', () => {
1968 const message = expectToThrowFailure(() => {
1969 console.error('Hi %s');
2595 - assertConsoleErrorDev(['Hi'], {withoutStack: true});
1970 + assertConsoleErrorDev(['Hi']);
1971 });
1972 expect(message).toMatchInlineSnapshot(`
1973 "assertConsoleErrorDev(expected)
@@ -2607,7 +1982,7 @@ describe('ReactInternalTestUtils console assertions', () => {
1982 const message = expectToThrowFailure(() => {
1983 console.error('Hi %s');
1984 console.error('Bye %s');
2610 - assertConsoleErrorDev(['Hi', 'Bye'], {withoutStack: true});
1985 + assertConsoleErrorDev(['Hi', 'Bye']);
1986 });
1987 expect(message).toMatchInlineSnapshot(`
1988 "assertConsoleErrorDev(expected)
@@ -2812,27 +2187,21 @@ describe('ReactInternalTestUtils console assertions', () => {
2187 it('expands [Server] to ANSI escape sequence for server badge', () => {
2188 const badge = '\u001b[0m\u001b[7m Server \u001b[0m';
2189 console.error(badge + 'Error: something went wrong');
2815 - assertConsoleErrorDev([
2816 - ['[Server] Error: something went wrong', {withoutStack: true}],
2817 - ]);
2190 + assertConsoleErrorDev(['[Server] Error: something went wrong']);
2191 });
2192
2193 // @gate __DEV__
2194 it('expands [Prerender] to ANSI escape sequence for server badge', () => {
2195 const badge = '\u001b[0m\u001b[7m Prerender \u001b[0m';
2196 console.error(badge + 'Error: something went wrong');
2824 - assertConsoleErrorDev([
2825 - ['[Prerender] Error: something went wrong', {withoutStack: true}],
2826 - ]);
2197 + assertConsoleErrorDev(['[Prerender] Error: something went wrong']);
2198 });
2199
2200 // @gate __DEV__
2201 it('expands [Cache] to ANSI escape sequence for server badge', () => {
2202 const badge = '\u001b[0m\u001b[7m Cache \u001b[0m';
2203 console.error(badge + 'Error: something went wrong');
2833 - assertConsoleErrorDev([
2834 - ['[Cache] Error: something went wrong', {withoutStack: true}],
2835 - ]);
2204 + assertConsoleErrorDev(['[Cache] Error: something went wrong']);
2205 });
2206 });
2207
packages/internal-test-utils/consoleMock.js
+3 -125
@@ -290,26 +290,11 @@ export function createLogAssertion(
290 }
291 }
292
293 - const withoutStack = options.withoutStack;
294 -
295 - if (consoleMethod === 'log' && withoutStack !== undefined) {
296 - throwFormattedError(
297 - `Do not pass withoutStack to assertConsoleLogDev, console.log does not have component stacks.`,
298 - );
299 - } else if (withoutStack !== undefined && withoutStack !== true) {
300 - throwFormattedError(
301 - `The second argument must be {withoutStack: true}.` +
302 - `\n\nInstead received ${JSON.stringify(options)}.`,
303 - );
304 - }
305 -
293 const observedLogs = clearObservedErrors();
294 const receivedLogs = [];
295 const missingExpectedLogs = Array.from(expectedMessages);
296
297 const unexpectedLogs = [];
311 - const unexpectedMissingComponentStack = [];
312 - const unexpectedIncludingComponentStack = [];
298 const unexpectedMissingErrorStack = [];
299 const unexpectedIncludingErrorStack = [];
300 const logsMismatchingFormat = [];
@@ -334,72 +319,12 @@ export function createLogAssertion(
319 }
320
321 let expectedMessage;
337 - let expectedWithoutStack;
322 const expectedMessageOrArray = expectedMessages[index];
339 - if (
340 - expectedMessageOrArray != null &&
341 - Array.isArray(expectedMessageOrArray)
342 - ) {
343 - // Should be in the local form assert([['log', {withoutStack: true}]])
344 -
345 - // Some validations for common mistakes.
346 - if (expectedMessageOrArray.length === 1) {
347 - throwFormattedError(
348 - `Did you forget to remove the array around the log?` +
349 - `\n\nThe expected message for ${matcherName}() must be a string or an array of length 2, but there's only one item in the array. If this is intentional, remove the extra array.`,
350 - );
351 - } else if (expectedMessageOrArray.length !== 2) {
352 - throwFormattedError(
353 - `The expected message for ${matcherName}() must be a string or an array of length 2. ` +
354 - `Instead received ${expectedMessageOrArray}.`,
355 - );
356 - } else if (consoleMethod === 'log') {
357 - // We don't expect any console.log calls to have a stack.
358 - throwFormattedError(
359 - `Do not pass withoutStack to assertConsoleLogDev logs, console.log does not have component stacks.`,
360 - );
361 - }
362 -
363 - // Format is correct, check the values.
364 - const currentExpectedMessage = expectedMessageOrArray[0];
365 - const currentExpectedOptions = expectedMessageOrArray[1];
366 - if (
367 - typeof currentExpectedMessage !== 'string' ||
368 - typeof currentExpectedOptions !== 'object' ||
369 - currentExpectedOptions.withoutStack !== true
370 - ) {
371 - throwFormattedError(
372 - `Log entries that are arrays must be of the form [string, {withoutStack: true}]` +
373 - `\n\nInstead received [${typeof currentExpectedMessage}, ${JSON.stringify(
374 - currentExpectedOptions,
375 - )}].`,
376 - );
377 - }
378 -
379 - expectedMessage = normalizeExpectedMessage(currentExpectedMessage);
380 - expectedWithoutStack = expectedMessageOrArray[1].withoutStack;
381 - } else if (typeof expectedMessageOrArray === 'string') {
323 + if (typeof expectedMessageOrArray === 'string') {
324 expectedMessage = normalizeExpectedMessage(expectedMessageOrArray);
383 - // withoutStack: inherit from global option - simplify when withoutStack is removed.
384 - if (consoleMethod === 'log') {
385 - expectedWithoutStack = true;
386 - } else {
387 - expectedWithoutStack = withoutStack;
388 - }
389 - } else if (
390 - typeof expectedMessageOrArray === 'object' &&
391 - expectedMessageOrArray != null &&
392 - expectedMessageOrArray.withoutStack != null
393 - ) {
394 - // Special case for common case of a wrong withoutStack value.
395 - throwFormattedError(
396 - `Did you forget to wrap a log with withoutStack in an array?` +
397 - `\n\nThe expected message for ${matcherName}() must be a string or an array of length 2.` +
398 - `\n\nInstead received ${JSON.stringify(expectedMessageOrArray)}.`,
399 - );
325 } else if (expectedMessageOrArray != null) {
326 throwFormattedError(
402 - `The expected message for ${matcherName}() must be a string or an array of length 2. ` +
327 + `The expected message for ${matcherName}() must be a string. ` +
328 `Instead received ${JSON.stringify(expectedMessageOrArray)}.`,
329 );
330 }
@@ -499,18 +424,6 @@ export function createLogAssertion(
424 }
425
426 if (matchesExpectedMessage) {
502 - // withoutStack: Check for unexpected/missing component stacks.
503 - // These checks can be simplified when withoutStack is removed.
504 - if (isLikelyAComponentStack(normalizedMessage)) {
505 - if (expectedWithoutStack === true && !hasErrorStack) {
506 - // Only report unexpected component stack if it's not an error stack
507 - // (error stacks look like component stacks after normalization)
508 - unexpectedIncludingComponentStack.push(normalizedMessage);
509 - }
510 - } else if (expectedWithoutStack !== true && !expectsErrorStack) {
511 - unexpectedMissingComponentStack.push(normalizedMessage);
512 - }
513 -
427 // Check for unexpected/missing error stacks
428 if (hasErrorStack && !expectsErrorStack) {
429 // Error stack is present but \n in <stack> was not in the expected message
@@ -538,12 +451,7 @@ export function createLogAssertion(
451 function printDiff() {
452 return `${diff(
453 expectedMessages
541 - .map(messageOrTuple => {
542 - const message = Array.isArray(messageOrTuple)
543 - ? messageOrTuple[0]
544 - : messageOrTuple;
545 - return message.replace('\n', ' ');
546 - })
454 + .map(message => message.replace('\n', ' '))
455 .join('\n'),
456 receivedLogs.map(message => message.replace('\n', ' ')).join('\n'),
457 {
@@ -582,36 +490,6 @@ export function createLogAssertion(
490 );
491 }
492
585 - // Any logs that include a component stack but shouldn't.
586 - if (unexpectedIncludingComponentStack.length > 0) {
587 - throwFormattedError(
588 - `${unexpectedIncludingComponentStack
589 - .map(
590 - stack =>
591 - `Unexpected component stack for:\n ${printReceived(stack)}`,
592 - )
593 - .join(
594 - '\n\n',
595 - )}\n\nIf this ${logName()} should include a component stack, remove {withoutStack: true} from this ${logName()}.` +
596 - `\nIf all ${logName()}s should include the component stack, you may need to remove {withoutStack: true} from the ${matcherName} call.`,
597 - );
598 - }
599 -
600 - // Any logs that are missing a component stack without withoutStack.
601 - if (unexpectedMissingComponentStack.length > 0) {
602 - throwFormattedError(
603 - `${unexpectedMissingComponentStack
604 - .map(
605 - stack =>
606 - `Missing component stack for:\n ${printReceived(stack)}`,
607 - )
608 - .join(
609 - '\n\n',
610 - )}\n\nIf this ${logName()} should omit a component stack, pass [log, {withoutStack: true}].` +
611 - `\nIf all ${logName()}s should omit the component stack, add {withoutStack: true} to the ${matcherName} call.`,
612 - );
613 - }
614 -
493 // Any logs that include an error stack trace but \n in <stack> wasn't expected.
494 if (unexpectedIncludingErrorStack.length > 0) {
495 throwFormattedError(
packages/react-client/src/__tests__/ReactFlight-test.js
+58 -88
@@ -1514,16 +1514,13 @@ describe('ReactFlight', () => {
1514 },
1515 };
1516 const transport = ReactNoopFlightServer.render(<input value={obj} />);
1517 - assertConsoleErrorDev(
1518 - [
1519 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1520 - 'Objects with toJSON methods are not supported. ' +
1521 - 'Convert it manually to a simple value before passing it to props.\n' +
1522 - ' <input value={{toJSON: ...}}>\n' +
1523 - ' ^^^^^^^^^^^^^^^',
1524 - ],
1525 - {withoutStack: true},
1526 - );
1517 + assertConsoleErrorDev([
1518 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1519 + 'Objects with toJSON methods are not supported. ' +
1520 + 'Convert it manually to a simple value before passing it to props.\n' +
1521 + ' <input value={{toJSON: ...}}>\n' +
1522 + ' ^^^^^^^^^^^^^^^',
1523 + ]);
1524
1525 ReactNoopFlightClient.read(transport);
1526 assertConsoleErrorDev([
@@ -1545,14 +1542,11 @@ describe('ReactFlight', () => {
1542 const transport = ReactNoopFlightServer.render(
1543 <div>Womp womp: {new MyError('spaghetti')}</div>,
1544 );
1548 - assertConsoleErrorDev(
1549 - [
1550 - 'Error objects cannot be rendered as text children. Try formatting it using toString().\n' +
1551 - ' <div>Womp womp: {Error}</div>\n' +
1552 - ' ^^^^^^^',
1553 - ],
1554 - {withoutStack: true},
1555 - );
1545 + assertConsoleErrorDev([
1546 + 'Error objects cannot be rendered as text children. Try formatting it using toString().\n' +
1547 + ' <div>Womp womp: {Error}</div>\n' +
1548 + ' ^^^^^^^',
1549 + ]);
1550
1551 ReactNoopFlightClient.read(transport);
1552 assertConsoleErrorDev([
@@ -1565,15 +1559,12 @@ describe('ReactFlight', () => {
1559
1560 it('should warn in DEV if a special object is passed to a host component', () => {
1561 const transport = ReactNoopFlightServer.render(<input value={Math} />);
1568 - assertConsoleErrorDev(
1569 - [
1570 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1571 - 'Math objects are not supported.\n' +
1572 - ' <input value={Math}>\n' +
1573 - ' ^^^^^^',
1574 - ],
1575 - {withoutStack: true},
1576 - );
1562 + assertConsoleErrorDev([
1563 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1564 + 'Math objects are not supported.\n' +
1565 + ' <input value={Math}>\n' +
1566 + ' ^^^^^^',
1567 + ]);
1568
1569 ReactNoopFlightClient.read(transport);
1570 assertConsoleErrorDev([
@@ -1589,15 +1580,12 @@ describe('ReactFlight', () => {
1580 const transport = ReactNoopFlightServer.render(
1581 <input value={{[Symbol.iterator]: {}}} />,
1582 );
1592 - assertConsoleErrorDev(
1593 - [
1594 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1595 - 'Objects with symbol properties like Symbol.iterator are not supported.\n' +
1596 - ' <input value={{}}>\n' +
1597 - ' ^^^^',
1598 - ],
1599 - {withoutStack: true},
1600 - );
1583 + assertConsoleErrorDev([
1584 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1585 + 'Objects with symbol properties like Symbol.iterator are not supported.\n' +
1586 + ' <input value={{}}>\n' +
1587 + ' ^^^^',
1588 + ]);
1589
1590 ReactNoopFlightClient.read(transport);
1591 assertConsoleErrorDev([
@@ -1620,16 +1608,13 @@ describe('ReactFlight', () => {
1608 }
1609 const Client = clientReference(ClientImpl);
1610 const transport = ReactNoopFlightServer.render(<Client value={obj} />);
1623 - assertConsoleErrorDev(
1624 - [
1625 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1626 - 'Objects with toJSON methods are not supported. ' +
1627 - 'Convert it manually to a simple value before passing it to props.\n' +
1628 - ' <... value={{toJSON: ...}}>\n' +
1629 - ' ^^^^^^^^^^^^^^^',
1630 - ],
1631 - {withoutStack: true},
1632 - );
1611 + assertConsoleErrorDev([
1612 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1613 + 'Objects with toJSON methods are not supported. ' +
1614 + 'Convert it manually to a simple value before passing it to props.\n' +
1615 + ' <... value={{toJSON: ...}}>\n' +
1616 + ' ^^^^^^^^^^^^^^^',
1617 + ]);
1618
1619 ReactNoopFlightClient.read(transport);
1620 assertConsoleErrorDev([
@@ -1655,16 +1640,13 @@ describe('ReactFlight', () => {
1640 const transport = ReactNoopFlightServer.render(
1641 <Client>Current date: {obj}</Client>,
1642 );
1658 - assertConsoleErrorDev(
1659 - [
1660 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1661 - 'Objects with toJSON methods are not supported. ' +
1662 - 'Convert it manually to a simple value before passing it to props.\n' +
1663 - ' <>Current date: {{toJSON: ...}}</>\n' +
1664 - ' ^^^^^^^^^^^^^^^',
1665 - ],
1666 - {withoutStack: true},
1667 - );
1643 + assertConsoleErrorDev([
1644 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1645 + 'Objects with toJSON methods are not supported. ' +
1646 + 'Convert it manually to a simple value before passing it to props.\n' +
1647 + ' <>Current date: {{toJSON: ...}}</>\n' +
1648 + ' ^^^^^^^^^^^^^^^',
1649 + ]);
1650
1651 ReactNoopFlightClient.read(transport);
1652 assertConsoleErrorDev([
@@ -1683,15 +1665,12 @@ describe('ReactFlight', () => {
1665 }
1666 const Client = clientReference(ClientImpl);
1667 const transport = ReactNoopFlightServer.render(<Client value={Math} />);
1686 - assertConsoleErrorDev(
1687 - [
1688 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1689 - 'Math objects are not supported.\n' +
1690 - ' <... value={Math}>\n' +
1691 - ' ^^^^^^',
1692 - ],
1693 - {withoutStack: true},
1694 - );
1668 + assertConsoleErrorDev([
1669 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1670 + 'Math objects are not supported.\n' +
1671 + ' <... value={Math}>\n' +
1672 + ' ^^^^^^',
1673 + ]);
1674
1675 ReactNoopFlightClient.read(transport);
1676 assertConsoleErrorDev([
@@ -1712,15 +1691,12 @@ describe('ReactFlight', () => {
1691 const transport = ReactNoopFlightServer.render(
1692 <Client value={{[Symbol.iterator]: {}}} />,
1693 );
1715 - assertConsoleErrorDev(
1716 - [
1717 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1718 - 'Objects with symbol properties like Symbol.iterator are not supported.\n' +
1719 - ' <... value={{}}>\n' +
1720 - ' ^^^^',
1721 - ],
1722 - {withoutStack: true},
1723 - );
1694 + assertConsoleErrorDev([
1695 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1696 + 'Objects with symbol properties like Symbol.iterator are not supported.\n' +
1697 + ' <... value={{}}>\n' +
1698 + ' ^^^^',
1699 + ]);
1700
1701 ReactNoopFlightClient.read(transport);
1702
@@ -1744,13 +1720,10 @@ describe('ReactFlight', () => {
1720 ReactNoopFlightClient.read(transport);
1721
1722 assertConsoleErrorDev([
1747 - [
1748 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1749 - 'Objects with symbol properties like Symbol.iterator are not supported.\n' +
1750 - ' <... value={{}}>\n' +
1751 - ' ^^^^',
1752 - {withoutStack: true},
1753 - ],
1723 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1724 + 'Objects with symbol properties like Symbol.iterator are not supported.\n' +
1725 + ' <... value={{}}>\n' +
1726 + ' ^^^^',
1727 'Only plain objects can be passed to Client Components from Server Components. ' +
1728 'Objects with symbol properties like Symbol.iterator are not supported.\n' +
1729 ' <... value={{}}>\n' +
@@ -1769,13 +1742,10 @@ describe('ReactFlight', () => {
1742 );
1743 ReactNoopFlightClient.read(transport);
1744 assertConsoleErrorDev([
1772 - [
1773 - 'Only plain objects can be passed to Client Components from Server Components. ' +
1774 - 'Math objects are not supported.\n' +
1775 - ' [..., Math, <h1/>]\n' +
1776 - ' ^^^^',
1777 - {withoutStack: true},
1778 - ],
1745 + 'Only plain objects can be passed to Client Components from Server Components. ' +
1746 + 'Math objects are not supported.\n' +
1747 + ' [..., Math, <h1/>]\n' +
1748 + ' ^^^^',
1749 'Only plain objects can be passed to Client Components from Server Components. ' +
1750 'Math objects are not supported.\n' +
1751 ' [..., Math, <h1/>]\n' +
packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
+157 -193
@@ -642,35 +642,32 @@ describe('ReactComponentLifeCycle', () => {
642 'https://react.dev/link/unsafe-component-lifecycles\n' +
643 ' in Component (at **)',
644 ]);
645 - assertConsoleWarnDev(
646 - [
647 - 'componentWillMount has been renamed, and is not recommended for use. ' +
648 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
649 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
650 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
651 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
652 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
653 - 'Please update the following components: Component',
654 - 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
655 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
656 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
657 - "* If you're updating state whenever props change, refactor your code to use " +
658 - 'memoization techniques or move it to static getDerivedStateFromProps. ' +
659 - 'Learn more at: https://react.dev/link/derived-state\n' +
660 - '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
661 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
662 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
663 - 'Please update the following components: Component',
664 - 'componentWillUpdate has been renamed, and is not recommended for use. ' +
665 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
666 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
667 - '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
668 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
669 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
670 - 'Please update the following components: Component',
671 - ],
672 - {withoutStack: true},
673 - );
645 + assertConsoleWarnDev([
646 + 'componentWillMount has been renamed, and is not recommended for use. ' +
647 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
648 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
649 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
650 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
651 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
652 + 'Please update the following components: Component',
653 + 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
654 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
655 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
656 + "* If you're updating state whenever props change, refactor your code to use " +
657 + 'memoization techniques or move it to static getDerivedStateFromProps. ' +
658 + 'Learn more at: https://react.dev/link/derived-state\n' +
659 + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
660 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
661 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
662 + 'Please update the following components: Component',
663 + 'componentWillUpdate has been renamed, and is not recommended for use. ' +
664 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
665 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
666 + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
667 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
668 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
669 + 'Please update the following components: Component',
670 + ]);
671 });
672
673 it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', async () => {
@@ -708,35 +705,32 @@ describe('ReactComponentLifeCycle', () => {
705 'https://react.dev/link/unsafe-component-lifecycles\n' +
706 ' in Component (at **)',
707 ]);
711 - assertConsoleWarnDev(
712 - [
713 - 'componentWillMount has been renamed, and is not recommended for use. ' +
714 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
715 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
716 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
717 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
718 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
719 - 'Please update the following components: Component',
720 - 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
721 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
722 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
723 - "* If you're updating state whenever props change, refactor your code to use " +
724 - 'memoization techniques or move it to static getDerivedStateFromProps. ' +
725 - 'Learn more at: https://react.dev/link/derived-state\n' +
726 - '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
727 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
728 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
729 - 'Please update the following components: Component',
730 - 'componentWillUpdate has been renamed, and is not recommended for use. ' +
731 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
732 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
733 - '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
734 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
735 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
736 - 'Please update the following components: Component',
737 - ],
738 - {withoutStack: true},
739 - );
708 + assertConsoleWarnDev([
709 + 'componentWillMount has been renamed, and is not recommended for use. ' +
710 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
711 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
712 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
713 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
714 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
715 + 'Please update the following components: Component',
716 + 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
717 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
718 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
719 + "* If you're updating state whenever props change, refactor your code to use " +
720 + 'memoization techniques or move it to static getDerivedStateFromProps. ' +
721 + 'Learn more at: https://react.dev/link/derived-state\n' +
722 + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
723 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
724 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
725 + 'Please update the following components: Component',
726 + 'componentWillUpdate has been renamed, and is not recommended for use. ' +
727 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
728 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
729 + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
730 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
731 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
732 + 'Please update the following components: Component',
733 + ]);
734
735 await act(() => {
736 root.render(<Component value={2} />);
@@ -810,25 +804,22 @@ describe('ReactComponentLifeCycle', () => {
804 'https://react.dev/link/unsafe-component-lifecycles\n' +
805 ' in AllLegacyLifecycles (at **)',
806 ]);
813 - assertConsoleWarnDev(
814 - [
815 - 'componentWillMount has been renamed, and is not recommended for use. ' +
816 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
817 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
818 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
819 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
820 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
821 - 'Please update the following components: AllLegacyLifecycles',
822 - 'componentWillUpdate has been renamed, and is not recommended for use. ' +
823 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
824 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
825 - '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
826 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
827 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
828 - 'Please update the following components: AllLegacyLifecycles',
829 - ],
830 - {withoutStack: true},
831 - );
807 + assertConsoleWarnDev([
808 + 'componentWillMount has been renamed, and is not recommended for use. ' +
809 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
810 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
811 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
812 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
813 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
814 + 'Please update the following components: AllLegacyLifecycles',
815 + 'componentWillUpdate has been renamed, and is not recommended for use. ' +
816 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
817 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
818 + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
819 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
820 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
821 + 'Please update the following components: AllLegacyLifecycles',
822 + ]);
823
824 class WillMount extends React.Component {
825 state = {};
@@ -877,18 +868,15 @@ describe('ReactComponentLifeCycle', () => {
868 'https://react.dev/link/unsafe-component-lifecycles\n' +
869 ' in WillMountAndUpdate (at **)',
870 ]);
880 - assertConsoleWarnDev(
881 - [
882 - 'componentWillMount has been renamed, and is not recommended for use. ' +
883 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
884 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
885 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
886 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
887 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
888 - 'Please update the following components: WillMountAndUpdate',
889 - ],
890 - {withoutStack: true},
891 - );
871 + assertConsoleWarnDev([
872 + 'componentWillMount has been renamed, and is not recommended for use. ' +
873 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
874 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
875 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
876 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
877 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
878 + 'Please update the following components: WillMountAndUpdate',
879 + ]);
880
881 class WillReceiveProps extends React.Component {
882 state = {};
@@ -912,23 +900,18 @@ describe('ReactComponentLifeCycle', () => {
900 'https://react.dev/link/unsafe-component-lifecycles\n' +
901 ' in WillReceiveProps (at **)',
902 ]);
915 - assertConsoleWarnDev(
916 - [
917 - 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
918 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
919 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
920 - "* If you're updating state whenever props change, refactor your code to use " +
921 - 'memoization techniques or move it to static getDerivedStateFromProps. ' +
922 - 'Learn more at: https://react.dev/link/derived-state\n' +
923 - '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
924 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
925 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
926 - 'Please update the following components: WillReceiveProps',
927 - ],
928 - {
929 - withoutStack: true,
930 - },
931 - );
903 + assertConsoleWarnDev([
904 + 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
905 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
906 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
907 + "* If you're updating state whenever props change, refactor your code to use " +
908 + 'memoization techniques or move it to static getDerivedStateFromProps. ' +
909 + 'Learn more at: https://react.dev/link/derived-state\n' +
910 + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
911 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
912 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
913 + 'Please update the following components: WillReceiveProps',
914 + ]);
915 });
916
917 it('should warn about deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', async () => {
@@ -958,25 +941,22 @@ describe('ReactComponentLifeCycle', () => {
941 'https://react.dev/link/unsafe-component-lifecycles\n' +
942 ' in AllLegacyLifecycles (at **)',
943 ]);
961 - assertConsoleWarnDev(
962 - [
963 - 'componentWillMount has been renamed, and is not recommended for use. ' +
964 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
965 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
966 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
967 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
968 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
969 - 'Please update the following components: AllLegacyLifecycles',
970 - 'componentWillUpdate has been renamed, and is not recommended for use. ' +
971 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
972 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
973 - '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
974 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
975 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
976 - 'Please update the following components: AllLegacyLifecycles',
977 - ],
978 - {withoutStack: true},
979 - );
944 + assertConsoleWarnDev([
945 + 'componentWillMount has been renamed, and is not recommended for use. ' +
946 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
947 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
948 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
949 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
950 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
951 + 'Please update the following components: AllLegacyLifecycles',
952 + 'componentWillUpdate has been renamed, and is not recommended for use. ' +
953 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
954 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
955 + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
956 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
957 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
958 + 'Please update the following components: AllLegacyLifecycles',
959 + ]);
960
961 class WillMount extends React.Component {
962 state = {};
@@ -1023,20 +1003,15 @@ describe('ReactComponentLifeCycle', () => {
1003 'https://react.dev/link/unsafe-component-lifecycles\n' +
1004 ' in WillMountAndUpdate (at **)',
1005 ]);
1026 - assertConsoleWarnDev(
1027 - [
1028 - 'componentWillMount has been renamed, and is not recommended for use. ' +
1029 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1030 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
1031 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
1032 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1033 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1034 - 'Please update the following components: WillMountAndUpdate',
1035 - ],
1036 - {
1037 - withoutStack: true,
1038 - },
1039 - );
1006 + assertConsoleWarnDev([
1007 + 'componentWillMount has been renamed, and is not recommended for use. ' +
1008 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1009 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
1010 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
1011 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1012 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1013 + 'Please update the following components: WillMountAndUpdate',
1014 + ]);
1015
1016 class WillReceiveProps extends React.Component {
1017 state = {};
@@ -1059,23 +1034,18 @@ describe('ReactComponentLifeCycle', () => {
1034 'https://react.dev/link/unsafe-component-lifecycles\n' +
1035 ' in WillReceiveProps (at **)',
1036 ]);
1062 - assertConsoleWarnDev(
1063 - [
1064 - 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
1065 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1066 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
1067 - "* If you're updating state whenever props change, refactor your code to use " +
1068 - 'memoization techniques or move it to static getDerivedStateFromProps. ' +
1069 - 'Learn more at: https://react.dev/link/derived-state\n' +
1070 - '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
1071 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1072 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1073 - 'Please update the following components: WillReceiveProps',
1074 - ],
1075 - {
1076 - withoutStack: true,
1077 - },
1078 - );
1037 + assertConsoleWarnDev([
1038 + 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
1039 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1040 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
1041 + "* If you're updating state whenever props change, refactor your code to use " +
1042 + 'memoization techniques or move it to static getDerivedStateFromProps. ' +
1043 + 'Learn more at: https://react.dev/link/derived-state\n' +
1044 + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
1045 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1046 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1047 + 'Please update the following components: WillReceiveProps',
1048 + ]);
1049 });
1050
1051 it('should warn if getDerivedStateFromProps returns undefined', async () => {
@@ -1162,35 +1132,32 @@ describe('ReactComponentLifeCycle', () => {
1132 await act(() => {
1133 root.render(<MyComponent foo="bar" />);
1134 });
1165 - assertConsoleWarnDev(
1166 - [
1167 - 'componentWillMount has been renamed, and is not recommended for use. ' +
1168 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1169 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
1170 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
1171 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1172 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1173 - 'Please update the following components: MyComponent',
1174 - 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
1175 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1176 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
1177 - "* If you're updating state whenever props change, refactor your code to use " +
1178 - 'memoization techniques or move it to static getDerivedStateFromProps. ' +
1179 - 'Learn more at: https://react.dev/link/derived-state\n' +
1180 - '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
1181 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1182 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1183 - 'Please update the following components: MyComponent',
1184 - 'componentWillUpdate has been renamed, and is not recommended for use. ' +
1185 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1186 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
1187 - '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
1188 - 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1189 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1190 - 'Please update the following components: MyComponent',
1191 - ],
1192 - {withoutStack: true},
1193 - );
1135 + assertConsoleWarnDev([
1136 + 'componentWillMount has been renamed, and is not recommended for use. ' +
1137 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1138 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
1139 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
1140 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1141 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1142 + 'Please update the following components: MyComponent',
1143 + 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
1144 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1145 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
1146 + "* If you're updating state whenever props change, refactor your code to use " +
1147 + 'memoization techniques or move it to static getDerivedStateFromProps. ' +
1148 + 'Learn more at: https://react.dev/link/derived-state\n' +
1149 + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. ' +
1150 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1151 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1152 + 'Please update the following components: MyComponent',
1153 + 'componentWillUpdate has been renamed, and is not recommended for use. ' +
1154 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
1155 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
1156 + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. ' +
1157 + 'In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, ' +
1158 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\n' +
1159 + 'Please update the following components: MyComponent',
1160 + ]);
1161 expect(log).toEqual(['componentWillMount', 'UNSAFE_componentWillMount']);
1162
1163 log.length = 0;
@@ -1488,30 +1455,27 @@ describe('ReactComponentLifeCycle', () => {
1455 await act(() => {
1456 root.render(<MyComponent x={1} />);
1457 });
1491 - assertConsoleWarnDev(
1492 - [
1493 - `componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1458 + assertConsoleWarnDev([
1459 + `componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1460
1461 * Move code with side effects to componentDidMount, and set initial state in the constructor.
1462 * Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.
1463
1464 Please update the following components: MyComponent`,
1499 - `componentWillReceiveProps has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1465 + `componentWillReceiveProps has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1466
1467 * Move data fetching code or side effects to componentDidUpdate.
1468 * If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state
1469 * Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.
1470
1471 Please update the following components: MyComponent`,
1506 - `componentWillUpdate has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1472 + `componentWillUpdate has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
1473
1474 * Move data fetching code or side effects to componentDidUpdate.
1475 * Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.
1476
1477 Please update the following components: MyComponent`,
1512 - ],
1513 - {withoutStack: true},
1514 - );
1478 + ]);
1479
1480 // Dedupe check (update and instantiate new)
1481 await act(() => {
packages/react-dom/src/__tests__/ReactDOM-test.js
+24 -42
@@ -195,13 +195,10 @@ describe('ReactDOM', () => {
195 'Invalid argument passed as callback. Expected a function. Instead ' +
196 'received: no',
197 );
198 - assertConsoleErrorDev(
199 - [
200 - 'Expected the last optional `callback` argument to be a function. Instead received: no.',
201 - 'Expected the last optional `callback` argument to be a function. Instead received: no.',
202 - ],
203 - {withoutStack: 2},
204 - );
198 + assertConsoleErrorDev([
199 + 'Expected the last optional `callback` argument to be a function. Instead received: no.',
200 + 'Expected the last optional `callback` argument to be a function. Instead received: no.',
201 + ]);
202
203 await expect(async () => {
204 await act(() => {
@@ -211,13 +208,10 @@ describe('ReactDOM', () => {
208 'Invalid argument passed as callback. Expected a function. Instead ' +
209 'received: [object Object]',
210 );
214 - assertConsoleErrorDev(
215 - [
216 - "Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }",
217 - "Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
218 - ],
219 - {withoutStack: 2},
220 - );
211 + assertConsoleErrorDev([
212 + "Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }",
213 + "Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
214 + ]);
215
216 await expect(async () => {
217 await act(() => {
@@ -227,13 +221,10 @@ describe('ReactDOM', () => {
221 'Invalid argument passed as callback. Expected a function. Instead ' +
222 'received: [object Object]',
223 );
230 - assertConsoleErrorDev(
231 - [
232 - 'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
233 - 'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
234 - ],
235 - {withoutStack: 2},
236 - );
224 + assertConsoleErrorDev([
225 + 'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
226 + 'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
227 + ]);
228 });
229
230 // @gate !disableLegacyMode
@@ -261,13 +252,10 @@ describe('ReactDOM', () => {
252 'Invalid argument passed as callback. Expected a function. Instead ' +
253 'received: no',
254 );
264 - assertConsoleErrorDev(
265 - [
266 - 'Expected the last optional `callback` argument to be a function. Instead received: no.',
267 - 'Expected the last optional `callback` argument to be a function. Instead received: no.',
268 - ],
269 - {withoutStack: 2},
270 - );
255 + assertConsoleErrorDev([
256 + 'Expected the last optional `callback` argument to be a function. Instead received: no.',
257 + 'Expected the last optional `callback` argument to be a function. Instead received: no.',
258 + ]);
259
260 ReactDOM.render(<A />, myDiv); // Re-mount
261 await expect(async () => {
@@ -278,13 +266,10 @@ describe('ReactDOM', () => {
266 'Invalid argument passed as callback. Expected a function. Instead ' +
267 'received: [object Object]',
268 );
281 - assertConsoleErrorDev(
282 - [
283 - "Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
284 - "Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
285 - ],
286 - {withoutStack: 2},
287 - );
269 + assertConsoleErrorDev([
270 + "Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
271 + "Expected the last optional `callback` argument to be a function. Instead received: { foo: 'bar' }.",
272 + ]);
273
274 ReactDOM.render(<A />, myDiv); // Re-mount
275 await expect(async () => {
@@ -295,13 +280,10 @@ describe('ReactDOM', () => {
280 'Invalid argument passed as callback. Expected a function. Instead ' +
281 'received: [object Object]',
282 );
298 - assertConsoleErrorDev(
299 - [
300 - 'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
301 - 'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
302 - ],
303 - {withoutStack: 2},
304 - );
283 + assertConsoleErrorDev([
284 + 'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
285 + 'Expected the last optional `callback` argument to be a function. Instead received: Foo { a: 1, b: 2 }.',
286 + ]);
287 });
288
289 it('preserves focus', async () => {
packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+9 -24
@@ -3590,14 +3590,11 @@ describe('ReactDOMFizzServer', () => {
3590 onRecoverableError(error, errorInfo) {
3591 expect(error.digest).toBe('a digest');
3592 expect(errorInfo.digest).toBe(undefined);
3593 - assertConsoleErrorDev(
3594 - [
3595 - 'You are accessing "digest" from the errorInfo object passed to onRecoverableError.' +
3596 - ' This property is no longer provided as part of errorInfo but can be accessed as a property' +
3597 - ' of the Error instance itself.',
3598 - ],
3599 - {withoutStack: true},
3600 - );
3593 + assertConsoleErrorDev([
3594 + 'You are accessing "digest" from the errorInfo object passed to onRecoverableError.' +
3595 + ' This property is no longer provided as part of errorInfo but can be accessed as a property' +
3596 + ' of the Error instance itself.',
3597 + ]);
3598 },
3599 },
3600 );
@@ -7770,10 +7767,7 @@ describe('ReactDOMFizzServer', () => {
7767 </html>,
7768 );
7769 assertConsoleErrorDev([
7773 - [
7774 - 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
7775 - {withoutStack: true},
7776 - ],
7770 + 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
7771 'In HTML, <meta> cannot be a child of <html>.\nThis will cause a hydration error.' +
7772 '\n' +
7773 '\n <App>' +
@@ -7788,10 +7782,7 @@ describe('ReactDOMFizzServer', () => {
7782 '<html> cannot contain a nested <meta>.\nSee this log for the ancestor stack trace.' +
7783 '\n in html (at **)' +
7784 '\n in App (at **)',
7791 - [
7792 - 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
7793 - {withoutStack: true},
7794 - ],
7785 + 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
7786 ]);
7787
7788 await root.unmount();
@@ -7886,10 +7877,7 @@ describe('ReactDOMFizzServer', () => {
7877 </html>,
7878 );
7879 assertConsoleErrorDev([
7889 - [
7890 - 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
7891 - {withoutStack: true},
7892 - ],
7880 + 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
7881 'In HTML, <meta> cannot be a child of <html>.\nThis will cause a hydration error.' +
7882 '\n' +
7883 '\n <App>' +
@@ -7904,10 +7892,7 @@ describe('ReactDOMFizzServer', () => {
7892 '<html> cannot contain a nested <meta>.\nSee this log for the ancestor stack trace.' +
7893 '\n in html (at **)' +
7894 '\n in App (at **)',
7907 - [
7908 - 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
7909 - {withoutStack: true},
7910 - ],
7895 + 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
7896 ]);
7897
7898 await root.unmount();
packages/react-dom/src/__tests__/ReactDOMFloat-test.js
+8 -17
@@ -520,10 +520,7 @@ describe('ReactDOMFloat', () => {
520 );
521 await waitForAll([]);
522 assertConsoleErrorDev([
523 - [
524 - 'Cannot render <noscript> outside the main document. Try moving it into the root <head> tag.',
525 - {withoutStack: true},
526 - ],
523 + 'Cannot render <noscript> outside the main document. Try moving it into the root <head> tag.',
524 ]);
525
526 root.render(
@@ -580,11 +577,8 @@ describe('ReactDOMFloat', () => {
577 );
578 await waitForAll([]);
579 assertConsoleErrorDev([
583 - [
584 - 'Cannot render a <link rel="stylesheet" /> outside the main document without knowing its precedence. ' +
585 - 'Consider adding precedence="default" or moving it into the root <head> tag.',
586 - {withoutStack: true},
587 - ],
580 + 'Cannot render a <link rel="stylesheet" /> outside the main document without knowing its precedence. ' +
581 + 'Consider adding precedence="default" or moving it into the root <head> tag.',
582 ]);
583
584 root.render(
@@ -633,14 +627,11 @@ describe('ReactDOMFloat', () => {
627 </>,
628 );
629 await waitForAll([]);
636 - assertConsoleErrorDev(
637 - [
638 - 'Cannot render a <link> with onLoad or onError listeners outside the main document. ' +
639 - 'Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or ' +
640 - 'somewhere in the <body>.',
641 - ],
642 - {withoutStack: true},
643 - );
630 + assertConsoleErrorDev([
631 + 'Cannot render a <link> with onLoad or onError listeners outside the main document. ' +
632 + 'Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or ' +
633 + 'somewhere in the <body>.',
634 + ]);
635 return;
636 });
637
packages/react-dom/src/__tests__/ReactDOMForm-test.js
+8 -16
@@ -1505,13 +1505,10 @@ describe('ReactDOMForm', () => {
1505 // Dispatch outside of a transition.
1506 await act(() => dispatch());
1507 assertConsoleErrorDev([
1508 - [
1509 - 'An async function with useActionState was called outside of a transition. ' +
1510 - 'This is likely not what you intended (for example, isPending will not update ' +
1511 - 'correctly). Either call the returned function inside startTransition, or pass it ' +
1512 - 'to an `action` or `formAction` prop.',
1513 - {withoutStack: true},
1514 - ],
1508 + 'An async function with useActionState was called outside of a transition. ' +
1509 + 'This is likely not what you intended (for example, isPending will not update ' +
1510 + 'correctly). Either call the returned function inside startTransition, or pass it ' +
1511 + 'to an `action` or `formAction` prop.',
1512 ]);
1513 assertLog([
1514 'Suspend! [Count: 1]',
@@ -1967,15 +1964,10 @@ describe('ReactDOMForm', () => {
1964
1965 // This triggers a synchronous requestFormReset, and a warning
1966 await act(() => resolveText('Wait 1'));
1970 - assertConsoleErrorDev(
1971 - [
1972 - 'requestFormReset was called outside a transition or action. ' +
1973 - 'To fix, move to an action, or wrap with startTransition.',
1974 - ],
1975 - {
1976 - withoutStack: true,
1977 - },
1978 - );
1967 + assertConsoleErrorDev([
1968 + 'requestFormReset was called outside a transition or action. ' +
1969 + 'To fix, move to an action, or wrap with startTransition.',
1970 + ]);
1971 assertLog(['Request form reset']);
1972
1973 // The form was reset even though the action didn't finish.
packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js
+8 -14
@@ -1073,24 +1073,18 @@ describe('FragmentRefs', () => {
1073
1074 // Warning when there is no attached observer
1075 fragmentRef.current.unobserveUsing(observer);
1076 - assertConsoleErrorDev(
1077 - [
1078 - 'You are calling unobserveUsing() with an observer that is not being observed with this fragment ' +
1079 - 'instance. First attach the observer with observeUsing()',
1080 - ],
1081 - {withoutStack: true},
1082 - );
1076 + assertConsoleErrorDev([
1077 + 'You are calling unobserveUsing() with an observer that is not being observed with this fragment ' +
1078 + 'instance. First attach the observer with observeUsing()',
1079 + ]);
1080
1081 // Warning when the attached observer does not match
1082 fragmentRef.current.observeUsing(observer);
1083 fragmentRef.current.unobserveUsing(observer2);
1087 - assertConsoleErrorDev(
1088 - [
1089 - 'You are calling unobserveUsing() with an observer that is not being observed with this fragment ' +
1090 - 'instance. First attach the observer with observeUsing()',
1091 - ],
1092 - {withoutStack: true},
1093 - );
1084 + assertConsoleErrorDev([
1085 + 'You are calling unobserveUsing() with an observer that is not being observed with this fragment ' +
1086 + 'instance. First attach the observer with observeUsing()',
1087 + ]);
1088 });
1089
1090 // @gate enableFragmentRefs && enableFragmentRefsInstanceHandles
packages/react-dom/src/__tests__/ReactDOMLegacyComponentTree-test.internal.js
+12 -18
@@ -35,15 +35,12 @@ describe('ReactDOMComponentTree', () => {
35 const component = <div />;
36 const node = ReactDOM.render(<div>{component}</div>, container);
37 ReactDOM.unmountComponentAtNode(node);
38 - assertConsoleErrorDev(
39 - [
40 - "unmountComponentAtNode(): The node you're attempting to unmount " +
41 - 'was rendered by React and is not a top-level container. You may ' +
42 - 'have accidentally passed in a React root node instead of its ' +
43 - 'container.',
44 - ],
45 - {withoutStack: true},
46 - );
38 + assertConsoleErrorDev([
39 + "unmountComponentAtNode(): The node you're attempting to unmount " +
40 + 'was rendered by React and is not a top-level container. You may ' +
41 + 'have accidentally passed in a React root node instead of its ' +
42 + 'container.',
43 + ]);
44 });
45
46 // @gate !disableLegacyMode
@@ -56,14 +53,11 @@ describe('ReactDOMComponentTree', () => {
53 const anotherComponent = <div />;
54 const instance = ReactDOM.render(component, container);
55 ReactDOM.render(anotherComponent, instance);
59 - assertConsoleErrorDev(
60 - [
61 - 'Replacing React-rendered children with a new root ' +
62 - 'component. If you intended to update the children of this node, ' +
63 - 'you should instead have the existing children update their state ' +
64 - 'and render the new components instead of calling ReactDOM.render.',
65 - ],
66 - {withoutStack: true},
67 - );
56 + assertConsoleErrorDev([
57 + 'Replacing React-rendered children with a new root ' +
58 + 'component. If you intended to update the children of this node, ' +
59 + 'you should instead have the existing children update their state ' +
60 + 'and render the new components instead of calling ReactDOM.render.',
61 + ]);
62 });
63 });
packages/react-dom/src/__tests__/ReactDOMLegacyFiber-test.js
+21 -30
@@ -1275,16 +1275,13 @@ describe('ReactDOMLegacyFiber', () => {
1275 ReactDOM.render(<div key="2">baz</div>, container);
1276 });
1277 }).rejects.toThrow('The node to be removed is not a child of this node.');
1278 - assertConsoleErrorDev(
1279 - [
1280 - '' +
1281 - 'It looks like the React-rendered content of this container was ' +
1282 - 'removed without using React. This is not supported and will ' +
1283 - 'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1284 - 'to empty a container.',
1285 - ],
1286 - {withoutStack: true},
1287 - );
1278 + assertConsoleErrorDev([
1279 + '' +
1280 + 'It looks like the React-rendered content of this container was ' +
1281 + 'removed without using React. This is not supported and will ' +
1282 + 'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1283 + 'to empty a container.',
1284 + ]);
1285 });
1286
1287 // @gate !disableLegacyMode
@@ -1296,16 +1293,13 @@ describe('ReactDOMLegacyFiber', () => {
1293 // then we mess with the DOM before an update
1294 container.innerHTML = '<div>MEOW.</div>';
1295 ReactDOM.render(<div>baz</div>, container);
1299 - assertConsoleErrorDev(
1300 - [
1301 - '' +
1302 - 'It looks like the React-rendered content of this container was ' +
1303 - 'removed without using React. This is not supported and will ' +
1304 - 'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1305 - 'to empty a container.',
1306 - ],
1307 - {withoutStack: true},
1308 - );
1296 + assertConsoleErrorDev([
1297 + '' +
1298 + 'It looks like the React-rendered content of this container was ' +
1299 + 'removed without using React. This is not supported and will ' +
1300 + 'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1301 + 'to empty a container.',
1302 + ]);
1303 });
1304
1305 // @gate !disableLegacyMode
@@ -1317,16 +1311,13 @@ describe('ReactDOMLegacyFiber', () => {
1311 // then we mess with the DOM before an update
1312 container.innerHTML = '';
1313 ReactDOM.render(<div>baz</div>, container);
1320 - assertConsoleErrorDev(
1321 - [
1322 - '' +
1323 - 'It looks like the React-rendered content of this container was ' +
1324 - 'removed without using React. This is not supported and will ' +
1325 - 'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1326 - 'to empty a container.',
1327 - ],
1328 - {withoutStack: true},
1329 - );
1314 + assertConsoleErrorDev([
1315 + '' +
1316 + 'It looks like the React-rendered content of this container was ' +
1317 + 'removed without using React. This is not supported and will ' +
1318 + 'cause errors. Instead, call ReactDOM.unmountComponentAtNode ' +
1319 + 'to empty a container.',
1320 + ]);
1321 });
1322
1323 // @gate !disableLegacyMode
packages/react-dom/src/__tests__/ReactDOMRoot-test.js
+43 -76
@@ -52,13 +52,10 @@ describe('ReactDOMRoot', () => {
52 const callback = jest.fn();
53 const root = ReactDOMClient.createRoot(container);
54 root.render(<div>Hi</div>, callback);
55 - assertConsoleErrorDev(
56 - [
57 - 'does not support the second callback argument. ' +
58 - 'To execute a side effect after rendering, declare it in a component body with useEffect().',
59 - ],
60 - {withoutStack: true},
61 - );
55 + assertConsoleErrorDev([
56 + 'does not support the second callback argument. ' +
57 + 'To execute a side effect after rendering, declare it in a component body with useEffect().',
58 + ]);
59 await waitForAll([]);
60 expect(callback).not.toHaveBeenCalled();
61 });
@@ -70,15 +67,10 @@ describe('ReactDOMRoot', () => {
67
68 const root = ReactDOMClient.createRoot(container);
69 root.render(<App />, {});
73 - assertConsoleErrorDev(
74 - [
75 - 'You passed a second argument to root.render(...) but it only accepts ' +
76 - 'one argument.',
77 - ],
78 - {
79 - withoutStack: true,
80 - },
81 - );
70 + assertConsoleErrorDev([
71 + 'You passed a second argument to root.render(...) but it only accepts ' +
72 + 'one argument.',
73 + ]);
74 });
75
76 it('warn if a container is passed to root.render(...)', async () => {
@@ -88,16 +80,11 @@ describe('ReactDOMRoot', () => {
80
81 const root = ReactDOMClient.createRoot(container);
82 root.render(<App />, container);
91 - assertConsoleErrorDev(
92 - [
93 - 'You passed a container to the second argument of root.render(...). ' +
94 - "You don't need to pass it again since you already passed it to create " +
95 - 'the root.',
96 - ],
97 - {
98 - withoutStack: true,
99 - },
100 - );
83 + assertConsoleErrorDev([
84 + 'You passed a container to the second argument of root.render(...). ' +
85 + "You don't need to pass it again since you already passed it to create " +
86 + 'the root.',
87 + ]);
88 });
89
90 it('warns if a callback parameter is provided to unmount', async () => {
@@ -105,13 +92,10 @@ describe('ReactDOMRoot', () => {
92 const root = ReactDOMClient.createRoot(container);
93 root.render(<div>Hi</div>);
94 root.unmount(callback);
108 - assertConsoleErrorDev(
109 - [
110 - 'does not support a callback argument. ' +
111 - 'To execute a side effect after rendering, declare it in a component body with useEffect().',
112 - ],
113 - {withoutStack: true},
114 - );
95 + assertConsoleErrorDev([
96 + 'does not support a callback argument. ' +
97 + 'To execute a side effect after rendering, declare it in a component body with useEffect().',
98 + ]);
99 await waitForAll([]);
100 expect(callback).not.toHaveBeenCalled();
101 });
@@ -216,14 +200,11 @@ describe('ReactDOMRoot', () => {
200 it('warns when creating two roots managing the same container', () => {
201 ReactDOMClient.createRoot(container);
202 ReactDOMClient.createRoot(container);
219 - assertConsoleErrorDev(
220 - [
221 - 'You are calling ReactDOMClient.createRoot() on a container that ' +
222 - 'has already been passed to createRoot() before. Instead, call ' +
223 - 'root.render() on the existing root instead if you want to update it.',
224 - ],
225 - {withoutStack: true},
226 - );
203 + assertConsoleErrorDev([
204 + 'You are calling ReactDOMClient.createRoot() on a container that ' +
205 + 'has already been passed to createRoot() before. Instead, call ' +
206 + 'root.render() on the existing root instead if you want to update it.',
207 + ]);
208 });
209
210 it('does not warn when creating second root after first one is unmounted', async () => {
@@ -413,13 +394,10 @@ describe('ReactDOMRoot', () => {
394
395 it('warn if no children passed to hydrateRoot', async () => {
396 ReactDOMClient.hydrateRoot(container);
416 - assertConsoleErrorDev(
417 - [
418 - 'Must provide initial children as second argument to hydrateRoot. ' +
419 - 'Example usage: hydrateRoot(domContainer, <App />)',
420 - ],
421 - {withoutStack: true},
422 - );
397 + assertConsoleErrorDev([
398 + 'Must provide initial children as second argument to hydrateRoot. ' +
399 + 'Example usage: hydrateRoot(domContainer, <App />)',
400 + ]);
401 });
402
403 it('warn if JSX passed to createRoot', async () => {
@@ -428,18 +406,13 @@ describe('ReactDOMRoot', () => {
406 }
407
408 ReactDOMClient.createRoot(container, <App />);
431 - assertConsoleErrorDev(
432 - [
433 - 'You passed a JSX element to createRoot. You probably meant to call root.render instead. ' +
434 - 'Example usage:\n' +
435 - '\n' +
436 - ' let root = createRoot(domContainer);\n' +
437 - ' root.render(<App />);',
438 - ],
439 - {
440 - withoutStack: true,
441 - },
442 - );
409 + assertConsoleErrorDev([
410 + 'You passed a JSX element to createRoot. You probably meant to call root.render instead. ' +
411 + 'Example usage:\n' +
412 + '\n' +
413 + ' let root = createRoot(domContainer);\n' +
414 + ' root.render(<App />);',
415 + ]);
416 });
417
418 it('warns when given a function', () => {
@@ -452,15 +425,12 @@ describe('ReactDOMRoot', () => {
425 ReactDOM.flushSync(() => {
426 root.render(Component);
427 });
455 - assertConsoleErrorDev(
456 - [
457 - 'Functions are not valid as a React child. ' +
458 - 'This may happen if you return Component instead of <Component /> from render. ' +
459 - 'Or maybe you meant to call this function rather than return it.\n' +
460 - ' root.render(Component)',
461 - ],
462 - {withoutStack: true},
463 - );
428 + assertConsoleErrorDev([
429 + 'Functions are not valid as a React child. ' +
430 + 'This may happen if you return Component instead of <Component /> from render. ' +
431 + 'Or maybe you meant to call this function rather than return it.\n' +
432 + ' root.render(Component)',
433 + ]);
434 });
435
436 it('warns when given a symbol', () => {
@@ -469,12 +439,9 @@ describe('ReactDOMRoot', () => {
439 ReactDOM.flushSync(() => {
440 root.render(Symbol('foo'));
441 });
472 - assertConsoleErrorDev(
473 - [
474 - 'Symbols are not valid as a React child.\n' +
475 - ' root.render(Symbol(foo))',
476 - ],
477 - {withoutStack: true},
478 - );
442 + assertConsoleErrorDev([
443 + 'Symbols are not valid as a React child.\n' +
444 + ' root.render(Symbol(foo))',
445 + ]);
446 });
447 });
packages/react-dom/src/__tests__/ReactIdentity-test.js
+4 -7
@@ -323,12 +323,9 @@ describe('ReactIdentity', () => {
323 </div>,
324 );
325 }).toThrowError(new TypeError('prod message'));
326 - assertConsoleErrorDev(
327 - [
328 - 'The provided key is an unsupported type TemporalLike.' +
329 - ' This value must be coerced to a string before using it here.',
330 - ],
331 - {withoutStack: true},
332 - );
326 + assertConsoleErrorDev([
327 + 'The provided key is an unsupported type TemporalLike.' +
328 + ' This value must be coerced to a string before using it here.',
329 + ]);
330 });
331 });
packages/react-dom/src/__tests__/ReactLegacyMount-test.js
+49 -70
@@ -67,15 +67,12 @@ describe('ReactMount', () => {
67
68 const container = document.createElement('div');
69 ReactDOM.render(Component, container);
70 - assertConsoleErrorDev(
71 - [
72 - 'Functions are not valid as a React child. ' +
73 - 'This may happen if you return Component instead of <Component /> from render. ' +
74 - 'Or maybe you meant to call this function rather than return it.\n' +
75 - ' root.render(Component)',
76 - ],
77 - {withoutStack: true},
78 - );
70 + assertConsoleErrorDev([
71 + 'Functions are not valid as a React child. ' +
72 + 'This may happen if you return Component instead of <Component /> from render. ' +
73 + 'Or maybe you meant to call this function rather than return it.\n' +
74 + ' root.render(Component)',
75 + ]);
76 });
77
78 // @gate !disableLegacyMode
@@ -172,15 +169,12 @@ describe('ReactMount', () => {
169 const rootNode = container.firstChild;
170
171 ReactDOM.render(<span />, rootNode);
175 - assertConsoleErrorDev(
176 - [
177 - 'Replacing React-rendered children with a new ' +
178 - 'root component. If you intended to update the children of this node, ' +
179 - 'you should instead have the existing children update their state and ' +
180 - 'render the new components instead of calling ReactDOM.render.',
181 - ],
182 - {withoutStack: true},
183 - );
172 + assertConsoleErrorDev([
173 + 'Replacing React-rendered children with a new ' +
174 + 'root component. If you intended to update the children of this node, ' +
175 + 'you should instead have the existing children update their state and ' +
176 + 'render the new components instead of calling ReactDOM.render.',
177 + ]);
178 });
179
180 // @gate !disableLegacyMode
@@ -204,13 +198,10 @@ describe('ReactMount', () => {
198 expect(ReactDOM).not.toEqual(ReactDOMOther);
199
200 ReactDOMOther.unmountComponentAtNode(container);
207 - assertConsoleErrorDev(
208 - [
209 - "unmountComponentAtNode(): The node you're attempting to unmount " +
210 - 'was rendered by another copy of React.',
211 - ],
212 - {withoutStack: true},
213 - );
201 + assertConsoleErrorDev([
202 + "unmountComponentAtNode(): The node you're attempting to unmount " +
203 + 'was rendered by another copy of React.',
204 + ]);
205
206 // Don't throw a warning if the correct React copy unmounts the node
207 ReactDOM.unmountComponentAtNode(container);
@@ -361,20 +352,17 @@ describe('ReactMount', () => {
352 await waitForAll([]);
353 expect(container.textContent).toEqual('Hi');
354 ReactDOM.render(<div>Bye</div>, container);
364 - assertConsoleErrorDev(
365 - [
366 - // We care about this warning:
367 - 'You are calling ReactDOM.render() on a container that was previously ' +
368 - 'passed to ReactDOMClient.createRoot(). This is not supported. ' +
369 - 'Did you mean to call root.render(element)?',
370 - // This is more of a symptom but restructuring the code to avoid it isn't worth it:
371 - 'Replacing React-rendered children with a new root component. ' +
372 - 'If you intended to update the children of this node, ' +
373 - 'you should instead have the existing children update their state ' +
374 - 'and render the new components instead of calling ReactDOM.render.',
375 - ],
376 - {withoutStack: true},
377 - );
355 + assertConsoleErrorDev([
356 + // We care about this warning:
357 + 'You are calling ReactDOM.render() on a container that was previously ' +
358 + 'passed to ReactDOMClient.createRoot(). This is not supported. ' +
359 + 'Did you mean to call root.render(element)?',
360 + // This is more of a symptom but restructuring the code to avoid it isn't worth it:
361 + 'Replacing React-rendered children with a new root component. ' +
362 + 'If you intended to update the children of this node, ' +
363 + 'you should instead have the existing children update their state ' +
364 + 'and render the new components instead of calling ReactDOM.render.',
365 + ]);
366 await waitForAll([]);
367 // This works now but we could disallow it:
368 expect(container.textContent).toEqual('Bye');
@@ -388,18 +376,15 @@ describe('ReactMount', () => {
376 await waitForAll([]);
377 expect(container.textContent).toEqual('Hi');
378 const unmounted = ReactDOM.unmountComponentAtNode(container);
391 - assertConsoleErrorDev(
392 - [
393 - // We care about this warning:
394 - 'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' +
395 - 'passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?',
396 - // This is more of a symptom but restructuring the code to avoid it isn't worth it:
397 - 'unmountComponentAtNode(): ' +
398 - "The node you're attempting to unmount was rendered by React and is not a top-level container. " +
399 - 'Instead, have the parent component update its state and rerender in order to remove this component.',
400 - ],
401 - {withoutStack: true},
402 - );
379 + assertConsoleErrorDev([
380 + // We care about this warning:
381 + 'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' +
382 + 'passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?',
383 + // This is more of a symptom but restructuring the code to avoid it isn't worth it:
384 + 'unmountComponentAtNode(): ' +
385 + "The node you're attempting to unmount was rendered by React and is not a top-level container. " +
386 + 'Instead, have the parent component update its state and rerender in order to remove this component.',
387 + ]);
388 expect(unmounted).toBe(false);
389 await waitForAll([]);
390 expect(container.textContent).toEqual('Hi');
@@ -419,18 +404,15 @@ describe('ReactMount', () => {
404 await waitForAll([]);
405 expect(container.textContent).toEqual('Hi');
406 const unmounted = ReactDOM.unmountComponentAtNode(container);
422 - assertConsoleErrorDev(
423 - [
424 - 'You are calling ReactDOM.unmountComponentAtNode() on a container ' +
425 - 'that was previously passed to ReactDOMClient.createRoot(). ' +
426 - 'This is not supported. Did you mean to call root.unmount()?',
427 - // This is more of a symptom but restructuring the code to avoid it isn't worth it:
428 - 'unmountComponentAtNode(): ' +
429 - "The node you're attempting to unmount was rendered by React and is not a top-level container. " +
430 - 'Instead, have the parent component update its state and rerender in order to remove this component.',
431 - ],
432 - {withoutStack: true},
433 - );
407 + assertConsoleErrorDev([
408 + 'You are calling ReactDOM.unmountComponentAtNode() on a container ' +
409 + 'that was previously passed to ReactDOMClient.createRoot(). ' +
410 + 'This is not supported. Did you mean to call root.unmount()?',
411 + // This is more of a symptom but restructuring the code to avoid it isn't worth it:
412 + 'unmountComponentAtNode(): ' +
413 + "The node you're attempting to unmount was rendered by React and is not a top-level container. " +
414 + 'Instead, have the parent component update its state and rerender in order to remove this component.',
415 + ]);
416 expect(unmounted).toBe(false);
417 await waitForAll([]);
418 expect(container.textContent).toEqual('Hi');
@@ -444,12 +426,9 @@ describe('ReactMount', () => {
426 const container = document.createElement('div');
427 ReactDOM.render(<div>Hi</div>, container);
428 ReactDOMClient.createRoot(container);
447 - assertConsoleErrorDev(
448 - [
449 - 'You are calling ReactDOMClient.createRoot() on a container that was previously ' +
450 - 'passed to ReactDOM.render(). This is not supported.',
451 - ],
452 - {withoutStack: true},
453 - );
429 + assertConsoleErrorDev([
430 + 'You are calling ReactDOMClient.createRoot() on a container that was previously ' +
431 + 'passed to ReactDOM.render(). This is not supported.',
432 + ]);
433 });
434 });
packages/react-dom/src/__tests__/ReactLegacyUpdates-test.js
+16 -28
@@ -916,13 +916,10 @@ describe('ReactLegacyUpdates', () => {
916 'Invalid argument passed as callback. Expected a function. ' +
917 'Instead received: no',
918 );
919 - assertConsoleErrorDev(
920 - [
921 - 'Expected the last optional `callback` argument to be ' +
922 - 'a function. Instead received: no.',
923 - ],
924 - {withoutStack: true},
925 - );
919 + assertConsoleErrorDev([
920 + 'Expected the last optional `callback` argument to be ' +
921 + 'a function. Instead received: no.',
922 + ]);
923
924 container = document.createElement('div');
925 component = ReactDOM.render(<A />, container);
@@ -934,13 +931,10 @@ describe('ReactLegacyUpdates', () => {
931 'Invalid argument passed as callback. Expected a function. Instead ' +
932 'received: [object Object]',
933 );
937 - assertConsoleErrorDev(
938 - [
939 - 'Expected the last optional `callback` argument to be a function. ' +
940 - "Instead received: { foo: 'bar' }.",
941 - ],
942 - {withoutStack: true},
943 - );
934 + assertConsoleErrorDev([
935 + 'Expected the last optional `callback` argument to be a function. ' +
936 + "Instead received: { foo: 'bar' }.",
937 + ]);
938 // Make sure the warning is deduplicated and doesn't fire again
939 container = document.createElement('div');
940 component = ReactDOM.render(<A />, container);
@@ -980,13 +974,10 @@ describe('ReactLegacyUpdates', () => {
974 'Invalid argument passed as callback. Expected a function. Instead ' +
975 'received: no',
976 );
983 - assertConsoleErrorDev(
984 - [
985 - 'Expected the last optional `callback` argument to be a function. ' +
986 - 'Instead received: no.',
987 - ],
988 - {withoutStack: true},
989 - );
977 + assertConsoleErrorDev([
978 + 'Expected the last optional `callback` argument to be a function. ' +
979 + 'Instead received: no.',
980 + ]);
981 container = document.createElement('div');
982 component = ReactDOM.render(<A />, container);
983 await expect(async () => {
@@ -997,13 +988,10 @@ describe('ReactLegacyUpdates', () => {
988 'Invalid argument passed as callback. Expected a function. Instead ' +
989 'received: [object Object]',
990 );
1000 - assertConsoleErrorDev(
1001 - [
1002 - 'Expected the last optional `callback` argument to be a function. ' +
1003 - "Instead received: { foo: 'bar' }.",
1004 - ],
1005 - {withoutStack: true},
1006 - );
991 + assertConsoleErrorDev([
992 + 'Expected the last optional `callback` argument to be a function. ' +
993 + "Instead received: { foo: 'bar' }.",
994 + ]);
995 // Make sure the warning is deduplicated and doesn't fire again
996 container = document.createElement('div');
997 component = ReactDOM.render(<A />, container);
packages/react-dom/src/__tests__/ReactMountDestruction-test.js
+12 -18
@@ -66,15 +66,12 @@ describe('ReactMount', () => {
66 // Test that unmounting at a root node gives a helpful warning
67 const rootDiv = mainContainerDiv.firstChild;
68 ReactDOM.unmountComponentAtNode(rootDiv);
69 - assertConsoleErrorDev(
70 - [
71 - "unmountComponentAtNode(): The node you're attempting to " +
72 - 'unmount was rendered by React and is not a top-level container. You ' +
73 - 'may have accidentally passed in a React root node instead of its ' +
74 - 'container.',
75 - ],
76 - {withoutStack: true},
77 - );
69 + assertConsoleErrorDev([
70 + "unmountComponentAtNode(): The node you're attempting to " +
71 + 'unmount was rendered by React and is not a top-level container. You ' +
72 + 'may have accidentally passed in a React root node instead of its ' +
73 + 'container.',
74 + ]);
75 });
76
77 // @gate !disableLegacyMode
@@ -94,14 +91,11 @@ describe('ReactMount', () => {
91 // Test that unmounting at a non-root node gives a different warning
92 const nonRootDiv = mainContainerDiv.firstChild.firstChild;
93 ReactDOM.unmountComponentAtNode(nonRootDiv);
97 - assertConsoleErrorDev(
98 - [
99 - "unmountComponentAtNode(): The node you're attempting to " +
100 - 'unmount was rendered by React and is not a top-level container. ' +
101 - 'Instead, have the parent component update its state and rerender in ' +
102 - 'order to remove this component.',
103 - ],
104 - {withoutStack: true},
105 - );
94 + assertConsoleErrorDev([
95 + "unmountComponentAtNode(): The node you're attempting to " +
96 + 'unmount was rendered by React and is not a top-level container. ' +
97 + 'Instead, have the parent component update its state and rerender in ' +
98 + 'order to remove this component.',
99 + ]);
100 });
101 });
packages/react-dom/src/__tests__/ReactServerRendering-test.js
+14 -20
@@ -606,16 +606,13 @@ describe('ReactDOMServer', () => {
606
607 ReactDOMServer.renderToString(<Foo />);
608 jest.runOnlyPendingTimers();
609 - assertConsoleErrorDev(
610 - [
611 - 'Can only update a mounting component. ' +
612 - 'This usually means you called setState() outside componentWillMount() on the server. ' +
613 - 'This is a no-op.\n' +
614 - '\n' +
615 - 'Please check the code for the Foo component.',
616 - ],
617 - {withoutStack: true},
618 - );
609 + assertConsoleErrorDev([
610 + 'Can only update a mounting component. ' +
611 + 'This usually means you called setState() outside componentWillMount() on the server. ' +
612 + 'This is a no-op.\n' +
613 + '\n' +
614 + 'Please check the code for the Foo component.',
615 + ]);
616
617 const markup = ReactDOMServer.renderToStaticMarkup(<Foo />);
618 expect(markup).toBe('<div>hello</div>');
@@ -639,16 +636,13 @@ describe('ReactDOMServer', () => {
636
637 ReactDOMServer.renderToString(<Baz />);
638 jest.runOnlyPendingTimers();
642 - assertConsoleErrorDev(
643 - [
644 - 'Can only update a mounting component. ' +
645 - 'This usually means you called forceUpdate() outside componentWillMount() on the server. ' +
646 - 'This is a no-op.\n' +
647 - '\n' +
648 - 'Please check the code for the Baz component.',
649 - ],
650 - {withoutStack: true},
651 - );
639 + assertConsoleErrorDev([
640 + 'Can only update a mounting component. ' +
641 + 'This usually means you called forceUpdate() outside componentWillMount() on the server. ' +
642 + 'This is a no-op.\n' +
643 + '\n' +
644 + 'Please check the code for the Baz component.',
645 + ]);
646 const markup = ReactDOMServer.renderToStaticMarkup(<Baz />);
647 expect(markup).toBe('<div></div>');
648 });
packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
+12 -17
@@ -377,23 +377,18 @@ describe('ReactDOMServerHydration', () => {
377 await act(() => {
378 ReactDOMClient.hydrateRoot(element, markup);
379 });
380 - assertConsoleWarnDev(
381 - [
382 - 'componentWillMount has been renamed, and is not recommended for use. ' +
383 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n' +
384 - '\n' +
385 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
386 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
387 - 'In React 18.x, only the UNSAFE_ name will work. ' +
388 - 'To rename all deprecated lifecycles to their new names, ' +
389 - 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
390 - '\n' +
391 - 'Please update the following components: ComponentWithWarning',
392 - ],
393 - {
394 - withoutStack: true,
395 - },
396 - );
380 + assertConsoleWarnDev([
381 + 'componentWillMount has been renamed, and is not recommended for use. ' +
382 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n' +
383 + '\n' +
384 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
385 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. ' +
386 + 'In React 18.x, only the UNSAFE_ name will work. ' +
387 + 'To rename all deprecated lifecycles to their new names, ' +
388 + 'you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
389 + '\n' +
390 + 'Please update the following components: ComponentWithWarning',
391 + ]);
392 expect(element.textContent).toBe('Hi');
393 });
394
packages/react-dom/src/__tests__/ReactUpdates-test.js
+16 -28
@@ -1063,13 +1063,10 @@ describe('ReactUpdates', () => {
1063 'Invalid argument passed as callback. Expected a function. Instead ' +
1064 'received: no',
1065 );
1066 - assertConsoleErrorDev(
1067 - [
1068 - 'Expected the last optional `callback` argument to be ' +
1069 - 'a function. Instead received: no.',
1070 - ],
1071 - {withoutStack: true},
1072 - );
1066 + assertConsoleErrorDev([
1067 + 'Expected the last optional `callback` argument to be ' +
1068 + 'a function. Instead received: no.',
1069 + ]);
1070 container = document.createElement('div');
1071 root = ReactDOMClient.createRoot(container);
1072 await act(() => {
@@ -1084,13 +1081,10 @@ describe('ReactUpdates', () => {
1081 'Invalid argument passed as callback. Expected a function. Instead ' +
1082 'received: [object Object]',
1083 );
1087 - assertConsoleErrorDev(
1088 - [
1089 - 'Expected the last optional `callback` argument to be ' +
1090 - "a function. Instead received: { foo: 'bar' }.",
1091 - ],
1092 - {withoutStack: true},
1093 - );
1084 + assertConsoleErrorDev([
1085 + 'Expected the last optional `callback` argument to be ' +
1086 + "a function. Instead received: { foo: 'bar' }.",
1087 + ]);
1088 container = document.createElement('div');
1089 root = ReactDOMClient.createRoot(container);
1090 await act(() => {
@@ -1136,13 +1130,10 @@ describe('ReactUpdates', () => {
1130 'Invalid argument passed as callback. Expected a function. Instead ' +
1131 'received: no',
1132 );
1139 - assertConsoleErrorDev(
1140 - [
1141 - 'Expected the last optional `callback` argument to be ' +
1142 - 'a function. Instead received: no.',
1143 - ],
1144 - {withoutStack: true},
1145 - );
1133 + assertConsoleErrorDev([
1134 + 'Expected the last optional `callback` argument to be ' +
1135 + 'a function. Instead received: no.',
1136 + ]);
1137 container = document.createElement('div');
1138 root = ReactDOMClient.createRoot(container);
1139 await act(() => {
@@ -1157,13 +1148,10 @@ describe('ReactUpdates', () => {
1148 'Invalid argument passed as callback. Expected a function. Instead ' +
1149 'received: [object Object]',
1150 );
1160 - assertConsoleErrorDev(
1161 - [
1162 - 'Expected the last optional `callback` argument to be ' +
1163 - "a function. Instead received: { foo: 'bar' }.",
1164 - ],
1165 - {withoutStack: true},
1166 - );
1151 + assertConsoleErrorDev([
1152 + 'Expected the last optional `callback` argument to be ' +
1153 + "a function. Instead received: { foo: 'bar' }.",
1154 + ]);
1155 // Make sure the warning is deduplicated and doesn't fire again
1156 container = document.createElement('div');
1157 root = ReactDOMClient.createRoot(container);
packages/react-dom/src/__tests__/validateDOMNesting-test.js
+2 -5
@@ -15,7 +15,7 @@ const ReactDOMClient = require('react-dom/client');
15 const assertConsoleErrorDev =
16 require('internal-test-utils').assertConsoleErrorDev;
17
18 -function expectWarnings(tags, warnings = [], withoutStack = 0) {
18 +function expectWarnings(tags, warnings = []) {
19 tags = [...tags];
20 warnings = [...warnings];
21
@@ -61,10 +61,7 @@ function expectWarnings(tags, warnings = [], withoutStack = 0) {
61 root.render(element);
62 });
63 if (warnings.length) {
64 - assertConsoleErrorDev(
65 - warnings,
66 - withoutStack > 0 ? {withoutStack} : undefined,
67 - );
64 + assertConsoleErrorDev(warnings);
65 }
66 root.unmount();
67 }
packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js
+2 -6
@@ -477,9 +477,7 @@ describe('ReactFabric', () => {
477
478 expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
479 ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]);
480 - assertConsoleErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], {
481 - withoutStack: true,
482 - });
480 + assertConsoleErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT]);
481
482 expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
483 });
@@ -542,9 +540,7 @@ describe('ReactFabric', () => {
540
541 expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
542 ReactFabric.sendAccessibilityEvent(viewRef, 'eventTypeName');
545 - assertConsoleErrorDev([SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT], {
546 - withoutStack: true,
547 - });
543 + assertConsoleErrorDev([SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT]);
544
545 expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
546 });
packages/react-reconciler/src/__tests__/ReactActWarnings-test.js
+61 -75
@@ -219,10 +219,9 @@ describe('act warnings', () => {
219 act(() => {
220 setState(1);
221 });
222 - assertConsoleErrorDev(
223 - ['The current testing environment is not configured to support act(...)'],
224 - {withoutStack: true},
225 - );
222 + assertConsoleErrorDev([
223 + 'The current testing environment is not configured to support act(...)',
224 + ]);
225 assertLog([1]);
226 expect(root).toMatchRenderedOutput('1');
227
@@ -240,12 +239,9 @@ describe('act warnings', () => {
239 act(() => {
240 setState(1);
241 });
243 - assertConsoleErrorDev(
244 - [
245 - 'The current testing environment is not configured to support act(...)',
246 - ],
247 - {withoutStack: true},
248 - );
242 + assertConsoleErrorDev([
243 + 'The current testing environment is not configured to support act(...)',
244 + ]);
245 assertLog([1]);
246 expect(root).toMatchRenderedOutput('1');
247 });
@@ -255,24 +251,21 @@ describe('act warnings', () => {
251 await withActEnvironment(true, () => {
252 const root = ReactNoop.createRoot();
253 root.render('Hi');
258 - assertConsoleErrorDev(
259 - [
260 - // TODO: Better error message that doesn't make it look like "Root" is
261 - // the name of a custom component
262 - 'An update to Root inside a test was not wrapped in act(...).\n' +
263 - '\n' +
264 - 'When testing, code that causes React state updates should be wrapped into act(...):\n' +
265 - '\n' +
266 - 'act(() => {\n' +
267 - ' /* fire events that update state */\n' +
268 - '});\n' +
269 - '/* assert on the output */\n' +
270 - '\n' +
271 - "This ensures that you're testing the behavior the user would see in the browser. " +
272 - 'Learn more at https://react.dev/link/wrap-tests-with-act',
273 - ],
274 - {withoutStack: true},
275 - );
254 + assertConsoleErrorDev([
255 + // TODO: Better error message that doesn't make it look like "Root" is
256 + // the name of a custom component
257 + 'An update to Root inside a test was not wrapped in act(...).\n' +
258 + '\n' +
259 + 'When testing, code that causes React state updates should be wrapped into act(...):\n' +
260 + '\n' +
261 + 'act(() => {\n' +
262 + ' /* fire events that update state */\n' +
263 + '});\n' +
264 + '/* assert on the output */\n' +
265 + '\n' +
266 + "This ensures that you're testing the behavior the user would see in the browser. " +
267 + 'Learn more at https://react.dev/link/wrap-tests-with-act',
268 + ]);
269 });
270 });
271
@@ -374,37 +367,33 @@ describe('act warnings', () => {
367
368 // This is a retry, not a ping, because we already showed a fallback.
369 resolveText('Async');
377 - assertConsoleErrorDev(
378 - [
379 - 'A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n' +
380 - '\n' +
381 - 'When testing, code that resolves suspended data should be wrapped into act(...):\n' +
382 - '\n' +
383 - 'act(() => {\n' +
384 - ' /* finish loading suspended data */\n' +
385 - '});\n' +
386 - '/* assert on the output */\n' +
387 - '\n' +
388 - "This ensures that you're testing the behavior the user would see in the browser. " +
389 - 'Learn more at https://react.dev/link/wrap-tests-with-act',
390 -
391 - // pre-warming
392 -
393 - 'A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n' +
394 - '\n' +
395 - 'When testing, code that resolves suspended data should be wrapped into act(...):\n' +
396 - '\n' +
397 - 'act(() => {\n' +
398 - ' /* finish loading suspended data */\n' +
399 - '});\n' +
400 - '/* assert on the output */\n' +
401 - '\n' +
402 - "This ensures that you're testing the behavior the user would see in the browser. " +
403 - 'Learn more at https://react.dev/link/wrap-tests-with-act',
404 - ],
405 -
406 - {withoutStack: true},
407 - );
370 + assertConsoleErrorDev([
371 + 'A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n' +
372 + '\n' +
373 + 'When testing, code that resolves suspended data should be wrapped into act(...):\n' +
374 + '\n' +
375 + 'act(() => {\n' +
376 + ' /* finish loading suspended data */\n' +
377 + '});\n' +
378 + '/* assert on the output */\n' +
379 + '\n' +
380 + "This ensures that you're testing the behavior the user would see in the browser. " +
381 + 'Learn more at https://react.dev/link/wrap-tests-with-act',
382 +
383 + // pre-warming
384 +
385 + 'A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n' +
386 + '\n' +
387 + 'When testing, code that resolves suspended data should be wrapped into act(...):\n' +
388 + '\n' +
389 + 'act(() => {\n' +
390 + ' /* finish loading suspended data */\n' +
391 + '});\n' +
392 + '/* assert on the output */\n' +
393 + '\n' +
394 + "This ensures that you're testing the behavior the user would see in the browser. " +
395 + 'Learn more at https://react.dev/link/wrap-tests-with-act',
396 + ]);
397 });
398 });
399
@@ -437,22 +426,19 @@ describe('act warnings', () => {
426
427 // This is a ping, not a retry, because no fallback is showing.
428 resolveText('Async');
440 - assertConsoleErrorDev(
441 - [
442 - 'A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n' +
443 - '\n' +
444 - 'When testing, code that resolves suspended data should be wrapped into act(...):\n' +
445 - '\n' +
446 - 'act(() => {\n' +
447 - ' /* finish loading suspended data */\n' +
448 - '});\n' +
449 - '/* assert on the output */\n' +
450 - '\n' +
451 - "This ensures that you're testing the behavior the user would see in the browser. " +
452 - 'Learn more at https://react.dev/link/wrap-tests-with-act',
453 - ],
454 - {withoutStack: true},
455 - );
429 + assertConsoleErrorDev([
430 + 'A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n' +
431 + '\n' +
432 + 'When testing, code that resolves suspended data should be wrapped into act(...):\n' +
433 + '\n' +
434 + 'act(() => {\n' +
435 + ' /* finish loading suspended data */\n' +
436 + '});\n' +
437 + '/* assert on the output */\n' +
438 + '\n' +
439 + "This ensures that you're testing the behavior the user would see in the browser. " +
440 + 'Learn more at https://react.dev/link/wrap-tests-with-act',
441 + ]);
442 });
443 });
444 });
packages/react-reconciler/src/__tests__/ReactAsyncActions-test.js
+5 -8
@@ -1237,14 +1237,11 @@ describe('ReactAsyncActions', () => {
1237 setLoadingProgress('25%');
1238 startTransition(() => setText('B'));
1239 });
1240 - assertConsoleErrorDev(
1241 - [
1242 - 'An optimistic state update occurred outside a transition or ' +
1243 - 'action. To fix, move the update to an action, or wrap ' +
1244 - 'with startTransition.',
1245 - ],
1246 - {withoutStack: true},
1247 - );
1240 + assertConsoleErrorDev([
1241 + 'An optimistic state update occurred outside a transition or ' +
1242 + 'action. To fix, move the update to an action, or wrap ' +
1243 + 'with startTransition.',
1244 + ]);
1245 assertLog(['Loading... (25%)', 'A', 'B']);
1246 expect(root).toMatchRenderedOutput(<div>B</div>);
1247 });
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+12 -18
@@ -244,15 +244,12 @@ describe('ReactHooks', () => {
244 throw new Error('Expected to ignore the callback.');
245 }),
246 );
247 - assertConsoleErrorDev(
248 - [
249 - 'State updates from the useState() and useReducer() Hooks ' +
250 - "don't support the second callback argument. " +
251 - 'To execute a side effect after rendering, ' +
252 - 'declare it in the component body with useEffect().',
253 - ],
254 - {withoutStack: true},
255 - );
247 + assertConsoleErrorDev([
248 + 'State updates from the useState() and useReducer() Hooks ' +
249 + "don't support the second callback argument. " +
250 + 'To execute a side effect after rendering, ' +
251 + 'declare it in the component body with useEffect().',
252 + ]);
253 assertLog(['Count: 1']);
254 expect(root).toMatchRenderedOutput('1');
255 });
@@ -279,15 +276,12 @@ describe('ReactHooks', () => {
276 throw new Error('Expected to ignore the callback.');
277 }),
278 );
282 - assertConsoleErrorDev(
283 - [
284 - 'State updates from the useState() and useReducer() Hooks ' +
285 - "don't support the second callback argument. " +
286 - 'To execute a side effect after rendering, ' +
287 - 'declare it in the component body with useEffect().',
288 - ],
289 - {withoutStack: true},
290 - );
279 + assertConsoleErrorDev([
280 + 'State updates from the useState() and useReducer() Hooks ' +
281 + "don't support the second callback argument. " +
282 + 'To execute a side effect after rendering, ' +
283 + 'declare it in the component body with useEffect().',
284 + ]);
285 assertLog(['Count: 1']);
286 expect(root).toMatchRenderedOutput('1');
287 });
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+8 -11
@@ -236,17 +236,14 @@ describe('ReactHooksWithNoopRenderer', () => {
236 expect(() => useState(0)).toThrow(
237 "Cannot read property 'useState' of null",
238 );
239 - assertConsoleErrorDev(
240 - [
241 - 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
242 - ' one of the following reasons:\n' +
243 - '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
244 - '2. You might be breaking the Rules of Hooks\n' +
245 - '3. You might have more than one copy of React in the same app\n' +
246 - 'See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.',
247 - ],
248 - {withoutStack: true},
249 - );
239 + assertConsoleErrorDev([
240 + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
241 + ' one of the following reasons:\n' +
242 + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
243 + '2. You might be breaking the Rules of Hooks\n' +
244 + '3. You might have more than one copy of React in the same app\n' +
245 + 'See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.',
246 + ]);
247 });
248
249 describe('useState', () => {
packages/react-reconciler/src/__tests__/ReactMemo-test.js
+8 -14
@@ -375,24 +375,18 @@ describe('memo', () => {
375
376 it('warns if the first argument is undefined', () => {
377 memo();
378 - assertConsoleErrorDev(
379 - [
380 - 'memo: The first argument must be a component. Instead ' +
381 - 'received: undefined',
382 - ],
383 - {withoutStack: true},
384 - );
378 + assertConsoleErrorDev([
379 + 'memo: The first argument must be a component. Instead ' +
380 + 'received: undefined',
381 + ]);
382 });
383
384 it('warns if the first argument is null', () => {
385 memo(null);
389 - assertConsoleErrorDev(
390 - [
391 - 'memo: The first argument must be a component. Instead ' +
392 - 'received: null',
393 - ],
394 - {withoutStack: true},
395 - );
386 + assertConsoleErrorDev([
387 + 'memo: The first argument must be a component. Instead ' +
388 + 'received: null',
389 + ]);
390 });
391
392 it('does not drop lower priority state updates when bailing out at higher pri (simple)', async () => {
packages/react-reconciler/src/__tests__/ReactNewContext-test.js
+3 -8
@@ -862,14 +862,9 @@ describe('ReactNewContext', () => {
862 );
863
864 await waitForAll([]);
865 - assertConsoleErrorDev(
866 - [
867 - 'The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?',
868 - ],
869 - {
870 - withoutStack: true,
871 - },
872 - );
865 + assertConsoleErrorDev([
866 + 'The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?',
867 + ]);
868 });
869
870 it('warns if multiple renderers concurrently render the same context', async () => {
packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js
+6 -12
@@ -1120,20 +1120,14 @@ describe('ReactFlightDOMEdge', () => {
1120 };
1121
1122 ServerModule.greet.bind({}, 'hi');
1123 - assertConsoleErrorDev(
1124 - [
1125 - 'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().',
1126 - ],
1127 - {withoutStack: true},
1128 - );
1123 + assertConsoleErrorDev([
1124 + 'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().',
1125 + ]);
1126
1127 ServerModuleImportedOnClient.greet.bind({}, 'hi');
1131 - assertConsoleErrorDev(
1132 - [
1133 - 'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().',
1134 - ],
1135 - {withoutStack: true},
1136 - );
1128 + assertConsoleErrorDev([
1129 + 'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().',
1130 + ]);
1131 });
1132
1133 it('should supports ReadableStreams with typed arrays', async () => {
packages/react-server/src/__tests__/ReactFlightServer-test.js
+4 -7
@@ -189,13 +189,10 @@ describe('ReactFlight', () => {
189 );
190
191 assertConsoleErrorDev([
192 - [
193 - 'Attempted to render <span key="one"> without development properties. This is not supported. It can happen if:' +
194 - '\n- The element is created with a production version of React but rendered in development.' +
195 - '\n- The element was cloned with a custom function instead of `React.cloneElement`.\n' +
196 - "The props of this element may help locate this element: { children: 'Free!', [key]: [Getter] }",
197 - {withoutStack: true},
198 - ],
192 + 'Attempted to render <span key="one"> without development properties. This is not supported. It can happen if:' +
193 + '\n- The element is created with a production version of React but rendered in development.' +
194 + '\n- The element was cloned with a custom function instead of `React.cloneElement`.\n' +
195 + "The props of this element may help locate this element: { children: 'Free!', [key]: [Getter] }",
196 "TypeError: Cannot read properties of undefined (reading 'stack')" +
197 '\n in <stack>',
198 ]);
packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js
+6 -11
@@ -38,17 +38,12 @@ describe('ReactTestRenderer', () => {
38 await act(() => {
39 ReactTestRenderer.create(ReactDOM.createPortal('foo', container));
40 }).catch(e => (error = e));
41 - assertConsoleErrorDev(
42 - [
43 - 'An invalid container has been provided. ' +
44 - 'This may indicate that another renderer is being used in addition to the test renderer. ' +
45 - '(For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) ' +
46 - 'This is not supported.',
47 - ],
48 - {
49 - withoutStack: true,
50 - },
51 - );
41 + assertConsoleErrorDev([
42 + 'An invalid container has been provided. ' +
43 + 'This may indicate that another renderer is being used in addition to the test renderer. ' +
44 + '(For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) ' +
45 + 'This is not supported.',
46 + ]);
47
48 // After the update throws, a subsequent render is scheduled to
49 // unmount the whole tree. This update also causes an error, so React
packages/react/src/__tests__/ReactCoffeeScriptClass-test.coffee
+2 -6
@@ -539,15 +539,11 @@ describe 'ReactCoffeeScriptClass', ->
539
540 expect(-> ref.current.replaceState {}).toThrow()
541 assertConsoleWarnDev([
542 - 'replaceState(...) is deprecated in plain JavaScript React classes.
543 - Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236).'
544 - ], {withoutStack: true})
542 + 'replaceState(...) is deprecated in plain JavaScript React classes. Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236).'])
543
544 expect(-> ref.current.isMounted()).toThrow()
545 assertConsoleWarnDev([
548 - 'isMounted(...) is deprecated in plain JavaScript React classes.
549 - Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks.',
550 - ], {withoutStack: true})
546 + 'isMounted(...) is deprecated in plain JavaScript React classes. Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks.'])
547
548 if !featureFlags.disableLegacyContext
549 it 'supports this.context passed via getChildContext', ->
packages/react/src/__tests__/ReactCreateElement-test.js
+16 -29
@@ -84,15 +84,12 @@ describe('ReactCreateElement', () => {
84 it('should warn when `key` is being accessed on a host element', () => {
85 const element = React.createElement('div', {key: '3'});
86 void element.props.key;
87 - assertConsoleErrorDev(
88 - [
89 - 'div: `key` is not a prop. Trying to access it will result ' +
90 - 'in `undefined` being returned. If you need to access the same ' +
91 - 'value within the child component, you should pass it as a different ' +
92 - 'prop. (https://react.dev/link/special-props)',
93 - ],
94 - {withoutStack: true},
95 - );
87 + assertConsoleErrorDev([
88 + 'div: `key` is not a prop. Trying to access it will result ' +
89 + 'in `undefined` being returned. If you need to access the same ' +
90 + 'value within the child component, you should pass it as a different ' +
91 + 'prop. (https://react.dev/link/special-props)',
92 + ]);
93 });
94
95 it('allows a string to be passed as the type', () => {
@@ -151,16 +148,11 @@ describe('ReactCreateElement', () => {
148 });
149 expect(element.type).toBe(ComponentClass);
150 expect(element.ref).toBe(ref);
154 - assertConsoleErrorDev(
155 - [
156 - 'Accessing element.ref was removed in React 19. ref is now a ' +
157 - 'regular prop. It will be removed from the JSX Element ' +
158 - 'type in a future release.',
159 - ],
160 - {
161 - withoutStack: true,
162 - },
163 - );
151 + assertConsoleErrorDev([
152 + 'Accessing element.ref was removed in React 19. ref is now a ' +
153 + 'regular prop. It will be removed from the JSX Element ' +
154 + 'type in a future release.',
155 + ]);
156 const expectation = {foo: '56', ref};
157 Object.freeze(expectation);
158 expect(element.props).toEqual(expectation);
@@ -429,16 +421,11 @@ describe('ReactCreateElement', () => {
421 it('warns if outdated JSX transform is detected', async () => {
422 // Warns if __self is detected, because that's only passed by a compiler
423 React.createElement('div', {className: 'foo', __self: this});
432 - assertConsoleWarnDev(
433 - [
434 - 'Your app (or one of its dependencies) is using an outdated JSX ' +
435 - 'transform. Update to the modern JSX transform for ' +
436 - 'faster performance: https://react.dev/link/new-jsx-transform',
437 - ],
438 - {
439 - withoutStack: true,
440 - },
441 - );
424 + assertConsoleWarnDev([
425 + 'Your app (or one of its dependencies) is using an outdated JSX ' +
426 + 'transform. Update to the modern JSX transform for ' +
427 + 'faster performance: https://react.dev/link/new-jsx-transform',
428 + ]);
429
430 // Only warns the first time. Subsequent elements don't warn.
431 React.createElement('div', {className: 'foo', __self: this});
packages/react/src/__tests__/ReactES6Class-test.js
+9 -15
@@ -589,22 +589,16 @@ describe('ReactES6Class', () => {
589 runTest(<Inner name="foo" ref={ref} />, 'DIV', 'foo');
590
591 expect(() => ref.current.replaceState({})).toThrow();
592 - assertConsoleWarnDev(
593 - [
594 - 'replaceState(...) is deprecated in plain JavaScript React classes. ' +
595 - 'Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236).',
596 - ],
597 - {withoutStack: true},
598 - );
592 + assertConsoleWarnDev([
593 + 'replaceState(...) is deprecated in plain JavaScript React classes. ' +
594 + 'Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236).',
595 + ]);
596 expect(() => ref.current.isMounted()).toThrow();
600 - assertConsoleWarnDev(
601 - [
602 - 'isMounted(...) is deprecated in plain JavaScript React classes. ' +
603 - 'Instead, make sure to clean up subscriptions and pending requests in ' +
604 - 'componentWillUnmount to prevent memory leaks.',
605 - ],
606 - {withoutStack: true},
607 - );
597 + assertConsoleWarnDev([
598 + 'isMounted(...) is deprecated in plain JavaScript React classes. ' +
599 + 'Instead, make sure to clean up subscriptions and pending requests in ' +
600 + 'componentWillUnmount to prevent memory leaks.',
601 + ]);
602 });
603
604 if (!require('shared/ReactFeatureFlags').disableLegacyContext) {
packages/react/src/__tests__/ReactElementClone-test.js
+5 -10
@@ -346,16 +346,11 @@ describe('ReactElementClone', () => {
346 expect(clone.key).toBe('12');
347 expect(clone.props.ref).toBe('34');
348 expect(clone.ref).toBe('34');
349 - assertConsoleErrorDev(
350 - [
351 - 'Accessing element.ref was removed in React 19. ref is now a ' +
352 - 'regular prop. It will be removed from the JSX Element ' +
353 - 'type in a future release.',
354 - ],
355 - {
356 - withoutStack: true,
357 - },
358 - );
349 + assertConsoleErrorDev([
350 + 'Accessing element.ref was removed in React 19. ref is now a ' +
351 + 'regular prop. It will be removed from the JSX Element ' +
352 + 'type in a future release.',
353 + ]);
354 expect(clone.props).toEqual({foo: 'ef', ref: '34'});
355 if (__DEV__) {
356 expect(Object.isFrozen(element)).toBe(true);
packages/react/src/__tests__/ReactJSXRuntime-test.js
+19 -28
@@ -225,28 +225,22 @@ describe('ReactJSXRuntime', () => {
225 await act(() => {
226 root.render(JSXRuntime.jsxs('div', {children: 'foo'}, null));
227 });
228 - assertConsoleErrorDev(
229 - [
230 - 'React.jsx: Static children should always be an array. ' +
231 - 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' +
232 - 'Use the Babel transform instead.',
233 - ],
234 - {withoutStack: true},
235 - );
228 + assertConsoleErrorDev([
229 + 'React.jsx: Static children should always be an array. ' +
230 + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' +
231 + 'Use the Babel transform instead.',
232 + ]);
233 });
234
235 it('should warn when `key` is being accessed on a host element', () => {
236 const element = JSXRuntime.jsxs('div', {}, '3');
237 void element.props.key;
241 - assertConsoleErrorDev(
242 - [
243 - 'div: `key` is not a prop. Trying to access it will result ' +
244 - 'in `undefined` being returned. If you need to access the same ' +
245 - 'value within the child component, you should pass it as a different ' +
246 - 'prop. (https://react.dev/link/special-props)',
247 - ],
248 - {withoutStack: true},
249 - );
238 + assertConsoleErrorDev([
239 + 'div: `key` is not a prop. Trying to access it will result ' +
240 + 'in `undefined` being returned. If you need to access the same ' +
241 + 'value within the child component, you should pass it as a different ' +
242 + 'prop. (https://react.dev/link/special-props)',
243 + ]);
244 });
245
246 it('should warn when unkeyed children are passed to jsx', async () => {
@@ -372,17 +366,14 @@ describe('ReactJSXRuntime', () => {
366 const elementWithSpreadKey = __DEV__
367 ? JSXDEVRuntime.jsxDEV('div', configWithKey)
368 : JSXRuntime.jsx('div', configWithKey);
375 - assertConsoleErrorDev(
376 - [
377 - 'A props object containing a "key" prop is being spread into JSX:\n' +
378 - ' let props = {key: someKey, foo: ..., bar: ...};\n' +
379 - ' <div {...props} />\n' +
380 - 'React keys must be passed directly to JSX without using spread:\n' +
381 - ' let props = {foo: ..., bar: ...};\n' +
382 - ' <div key={someKey} {...props} />',
383 - ],
384 - {withoutStack: true},
385 - );
369 + assertConsoleErrorDev([
370 + 'A props object containing a "key" prop is being spread into JSX:\n' +
371 + ' let props = {key: someKey, foo: ..., bar: ...};\n' +
372 + ' <div {...props} />\n' +
373 + 'React keys must be passed directly to JSX without using spread:\n' +
374 + ' let props = {foo: ..., bar: ...};\n' +
375 + ' <div key={someKey} {...props} />',
376 + ]);
377 expect(elementWithSpreadKey.props).not.toBe(configWithKey);
378 });
379 });
packages/react/src/__tests__/ReactJSXTransformIntegration-test.js
+5 -8
@@ -114,14 +114,11 @@ describe('ReactJSXTransformIntegration', () => {
114 const element = <Component ref={ref} foo="56" />;
115 expect(element.type).toBe(Component);
116 expect(element.ref).toBe(ref);
117 - assertConsoleErrorDev(
118 - [
119 - 'Accessing element.ref was removed in React 19. ref is now a ' +
120 - 'regular prop. It will be removed from the JSX Element ' +
121 - 'type in a future release.',
122 - ],
123 - {withoutStack: true},
124 - );
117 + assertConsoleErrorDev([
118 + 'Accessing element.ref was removed in React 19. ref is now a ' +
119 + 'regular prop. It will be removed from the JSX Element ' +
120 + 'type in a future release.',
121 + ]);
122 const expectation = {foo: '56', ref};
123 Object.freeze(expectation);
124 expect(element.props).toEqual(expectation);
packages/react/src/__tests__/ReactProfilerComponent-test.internal.js
+3 -8
@@ -59,14 +59,9 @@ describe('Profiler', () => {
59 await act(() => {
60 root.render(<React.Profiler />);
61 });
62 - assertConsoleErrorDev(
63 - [
64 - 'Profiler must specify an "id" of type `string` as a prop. Received the type `undefined` instead.',
65 - ],
66 - {
67 - withoutStack: true,
68 - },
69 - );
62 + assertConsoleErrorDev([
63 + 'Profiler must specify an "id" of type `string` as a prop. Received the type `undefined` instead.',
64 + ]);
65 });
66 }
67
packages/react/src/__tests__/ReactStartTransition-test.js
+10 -16
@@ -61,14 +61,11 @@ describe('ReactStartTransition', () => {
61 });
62 });
63 });
64 - assertConsoleWarnDev(
65 - [
66 - 'Detected a large number of updates inside startTransition. ' +
67 - 'If this is due to a subscription please re-write it to use React provided hooks. ' +
68 - 'Otherwise concurrent mode guarantees are off the table.',
69 - ],
70 - {withoutStack: true},
71 - );
64 + assertConsoleWarnDev([
65 + 'Detected a large number of updates inside startTransition. ' +
66 + 'If this is due to a subscription please re-write it to use React provided hooks. ' +
67 + 'Otherwise concurrent mode guarantees are off the table.',
68 + ]);
69
70 await act(() => {
71 triggerHookTransition(() => {
@@ -77,13 +74,10 @@ describe('ReactStartTransition', () => {
74 });
75 });
76 });
80 - assertConsoleWarnDev(
81 - [
82 - 'Detected a large number of updates inside startTransition. ' +
83 - 'If this is due to a subscription please re-write it to use React provided hooks. ' +
84 - 'Otherwise concurrent mode guarantees are off the table.',
85 - ],
86 - {withoutStack: true},
87 - );
77 + assertConsoleWarnDev([
78 + 'Detected a large number of updates inside startTransition. ' +
79 + 'If this is due to a subscription please re-write it to use React provided hooks. ' +
80 + 'Otherwise concurrent mode guarantees are off the table.',
81 + ]);
82 });
83 });
packages/react/src/__tests__/ReactStrictMode-test.js
+37 -55
@@ -624,27 +624,24 @@ describe('Concurrent Mode', () => {
624 const container = document.createElement('div');
625 const root = ReactDOMClient.createRoot(container);
626 await act(() => root.render(<StrictRoot />));
627 - assertConsoleErrorDev(
628 - [
629 - `Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
627 + assertConsoleErrorDev([
628 + `Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
629
630 * Move code with side effects to componentDidMount, and set initial state in the constructor.
631
632 Please update the following components: App`,
634 - `Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
633 + `Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
634
635 * Move data fetching code or side effects to componentDidUpdate.
636 * If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state
637
638 Please update the following components: Bar, Foo`,
640 - `Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
639 + `Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
640
641 * Move data fetching code or side effects to componentDidUpdate.
642
643 Please update the following components: App`,
645 - ],
646 - {withoutStack: true},
647 - );
644 + ]);
645
646 // Dedupe
647 await act(() => root.render(<App />));
@@ -684,51 +681,45 @@ Please update the following components: App`,
681 const root = ReactDOMClient.createRoot(container);
682
683 await act(() => root.render(<StrictRoot />));
687 - assertConsoleErrorDev(
688 - [
689 - `Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
684 + assertConsoleErrorDev([
685 + `Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
686
687 * Move code with side effects to componentDidMount, and set initial state in the constructor.
688
689 Please update the following components: App`,
694 - `Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
690 + `Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
691
692 * Move data fetching code or side effects to componentDidUpdate.
693 * If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state
694
695 Please update the following components: Child`,
700 - `Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
696 + `Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://react.dev/link/unsafe-component-lifecycles for details.
697
698 * Move data fetching code or side effects to componentDidUpdate.
699
700 Please update the following components: App`,
705 - ],
706 - {withoutStack: true},
707 - );
708 - assertConsoleWarnDev(
709 - [
710 - `componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
701 + ]);
702 + assertConsoleWarnDev([
703 + `componentWillMount has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
704
705 * Move code with side effects to componentDidMount, and set initial state in the constructor.
706 * Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.
707
708 Please update the following components: Parent`,
716 - `componentWillReceiveProps has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
709 + `componentWillReceiveProps has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
710
711 * Move data fetching code or side effects to componentDidUpdate.
712 * If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state
713 * Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.
714
715 Please update the following components: Parent`,
723 - `componentWillUpdate has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
716 + `componentWillUpdate has been renamed, and is not recommended for use. See https://react.dev/link/unsafe-component-lifecycles for details.
717
718 * Move data fetching code or side effects to componentDidUpdate.
719 * Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run \`npx react-codemod rename-unsafe-lifecycles\` in your project source folder.
720
721 Please update the following components: Parent`,
729 - ],
730 - {withoutStack: true},
731 - );
722 + ]);
723 // Dedupe
724 await act(() => root.render(<StrictRoot />));
725 });
@@ -753,26 +744,20 @@ Please update the following components: Parent`,
744 const container = document.createElement('div');
745 const root = ReactDOMClient.createRoot(container);
746 await act(() => root.render(<StrictRoot foo={true} />));
756 - assertConsoleErrorDev(
757 - [
758 - 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' +
759 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
760 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\n' +
761 - 'Please update the following components: Foo',
762 - ],
763 - {withoutStack: true},
764 - );
747 + assertConsoleErrorDev([
748 + 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' +
749 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
750 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\n' +
751 + 'Please update the following components: Foo',
752 + ]);
753
754 await act(() => root.render(<StrictRoot foo={false} />));
767 - assertConsoleErrorDev(
768 - [
769 - 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' +
770 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
771 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\n' +
772 - 'Please update the following components: Bar',
773 - ],
774 - {withoutStack: true},
775 - );
755 + assertConsoleErrorDev([
756 + 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' +
757 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
758 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\n' +
759 + 'Please update the following components: Bar',
760 + ]);
761
762 // Dedupe
763 await act(() => root.render(<StrictRoot foo={true} />));
@@ -821,19 +806,16 @@ Please update the following components: Parent`,
806 await act(() => {
807 root.render(<SyncRoot />);
808 });
824 - assertConsoleErrorDev(
825 - [
826 - 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' +
827 - 'and may indicate bugs in your code. ' +
828 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
829 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
830 - "* If you're updating state whenever props change, " +
831 - 'refactor your code to use memoization techniques or move it to ' +
832 - 'static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n\n' +
833 - 'Please update the following components: Bar, Foo',
834 - ],
835 - {withoutStack: true},
836 - );
809 + assertConsoleErrorDev([
810 + 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' +
811 + 'and may indicate bugs in your code. ' +
812 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
813 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
814 + "* If you're updating state whenever props change, " +
815 + 'refactor your code to use memoization techniques or move it to ' +
816 + 'static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n\n' +
817 + 'Please update the following components: Bar, Foo',
818 + ]);
819
820 // Dedupe
821 await act(() => {
packages/react/src/__tests__/ReactTypeScriptClass-test.ts
+9 -15
@@ -694,22 +694,16 @@ describe('ReactTypeScriptClass', function () {
694 const ref = React.createRef();
695 test(React.createElement(Inner, {name: 'foo', ref: ref}), 'DIV', 'foo');
696 expect(() => ref.current.replaceState({})).toThrow();
697 - assertConsoleWarnDev(
698 - [
699 - 'replaceState(...) is deprecated in plain JavaScript React classes. ' +
700 - 'Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236).',
701 - ],
702 - {withoutStack: true},
703 - );
697 + assertConsoleWarnDev([
698 + 'replaceState(...) is deprecated in plain JavaScript React classes. ' +
699 + 'Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236).',
700 + ]);
701 expect(() => ref.current.isMounted()).toThrow();
705 - assertConsoleWarnDev(
706 - [
707 - 'isMounted(...) is deprecated in plain JavaScript React classes. ' +
708 - 'Instead, make sure to clean up subscriptions and pending requests in ' +
709 - 'componentWillUnmount to prevent memory leaks.',
710 - ],
711 - {withoutStack: true},
712 - );
702 + assertConsoleWarnDev([
703 + 'isMounted(...) is deprecated in plain JavaScript React classes. ' +
704 + 'Instead, make sure to clean up subscriptions and pending requests in ' +
705 + 'componentWillUnmount to prevent memory leaks.',
706 + ]);
707 });
708
709 if (!ReactFeatureFlags.disableLegacyContext) {
packages/react/src/__tests__/createReactClassIntegration-test.js
+122 -158
@@ -67,13 +67,10 @@ describe('create-react-class-integration', () => {
67 return <span>{this.props.prop}</span>;
68 },
69 });
70 - assertConsoleErrorDev(
71 - [
72 - 'Warning: Component: prop type `prop` is invalid; ' +
73 - 'it must be a function, usually from React.PropTypes.',
74 - ],
75 - {withoutStack: true},
76 - );
70 + assertConsoleErrorDev([
71 + 'Warning: Component: prop type `prop` is invalid; ' +
72 + 'it must be a function, usually from React.PropTypes.',
73 + ]);
74 });
75
76 it('should warn on invalid context types', () => {
@@ -86,13 +83,10 @@ describe('create-react-class-integration', () => {
83 return <span>{this.props.prop}</span>;
84 },
85 });
89 - assertConsoleErrorDev(
90 - [
91 - 'Warning: Component: context type `prop` is invalid; ' +
92 - 'it must be a function, usually from React.PropTypes.',
93 - ],
94 - {withoutStack: true},
95 - );
86 + assertConsoleErrorDev([
87 + 'Warning: Component: context type `prop` is invalid; ' +
88 + 'it must be a function, usually from React.PropTypes.',
89 + ]);
90 });
91
92 it('should throw on invalid child context types', () => {
@@ -105,12 +99,9 @@ describe('create-react-class-integration', () => {
99 return <span>{this.props.prop}</span>;
100 },
101 });
108 - assertConsoleErrorDev(
109 - [
110 - 'Warning: Component: child context type `prop` is invalid; it must be a function, usually from React.PropTypes.',
111 - ],
112 - {withoutStack: true},
113 - );
102 + assertConsoleErrorDev([
103 + 'Warning: Component: child context type `prop` is invalid; it must be a function, usually from React.PropTypes.',
104 + ]);
105 });
106
107 it('should warn when misspelling shouldComponentUpdate', () => {
@@ -122,14 +113,11 @@ describe('create-react-class-integration', () => {
113 return <div />;
114 },
115 });
125 - assertConsoleErrorDev(
126 - [
127 - 'Warning: A component has a method called componentShouldUpdate(). Did you ' +
128 - 'mean shouldComponentUpdate()? The name is phrased as a question ' +
129 - 'because the function is expected to return a value.',
130 - ],
131 - {withoutStack: true},
132 - );
116 + assertConsoleErrorDev([
117 + 'Warning: A component has a method called componentShouldUpdate(). Did you ' +
118 + 'mean shouldComponentUpdate()? The name is phrased as a question ' +
119 + 'because the function is expected to return a value.',
120 + ]);
121
122 createReactClass({
123 displayName: 'NamedComponent',
@@ -140,14 +128,11 @@ describe('create-react-class-integration', () => {
128 return <div />;
129 },
130 });
143 - assertConsoleErrorDev(
144 - [
145 - 'Warning: NamedComponent has a method called componentShouldUpdate(). Did you ' +
146 - 'mean shouldComponentUpdate()? The name is phrased as a question ' +
147 - 'because the function is expected to return a value.',
148 - ],
149 - {withoutStack: true},
150 - );
131 + assertConsoleErrorDev([
132 + 'Warning: NamedComponent has a method called componentShouldUpdate(). Did you ' +
133 + 'mean shouldComponentUpdate()? The name is phrased as a question ' +
134 + 'because the function is expected to return a value.',
135 + ]);
136 });
137
138 it('should warn when misspelling componentWillReceiveProps', () => {
@@ -159,13 +144,10 @@ describe('create-react-class-integration', () => {
144 return <div />;
145 },
146 });
162 - assertConsoleErrorDev(
163 - [
164 - 'Warning: A component has a method called componentWillRecieveProps(). Did you ' +
165 - 'mean componentWillReceiveProps()?',
166 - ],
167 - {withoutStack: true},
168 - );
147 + assertConsoleErrorDev([
148 + 'Warning: A component has a method called componentWillRecieveProps(). Did you ' +
149 + 'mean componentWillReceiveProps()?',
150 + ]);
151 });
152
153 it('should warn when misspelling UNSAFE_componentWillReceiveProps', () => {
@@ -177,13 +159,10 @@ describe('create-react-class-integration', () => {
159 return <div />;
160 },
161 });
180 - assertConsoleErrorDev(
181 - [
182 - 'Warning: A component has a method called UNSAFE_componentWillRecieveProps(). ' +
183 - 'Did you mean UNSAFE_componentWillReceiveProps()?',
184 - ],
185 - {withoutStack: true},
186 - );
162 + assertConsoleErrorDev([
163 + 'Warning: A component has a method called UNSAFE_componentWillRecieveProps(). ' +
164 + 'Did you mean UNSAFE_componentWillReceiveProps()?',
165 + ]);
166 });
167
168 it('should throw if a reserved property is in statics', () => {
@@ -348,11 +327,8 @@ describe('create-react-class-integration', () => {
327 root.render(<Outer />);
328 });
329 assertConsoleErrorDev([
351 - [
352 - 'Component uses the legacy childContextTypes API which will soon be removed. ' +
353 - 'Use React.createContext() instead. (https://react.dev/link/legacy-context)',
354 - {withoutStack: true},
355 - ],
330 + 'Component uses the legacy childContextTypes API which will soon be removed. ' +
331 + 'Use React.createContext() instead. (https://react.dev/link/legacy-context)',
332 'Component uses the legacy contextTypes API which will soon be removed. ' +
333 'Use React.createContext() with static contextType instead. (https://react.dev/link/legacy-context)' +
334 '\n in ReactClassComponent (at **)',
@@ -409,13 +385,10 @@ describe('create-react-class-integration', () => {
385 });
386
387 expect(() => Component()).toThrow();
412 - assertConsoleErrorDev(
413 - [
414 - 'Warning: Something is calling a React component directly. Use a ' +
415 - 'factory or JSX instead. See: https://fb.me/react-legacyfactory',
416 - ],
417 - {withoutStack: true},
418 - );
388 + assertConsoleErrorDev([
389 + 'Warning: Something is calling a React component directly. Use a ' +
390 + 'factory or JSX instead. See: https://fb.me/react-legacyfactory',
391 + ]);
392 });
393
394 it('replaceState and callback works', async () => {
@@ -635,38 +608,35 @@ describe('create-react-class-integration', () => {
608 'https://react.dev/link/unsafe-component-lifecycles\n' +
609 ' in Component (at **)',
610 ]);
638 - assertConsoleWarnDev(
639 - [
640 - 'componentWillMount has been renamed, and is not recommended for use. ' +
641 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
642 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
643 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' +
644 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
645 - 'To rename all deprecated lifecycles to their new names, you can run ' +
646 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
647 - '\nPlease update the following components: Component',
648 - 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
649 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
650 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
651 - "* If you're updating state whenever props change, refactor your " +
652 - 'code to use memoization techniques or move it to ' +
653 - 'static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n' +
654 - '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' +
655 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
656 - 'To rename all deprecated lifecycles to their new names, you can run ' +
657 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
658 - '\nPlease update the following components: Component',
659 - 'componentWillUpdate has been renamed, and is not recommended for use. ' +
660 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
661 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
662 - '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' +
663 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
664 - 'To rename all deprecated lifecycles to their new names, you can run ' +
665 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
666 - '\nPlease update the following components: Component',
667 - ],
668 - {withoutStack: true},
669 - );
611 + assertConsoleWarnDev([
612 + 'componentWillMount has been renamed, and is not recommended for use. ' +
613 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
614 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
615 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' +
616 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
617 + 'To rename all deprecated lifecycles to their new names, you can run ' +
618 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
619 + '\nPlease update the following components: Component',
620 + 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
621 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
622 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
623 + "* If you're updating state whenever props change, refactor your " +
624 + 'code to use memoization techniques or move it to ' +
625 + 'static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n' +
626 + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' +
627 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
628 + 'To rename all deprecated lifecycles to their new names, you can run ' +
629 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
630 + '\nPlease update the following components: Component',
631 + 'componentWillUpdate has been renamed, and is not recommended for use. ' +
632 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
633 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
634 + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' +
635 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
636 + 'To rename all deprecated lifecycles to their new names, you can run ' +
637 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
638 + '\nPlease update the following components: Component',
639 + ]);
640 await act(() => {
641 root.render(<Component foo={1} />);
642 });
@@ -707,38 +677,35 @@ describe('create-react-class-integration', () => {
677 'https://react.dev/link/unsafe-component-lifecycles\n' +
678 ' in Component (at **)',
679 ]);
710 - assertConsoleWarnDev(
711 - [
712 - 'componentWillMount has been renamed, and is not recommended for use. ' +
713 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
714 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
715 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' +
716 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
717 - 'To rename all deprecated lifecycles to their new names, you can run ' +
718 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
719 - '\nPlease update the following components: Component',
720 - 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
721 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
722 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
723 - "* If you're updating state whenever props change, refactor your " +
724 - 'code to use memoization techniques or move it to ' +
725 - 'static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n' +
726 - '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' +
727 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
728 - 'To rename all deprecated lifecycles to their new names, you can run ' +
729 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
730 - '\nPlease update the following components: Component',
731 - 'componentWillUpdate has been renamed, and is not recommended for use. ' +
732 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
733 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
734 - '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' +
735 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
736 - 'To rename all deprecated lifecycles to their new names, you can run ' +
737 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
738 - '\nPlease update the following components: Component',
739 - ],
740 - {withoutStack: true},
741 - );
680 + assertConsoleWarnDev([
681 + 'componentWillMount has been renamed, and is not recommended for use. ' +
682 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
683 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
684 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' +
685 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
686 + 'To rename all deprecated lifecycles to their new names, you can run ' +
687 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
688 + '\nPlease update the following components: Component',
689 + 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
690 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
691 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
692 + "* If you're updating state whenever props change, refactor your " +
693 + 'code to use memoization techniques or move it to ' +
694 + 'static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n' +
695 + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' +
696 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
697 + 'To rename all deprecated lifecycles to their new names, you can run ' +
698 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
699 + '\nPlease update the following components: Component',
700 + 'componentWillUpdate has been renamed, and is not recommended for use. ' +
701 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
702 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
703 + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' +
704 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
705 + 'To rename all deprecated lifecycles to their new names, you can run ' +
706 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
707 + '\nPlease update the following components: Component',
708 + ]);
709 await act(() => {
710 const root2 = ReactDOMClient.createRoot(document.createElement('div'));
711 root2.render(<Component foo={1} />);
@@ -781,38 +748,35 @@ describe('create-react-class-integration', () => {
748 await act(() => {
749 root.render(<Component foo="bar" />);
750 });
784 - assertConsoleWarnDev(
785 - [
786 - 'componentWillMount has been renamed, and is not recommended for use. ' +
787 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
788 - '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
789 - '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' +
790 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
791 - 'To rename all deprecated lifecycles to their new names, you can run ' +
792 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
793 - '\nPlease update the following components: Component',
794 - 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
795 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
796 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
797 - "* If you're updating state whenever props change, refactor your " +
798 - 'code to use memoization techniques or move it to ' +
799 - 'static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n' +
800 - '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' +
801 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
802 - 'To rename all deprecated lifecycles to their new names, you can run ' +
803 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
804 - '\nPlease update the following components: Component',
805 - 'componentWillUpdate has been renamed, and is not recommended for use. ' +
806 - 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
807 - '* Move data fetching code or side effects to componentDidUpdate.\n' +
808 - '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' +
809 - 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
810 - 'To rename all deprecated lifecycles to their new names, you can run ' +
811 - '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
812 - '\nPlease update the following components: Component',
813 - ],
814 - {withoutStack: true},
815 - );
751 + assertConsoleWarnDev([
752 + 'componentWillMount has been renamed, and is not recommended for use. ' +
753 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
754 + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' +
755 + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' +
756 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
757 + 'To rename all deprecated lifecycles to their new names, you can run ' +
758 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
759 + '\nPlease update the following components: Component',
760 + 'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
761 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
762 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
763 + "* If you're updating state whenever props change, refactor your " +
764 + 'code to use memoization techniques or move it to ' +
765 + 'static getDerivedStateFromProps. Learn more at: https://react.dev/link/derived-state\n' +
766 + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' +
767 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
768 + 'To rename all deprecated lifecycles to their new names, you can run ' +
769 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
770 + '\nPlease update the following components: Component',
771 + 'componentWillUpdate has been renamed, and is not recommended for use. ' +
772 + 'See https://react.dev/link/unsafe-component-lifecycles for details.\n\n' +
773 + '* Move data fetching code or side effects to componentDidUpdate.\n' +
774 + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' +
775 + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' +
776 + 'To rename all deprecated lifecycles to their new names, you can run ' +
777 + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' +
778 + '\nPlease update the following components: Component',
779 + ]);
780 expect(log).toEqual(['componentWillMount', 'UNSAFE_componentWillMount']);
781
782 log.length = 0;
packages/react/src/__tests__/forwardRef-test.js
+29 -47
@@ -78,32 +78,26 @@ describe('forwardRef', () => {
78
79 it('should warn if not provided a callback during creation', () => {
80 React.forwardRef(undefined);
81 - assertConsoleErrorDev(
82 - ['forwardRef requires a render function but was given undefined.'],
83 - {withoutStack: true},
84 - );
81 + assertConsoleErrorDev([
82 + 'forwardRef requires a render function but was given undefined.',
83 + ]);
84
85 React.forwardRef(null);
87 - assertConsoleErrorDev(
88 - ['forwardRef requires a render function but was given null.'],
89 - {
90 - withoutStack: true,
91 - },
92 - );
86 + assertConsoleErrorDev([
87 + 'forwardRef requires a render function but was given null.',
88 + ]);
89
90 React.forwardRef('foo');
95 - assertConsoleErrorDev(
96 - ['forwardRef requires a render function but was given string.'],
97 - {withoutStack: true},
98 - );
91 + assertConsoleErrorDev([
92 + 'forwardRef requires a render function but was given string.',
93 + ]);
94 });
95
96 it('should warn if no render function is provided', () => {
97 React.forwardRef();
103 - assertConsoleErrorDev(
104 - ['forwardRef requires a render function but was given undefined.'],
105 - {withoutStack: true},
106 - );
98 + assertConsoleErrorDev([
99 + 'forwardRef requires a render function but was given undefined.',
100 + ]);
101 });
102
103 it('should warn if the render function provided has defaultProps attributes', () => {
@@ -113,13 +107,10 @@ describe('forwardRef', () => {
107 renderWithDefaultProps.defaultProps = {};
108
109 React.forwardRef(renderWithDefaultProps);
116 - assertConsoleErrorDev(
117 - [
118 - 'forwardRef render functions do not support defaultProps. ' +
119 - 'Did you accidentally pass a React component?',
120 - ],
121 - {withoutStack: true},
122 - );
110 + assertConsoleErrorDev([
111 + 'forwardRef render functions do not support defaultProps. ' +
112 + 'Did you accidentally pass a React component?',
113 + ]);
114 });
115
116 it('should not warn if the render function provided does not use any parameter', () => {
@@ -132,13 +123,10 @@ describe('forwardRef', () => {
123 const arityOfOne = props => <div {...props} />;
124
125 React.forwardRef(arityOfOne);
135 - assertConsoleErrorDev(
136 - [
137 - 'forwardRef render functions accept exactly two parameters: props and ref. ' +
138 - 'Did you forget to use the ref parameter?',
139 - ],
140 - {withoutStack: true},
141 - );
126 + assertConsoleErrorDev([
127 + 'forwardRef render functions accept exactly two parameters: props and ref. ' +
128 + 'Did you forget to use the ref parameter?',
129 + ]);
130 });
131
132 it('should not warn if the render function provided use exactly two parameters', () => {
@@ -150,13 +138,10 @@ describe('forwardRef', () => {
138 const arityOfThree = (props, ref, x) => <div {...props} ref={ref} x={x} />;
139
140 React.forwardRef(arityOfThree);
153 - assertConsoleErrorDev(
154 - [
155 - 'forwardRef render functions accept exactly two parameters: props and ref. ' +
156 - 'Any additional parameter will be undefined.',
157 - ],
158 - {withoutStack: true},
159 - );
141 + assertConsoleErrorDev([
142 + 'forwardRef render functions accept exactly two parameters: props and ref. ' +
143 + 'Any additional parameter will be undefined.',
144 + ]);
145 });
146
147 it('should skip forwardRef in the stack if neither displayName nor name are present', async () => {
@@ -394,13 +379,10 @@ describe('forwardRef', () => {
379 return null;
380 }),
381 );
397 - assertConsoleErrorDev(
398 - [
399 - 'forwardRef requires a render function but received a `memo` ' +
400 - 'component. Instead of forwardRef(memo(...)), use ' +
401 - 'memo(forwardRef(...)).',
402 - ],
403 - {withoutStack: true},
404 - );
382 + assertConsoleErrorDev([
383 + 'forwardRef requires a render function but received a `memo` ' +
384 + 'component. Instead of forwardRef(memo(...)), use ' +
385 + 'memo(forwardRef(...)).',
386 + ]);
387 });
388 });
packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js
+5 -11
@@ -637,17 +637,11 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => {
637 assertConsoleErrorDev(
638 gate(flags => flags.enableUseSyncExternalStoreShim)
639 ? [
640 - [
641 - 'The result of getSnapshot should be cached to avoid an infinite loop',
642 - {withoutStack: true},
643 - ],
644 - [
645 - 'Error: Maximum update depth exceeded. ' +
646 - 'This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. ' +
647 - 'React limits the number of nested updates to prevent infinite loops.' +
648 - '\n in <stack>',
649 - {withoutStack: true},
650 - ],
640 + 'The result of getSnapshot should be cached to avoid an infinite loop',
641 + 'Error: Maximum update depth exceeded. ' +
642 + 'This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. ' +
643 + 'React limits the number of nested updates to prevent infinite loops.' +
644 + '\n in <stack>',
645 'The above error occurred in the <App> component:\n\n' +
646 ' in App (at **)\n\n' +
647 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +