@samitouri / QOS-React-1 / commits / 83be48b9de

[tests] fix hidden use() warnings (#31984)

`spyOnDev` is such a footgun.

Ricky committed Jan 6, 2025 at 14:12 UTC 83be48b9dee25737063ca64880f82ef9fea11737
1 file changed +326 -107
packages/react-reconciler/src/__tests__/ReactUse-test.js
+326 -107
@@ -27,6 +27,7 @@ let waitForPaint;
27 let assertLog;
28 let waitForAll;
29 let waitForMicrotasks;
30 +let assertConsoleErrorDev;
31
32 describe('ReactUse', () => {
33 beforeEach(() => {
@@ -51,6 +52,7 @@ describe('ReactUse', () => {
52 waitForPaint = InternalTestUtils.waitForPaint;
53 waitFor = InternalTestUtils.waitFor;
54 waitForMicrotasks = InternalTestUtils.waitForMicrotasks;
55 + assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev;
56
57 pendingTextRequests = new Map();
58 });
@@ -246,16 +248,19 @@ describe('ReactUse', () => {
248 }
249
250 const root = ReactNoop.createRoot();
249 - await expect(async () => {
250 - await act(() => {
251 - startTransition(() => {
252 - root.render(<App />);
253 - });
251 + await act(() => {
252 + startTransition(() => {
253 + root.render(<App />);
254 });
255 - }).toErrorDev([
255 + });
256 + assertConsoleErrorDev([
257 'A component was suspended by an uncached promise. Creating ' +
258 'promises inside a Client Component or hook is not yet ' +
258 - 'supported, except via a Suspense-compatible library or framework.',
259 + 'supported, except via a Suspense-compatible library or framework.\n' +
260 + (gate('enableOwnerStacks')
261 + ? ''
262 + : ' in Async (at **)\n' + ' in Suspense (at **)\n') +
263 + ' in App (at **)',
264 ]);
265 assertLog(['ABC']);
266 expect(root).toMatchRenderedOutput('ABC');
@@ -416,19 +421,30 @@ describe('ReactUse', () => {
421 }
422
423 const root = ReactNoop.createRoot();
419 - await expect(async () => {
420 - await act(() => {
421 - startTransition(() => {
422 - root.render(<App />);
423 - });
424 + await act(() => {
425 + startTransition(() => {
426 + root.render(<App />);
427 });
425 - }).toErrorDev([
428 + });
429 + assertConsoleErrorDev([
430 'A component was suspended by an uncached promise. Creating ' +
431 'promises inside a Client Component or hook is not yet ' +
428 - 'supported, except via a Suspense-compatible library or framework.',
432 + 'supported, except via a Suspense-compatible library or framework.\n' +
433 + (gate('enableOwnerStacks')
434 + ? ''
435 + : ' in Async (at **)\n' +
436 + ' in ErrorBoundary (at **)\n' +
437 + ' in Suspense (at **)\n') +
438 + ' in App (at **)',
439 'A component was suspended by an uncached promise. Creating ' +
440 'promises inside a Client Component or hook is not yet ' +
431 - 'supported, except via a Suspense-compatible library or framework.',
441 + 'supported, except via a Suspense-compatible library or framework.\n' +
442 + (gate('enableOwnerStacks')
443 + ? ''
444 + : ' in Async (at **)\n' +
445 + ' in ErrorBoundary (at **)\n' +
446 + ' in Suspense (at **)\n') +
447 + ' in App (at **)',
448 ]);
449 assertLog([
450 // First attempt. The uncached promise suspends.
@@ -560,6 +576,7 @@ describe('ReactUse', () => {
576 'allowed and can lead to unexpected behavior. To handle errors ' +
577 'triggered by `use`, wrap your component in a error boundary.',
578 );
579 + console.error.mockRestore();
580 }
581 });
582
@@ -596,6 +613,13 @@ describe('ReactUse', () => {
613 resolveTextRequests('Async');
614 });
615 assertLog(['Async text requested [Async]', 'Async']);
616 + assertConsoleErrorDev([
617 + 'A component was suspended by an uncached promise. ' +
618 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
619 + 'except via a Suspense-compatible library or framework.\n' +
620 + ' in App (at **)\n' +
621 + ' in Suspense (at **)',
622 + ]);
623 expect(root).toMatchRenderedOutput('Async');
624 });
625
@@ -639,6 +663,13 @@ describe('ReactUse', () => {
663 });
664 // This time it finishes because it was during a retry.
665 assertLog(['Async text requested [Async]', 'Async']);
666 + assertConsoleErrorDev([
667 + 'A component was suspended by an uncached promise. ' +
668 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
669 + 'except via a Suspense-compatible library or framework.\n' +
670 + ' in App (at **)\n' +
671 + ' in Suspense (at **)',
672 + ]);
673 expect(root).toMatchRenderedOutput('Async');
674 });
675
@@ -886,6 +917,7 @@ describe('ReactUse', () => {
917 root.render(<ExcitingText text="Hello" />);
918 });
919 });
920 +
921 // Suspends while we wait for the async service to respond.
922 assertLog(['Compute uppercase: Hello', 'Async text requested [HELLO!]']);
923 expect(root).toMatchRenderedOutput(null);
@@ -894,6 +926,13 @@ describe('ReactUse', () => {
926 await act(() => {
927 resolveTextRequests('HELLO!');
928 });
929 + assertConsoleErrorDev([
930 + 'A component was suspended by an uncached promise. ' +
931 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
932 + 'except via a Suspense-compatible library or framework.\n' +
933 + ' in ExcitingText (at **)',
934 + ]);
935 +
936 assertLog([
937 // We shouldn't run the uppercase computation again, because we can reuse
938 // the computation from the previous attempt.
@@ -931,6 +970,13 @@ describe('ReactUse', () => {
970 resolveTextRequests('apple');
971 });
972 assertLog(['Async text requested [apple]', 'apple carrot']);
973 + assertConsoleErrorDev([
974 + 'A component was suspended by an uncached promise. ' +
975 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
976 + 'except via a Suspense-compatible library or framework.\n' +
977 + ' in Kitchen (at **)',
978 + ]);
979 +
980 expect(root).toMatchRenderedOutput('apple carrot');
981
982 // Update the state variable after the use().
@@ -945,6 +991,13 @@ describe('ReactUse', () => {
991 resolveTextRequests('apple');
992 });
993 assertLog(['Async text requested [apple]', 'apple dill']);
994 + assertConsoleErrorDev([
995 + 'A component was suspended by an uncached promise. ' +
996 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
997 + 'except via a Suspense-compatible library or framework.\n' +
998 + ' in Kitchen (at **)',
999 + ]);
1000 +
1001 expect(root).toMatchRenderedOutput('apple dill');
1002
1003 // Update the state variable before the use(). The second state is maintained.
@@ -959,6 +1012,12 @@ describe('ReactUse', () => {
1012 resolveTextRequests('banana');
1013 });
1014 assertLog(['Async text requested [banana]', 'banana dill']);
1015 + assertConsoleErrorDev([
1016 + 'A component was suspended by an uncached promise. ' +
1017 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1018 + 'except via a Suspense-compatible library or framework.\n' +
1019 + ' in Kitchen (at **)',
1020 + ]);
1021 expect(root).toMatchRenderedOutput('banana dill');
1022 });
1023
@@ -987,6 +1046,12 @@ describe('ReactUse', () => {
1046 resolveTextRequests('aguacate');
1047 });
1048 assertLog(['Async text requested [aguacate]', 'aguacate abogado']);
1049 + assertConsoleErrorDev([
1050 + 'A component was suspended by an uncached promise. ' +
1051 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1052 + 'except via a Suspense-compatible library or framework.\n' +
1053 + ' in Lexicon (at **)',
1054 + ]);
1055 expect(root).toMatchRenderedOutput('aguacate abogado');
1056
1057 // Now update the state.
@@ -1001,6 +1066,12 @@ describe('ReactUse', () => {
1066 resolveTextRequests('aguacate');
1067 });
1068 assertLog(['Async text requested [aguacate]', 'aguacate avocat']);
1069 + assertConsoleErrorDev([
1070 + 'A component was suspended by an uncached promise. ' +
1071 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1072 + 'except via a Suspense-compatible library or framework.\n' +
1073 + ' in Lexicon (at **)',
1074 + ]);
1075 expect(root).toMatchRenderedOutput('aguacate avocat');
1076 });
1077
@@ -1141,6 +1212,13 @@ describe('ReactUse', () => {
1212 'Async text requested [B]',
1213 '(Loading B...)',
1214 ]);
1215 + assertConsoleErrorDev([
1216 + 'A component was suspended by an uncached promise. ' +
1217 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1218 + 'except via a Suspense-compatible library or framework.\n' +
1219 + ' in AsyncText (at **)\n' +
1220 + ' in Suspense (at **)',
1221 + ]);
1222 expect(root).toMatchRenderedOutput('A(Loading B...)');
1223
1224 await act(() => {
@@ -1161,6 +1239,14 @@ describe('ReactUse', () => {
1239 'Async text requested [C]',
1240 '(Loading C...)',
1241 ]);
1242 + assertConsoleErrorDev([
1243 + 'A component was suspended by an uncached promise. ' +
1244 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1245 + 'except via a Suspense-compatible library or framework.\n' +
1246 + ' in AsyncText (at **)\n' +
1247 + ' in Suspense (at **)\n' +
1248 + ' in Suspense (at **)',
1249 + ]);
1250 expect(root).toMatchRenderedOutput('AB(Loading C...)');
1251
1252 await act(() => {
@@ -1173,6 +1259,15 @@ describe('ReactUse', () => {
1259 resolveTextRequests('C');
1260 });
1261 assertLog(['Async text requested [C]', 'C']);
1262 + assertConsoleErrorDev([
1263 + 'A component was suspended by an uncached promise. ' +
1264 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1265 + 'except via a Suspense-compatible library or framework.\n' +
1266 + ' in AsyncText (at **)\n' +
1267 + ' in Suspense (at **)\n' +
1268 + ' in Suspense (at **)\n' +
1269 + ' in Suspense (at **)',
1270 + ]);
1271 expect(root).toMatchRenderedOutput('ABC');
1272 });
1273
@@ -1202,6 +1297,22 @@ describe('ReactUse', () => {
1297 });
1298 });
1299 assertLog(['A1']);
1300 + assertConsoleErrorDev([
1301 + 'A component was suspended by an uncached promise. ' +
1302 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1303 + 'except via a Suspense-compatible library or framework.\n' +
1304 + (gate('enableOwnerStacks')
1305 + ? ''
1306 + : ' in Async (at **)\n' + ' in Suspense (at **)\n') +
1307 + ' in App (at **)',
1308 + 'A component was suspended by an uncached promise. ' +
1309 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1310 + 'except via a Suspense-compatible library or framework.\n' +
1311 + (gate('enableOwnerStacks')
1312 + ? ''
1313 + : ' in Async (at **)\n' + ' in Suspense (at **)\n') +
1314 + ' in App (at **)',
1315 + ]);
1316 expect(root).toMatchRenderedOutput('A1');
1317 });
1318
@@ -1231,7 +1342,12 @@ describe('ReactUse', () => {
1342 });
1343 });
1344 assertLog(['Async text requested [Hi]']);
1234 -
1345 + assertConsoleErrorDev([
1346 + 'async/await is not yet supported in Client Components, only Server Components. ' +
1347 + "This error is often caused by accidentally adding `'use client'` " +
1348 + 'to a module that was originally written for the server.\n' +
1349 + ' in App (at **)',
1350 + ]);
1351 await act(() => resolveTextRequests('Hi'));
1352 assertLog([
1353 // TODO: We shouldn't have to replay the function body again. Skip
@@ -1239,6 +1355,12 @@ describe('ReactUse', () => {
1355 'Async text requested [Hi]',
1356 'Hi',
1357 ]);
1358 + assertConsoleErrorDev([
1359 + 'A component was suspended by an uncached promise. ' +
1360 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1361 + 'except via a Suspense-compatible library or framework.\n' +
1362 + ' in App (at **)',
1363 + ]);
1364 expect(root).toMatchRenderedOutput('Hi');
1365 });
1366
@@ -1268,6 +1390,12 @@ describe('ReactUse', () => {
1390 'Async text requested [Hi]',
1391 'Hi',
1392 ]);
1393 + assertConsoleErrorDev([
1394 + 'A component was suspended by an uncached promise. ' +
1395 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1396 + 'except via a Suspense-compatible library or framework.\n' +
1397 + ' in App (at **)',
1398 + ]);
1399 expect(root).toMatchRenderedOutput('Hi');
1400 });
1401
@@ -1314,6 +1442,16 @@ describe('ReactUse', () => {
1442 });
1443 });
1444 assertLog(['A', 'Mount: A']);
1445 + assertConsoleErrorDev([
1446 + 'async/await is not yet supported in Client Components, only Server Components. ' +
1447 + "This error is often caused by accidentally adding `'use client'` " +
1448 + 'to a module that was originally written for the server.\n' +
1449 + ' in App (at **)',
1450 + 'A component was suspended by an uncached promise. ' +
1451 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1452 + 'except via a Suspense-compatible library or framework.\n' +
1453 + ' in App (at **)',
1454 + ]);
1455 expect(root).toMatchRenderedOutput('A');
1456
1457 // Update the child's props. It should not remount.
@@ -1323,6 +1461,12 @@ describe('ReactUse', () => {
1461 });
1462 });
1463 assertLog(['B', 'Mount: B']);
1464 + assertConsoleErrorDev([
1465 + 'A component was suspended by an uncached promise. ' +
1466 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1467 + 'except via a Suspense-compatible library or framework.\n' +
1468 + ' in App (at **)',
1469 + ]);
1470 expect(root).toMatchRenderedOutput('B');
1471 });
1472
@@ -1535,6 +1679,16 @@ describe('ReactUse', () => {
1679 });
1680 });
1681 assertLog(['Async']);
1682 + assertConsoleErrorDev([
1683 + 'A component was suspended by an uncached promise. ' +
1684 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1685 + 'except via a Suspense-compatible library or framework.\n' +
1686 + (gate('enableOwnerStacks')
1687 + ? ''
1688 + : ' in **/ReactUse-test.js:**:** (at **)\n' +
1689 + ' in Suspense (at **)\n') +
1690 + ' in App (at **)',
1691 + ]);
1692 expect(root).toMatchRenderedOutput('Async');
1693 expect(ref.current).toBe(asyncInstance);
1694 });
@@ -1563,6 +1717,16 @@ describe('ReactUse', () => {
1717 });
1718 });
1719 assertLog(['Async']);
1720 + assertConsoleErrorDev([
1721 + 'A component was suspended by an uncached promise. ' +
1722 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1723 + 'except via a Suspense-compatible library or framework.\n' +
1724 + (gate('enableOwnerStacks')
1725 + ? ''
1726 + : ' in **/ReactUse-test.js:**:** (at **)\n' +
1727 + ' in Suspense (at **)\n') +
1728 + ' in App (at **)',
1729 + ]);
1730 expect(root).toMatchRenderedOutput('Async');
1731
1732 // Update to the same value
@@ -1582,6 +1746,16 @@ describe('ReactUse', () => {
1746 });
1747 });
1748 assertLog(['Async!']);
1749 + assertConsoleErrorDev([
1750 + 'A component was suspended by an uncached promise. ' +
1751 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1752 + 'except via a Suspense-compatible library or framework.\n' +
1753 + (gate('enableOwnerStacks')
1754 + ? ''
1755 + : ' in **/ReactUse-test.js:**:** (at **)\n' +
1756 + ' in Suspense (at **)\n') +
1757 + ' in App (at **)',
1758 + ]);
1759 expect(root).toMatchRenderedOutput('Async!');
1760 });
1761
@@ -1631,6 +1805,41 @@ describe('ReactUse', () => {
1805 });
1806 });
1807 assertLog(['Async (function component)', 'Async (memo component)']);
1808 + assertConsoleErrorDev([
1809 + 'ContextProvider uses the legacy childContextTypes API which will soon be removed. ' +
1810 + 'Use React.createContext() instead. (https://react.dev/link/legacy-context)\n' +
1811 + (gate('enableOwnerStacks') ? '' : ' in ContextProvider (at **)\n') +
1812 + ' in App (at **)',
1813 + 'Async uses the legacy contextTypes API which will be removed soon. ' +
1814 + 'Use React.createContext() with React.useContext() instead. (https://react.dev/link/legacy-context)\n' +
1815 + (gate('enableOwnerStacks')
1816 + ? ''
1817 + : ' in Async (at **)\n' +
1818 + ' in div (at **)\n' +
1819 + ' in Suspense (at **)\n' +
1820 + ' in ContextProvider (at **)\n') +
1821 + ' in App (at **)',
1822 + 'A component was suspended by an uncached promise. ' +
1823 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1824 + 'except via a Suspense-compatible library or framework.\n' +
1825 + (gate('enableOwnerStacks')
1826 + ? ''
1827 + : ' in Async (at **)\n' +
1828 + ' in div (at **)\n' +
1829 + ' in Suspense (at **)\n' +
1830 + ' in ContextProvider (at **)\n') +
1831 + ' in App (at **)',
1832 + 'A component was suspended by an uncached promise. ' +
1833 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
1834 + 'except via a Suspense-compatible library or framework.\n' +
1835 + (gate('enableOwnerStacks')
1836 + ? ''
1837 + : ' in Async (at **)\n' +
1838 + ' in div (at **)\n' +
1839 + ' in Suspense (at **)\n' +
1840 + ' in ContextProvider (at **)\n') +
1841 + ' in App (at **)',
1842 + ]);
1843 expect(root).toMatchRenderedOutput(
1844 <>
1845 <div>Async (function component)</div>
@@ -1698,19 +1907,19 @@ describe('ReactUse', () => {
1907 }
1908
1909 const root = ReactNoop.createRoot();
1701 - await expect(async () => {
1702 - await act(() => {
1703 - root.render(
1704 - <ErrorBoundary>
1705 - <AsyncClientComponent />
1706 - </ErrorBoundary>,
1707 - );
1708 - });
1709 - }).toErrorDev([
1710 - 'async/await is not yet supported in Client Components, only ' +
1711 - 'Server Components. This error is often caused by accidentally ' +
1712 - "adding `'use client'` to a module that was originally written " +
1713 - 'for the server.',
1910 + await act(async () => {
1911 + root.render(
1912 + <ErrorBoundary>
1913 + <AsyncClientComponent />
1914 + </ErrorBoundary>,
1915 + );
1916 + });
1917 + assertConsoleErrorDev([
1918 + 'async/await is not yet supported in Client Components, only Server Components. ' +
1919 + "This error is often caused by accidentally adding `'use client'` " +
1920 + 'to a module that was originally written for the server.\n' +
1921 + ' in AsyncClientComponent (at **)' +
1922 + (gate('enableOwnerStacks') ? '' : '\n in ErrorBoundary (at **)'),
1923 ]);
1924 assertLog([
1925 'async/await is not yet supported in Client Components, only Server ' +
@@ -1750,19 +1959,19 @@ describe('ReactUse', () => {
1959 }
1960
1961 const root = ReactNoop.createRoot();
1753 - await expect(async () => {
1754 - await act(() => {
1755 - root.render(
1756 - <ErrorBoundary>
1757 - <AsyncClientComponent />
1758 - </ErrorBoundary>,
1759 - );
1760 - });
1761 - }).toErrorDev([
1762 - 'async/await is not yet supported in Client Components, only ' +
1763 - 'Server Components. This error is often caused by accidentally ' +
1764 - "adding `'use client'` to a module that was originally written " +
1765 - 'for the server.',
1962 + await act(async () => {
1963 + root.render(
1964 + <ErrorBoundary>
1965 + <AsyncClientComponent />
1966 + </ErrorBoundary>,
1967 + );
1968 + });
1969 + assertConsoleErrorDev([
1970 + 'async/await is not yet supported in Client Components, only Server Components. ' +
1971 + "This error is often caused by accidentally adding `'use client'` " +
1972 + 'to a module that was originally written for the server.\n' +
1973 + ' in AsyncClientComponent (at **)' +
1974 + (gate('enableOwnerStacks') ? '' : '\n in ErrorBoundary (at **)'),
1975 ]);
1976 assertLog([
1977 'async/await is not yet supported in Client Components, only Server ' +
@@ -1792,25 +2001,25 @@ describe('ReactUse', () => {
2001 }
2002
2003 const root = ReactNoop.createRoot();
1795 - await expect(async () => {
1796 - await act(() => {
1797 - startTransition(() => {
1798 - root.render(<AsyncClientComponent />);
1799 - });
2004 + await act(() => {
2005 + startTransition(() => {
2006 + root.render(<AsyncClientComponent />);
2007 });
1801 - }).toErrorDev([
2008 + });
2009 + assertConsoleErrorDev([
2010 // Note: This used to log a different warning about not using hooks
2011 // inside async components, like we do on the server. Since then, we
2012 // decided to warn for _any_ async client component regardless of
2013 // whether the update is sync. But if we ever add back support for async
2014 // client components, we should add back the hook warning.
1807 - 'async/await is not yet supported in Client Components, only Server ' +
1808 - 'Components. This error is often caused by accidentally adding ' +
1809 - "`'use client'` to a module that was originally written for " +
1810 - 'the server.',
1811 - 'A component was suspended by an uncached promise. Creating ' +
1812 - 'promises inside a Client Component or hook is not yet ' +
1813 - 'supported, except via a Suspense-compatible library or framework.',
2015 + 'async/await is not yet supported in Client Components, only Server Components. ' +
2016 + "This error is often caused by accidentally adding `'use client'` " +
2017 + 'to a module that was originally written for the server.\n' +
2018 + ' in AsyncClientComponent (at **)',
2019 + 'A component was suspended by an uncached promise. ' +
2020 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
2021 + 'except via a Suspense-compatible library or framework.\n' +
2022 + ' in AsyncClientComponent (at **)',
2023 ]);
2024 },
2025 );
@@ -1824,28 +2033,29 @@ describe('ReactUse', () => {
2033 }
2034
2035 const root = ReactNoop.createRoot();
1827 - await expect(async () => {
1828 - await act(() => {
1829 - startTransition(() => {
1830 - root.render(<AsyncClientComponent />);
1831 - });
2036 + await act(() => {
2037 + startTransition(() => {
2038 + root.render(<AsyncClientComponent />);
2039 });
1833 - }).toErrorDev([
2040 + });
2041 + assertConsoleErrorDev([
2042 // Note: This used to log a different warning about not using hooks
2043 // inside async components, like we do on the server. Since then, we
2044 // decided to warn for _any_ async client component regardless of
2045 // whether the update is sync. But if we ever add back support for async
2046 // client components, we should add back the hook warning.
1839 - 'async/await is not yet supported in Client Components, only Server ' +
1840 - 'Components. This error is often caused by accidentally adding ' +
1841 - "`'use client'` to a module that was originally written for " +
1842 - 'the server.',
1843 - 'A component was suspended by an uncached promise. Creating ' +
1844 - 'promises inside a Client Component or hook is not yet ' +
1845 - 'supported, except via a Suspense-compatible library or framework.',
1846 - 'A component was suspended by an uncached promise. Creating ' +
1847 - 'promises inside a Client Component or hook is not yet ' +
1848 - 'supported, except via a Suspense-compatible library or framework.',
2047 + 'async/await is not yet supported in Client Components, only Server Components. ' +
2048 + "This error is often caused by accidentally adding `'use client'` " +
2049 + 'to a module that was originally written for the server.\n' +
2050 + ' in AsyncClientComponent (at **)',
2051 + 'A component was suspended by an uncached promise. ' +
2052 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
2053 + 'except via a Suspense-compatible library or framework.\n' +
2054 + ' in AsyncClientComponent (at **)',
2055 + 'A component was suspended by an uncached promise. ' +
2056 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
2057 + 'except via a Suspense-compatible library or framework.\n' +
2058 + ' in AsyncClientComponent (at **)',
2059 ]);
2060 });
2061
@@ -1863,38 +2073,41 @@ describe('ReactUse', () => {
2073 }
2074
2075 const root = ReactNoop.createRoot();
1866 - await expect(async () => {
1867 - await act(() => {
1868 - startTransition(() => {
1869 - root.render(<App />);
1870 - });
2076 + await act(() => {
2077 + startTransition(() => {
2078 + root.render(<App />);
2079 });
1872 - }).toErrorDev([
1873 - 'async/await is not yet supported in Client Components, only ' +
1874 - 'Server Components. This error is often caused by accidentally ' +
1875 - "adding `'use client'` to a module that was originally written " +
1876 - 'for the server.',
2080 + });
2081 + assertConsoleErrorDev([
2082 + 'async/await is not yet supported in Client Components, only Server Components. ' +
2083 + "This error is often caused by accidentally adding `'use client'` " +
2084 + 'to a module that was originally written for the server.\n' +
2085 + ' in App (at **)',
2086 ]);
2087 assertLog(['Async text requested [Hi]']);
2088
1880 - await expect(async () => {
1881 - await act(() => resolveTextRequests('Hi'));
1882 - }).toErrorDev([
2089 + await act(() => resolveTextRequests('Hi'));
2090 + assertConsoleErrorDev([
2091 // We get this warning because the generator's promise themselves are not cached.
1884 - 'A component was suspended by an uncached promise. Creating ' +
1885 - 'promises inside a Client Component or hook is not yet ' +
1886 - 'supported, except via a Suspense-compatible library or framework.',
2092 + 'A component was suspended by an uncached promise. ' +
2093 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
2094 + 'except via a Suspense-compatible library or framework.\n' +
2095 + ' in App (at **)',
2096 ]);
2097
2098 assertLog(['Async text requested [World]']);
2099
1891 - if (gate('enableSiblingPrerendering')) {
1892 - await expect(async () => {
1893 - await act(() => resolveTextRequests('World'));
1894 - }).toErrorDev(['A component was suspended by an uncached promise.']);
1895 - } else {
1896 - await act(() => resolveTextRequests('World'));
1897 - }
2100 + await act(() => resolveTextRequests('World'));
2101 + assertConsoleErrorDev(
2102 + gate('enableSiblingPrerendering')
2103 + ? [
2104 + 'A component was suspended by an uncached promise. ' +
2105 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
2106 + 'except via a Suspense-compatible library or framework.\n' +
2107 + ' in App (at **)',
2108 + ]
2109 + : [],
2110 + );
2111
2112 assertLog(['Hi', 'World']);
2113 expect(root).toMatchRenderedOutput('Hi World');
@@ -1928,24 +2141,30 @@ describe('ReactUse', () => {
2141 });
2142 assertLog(['Async text requested [Hi]']);
2143
1931 - await expect(async () => {
1932 - await act(() => resolveTextRequests('Hi'));
1933 - }).toErrorDev([
2144 + await act(() => resolveTextRequests('Hi'));
2145 + assertConsoleErrorDev([
2146 // We get this warning because the generator's promise themselves are not cached.
1935 - 'A component was suspended by an uncached promise. Creating ' +
1936 - 'promises inside a Client Component or hook is not yet ' +
1937 - 'supported, except via a Suspense-compatible library or framework.',
2147 + 'A component was suspended by an uncached promise. ' +
2148 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
2149 + 'except via a Suspense-compatible library or framework.\n' +
2150 + ' in div (at **)\n' +
2151 + ' in App (at **)',
2152 ]);
2153
2154 assertLog(['Async text requested [World]']);
2155
1942 - if (gate('enableSiblingPrerendering')) {
1943 - await expect(async () => {
1944 - await act(() => resolveTextRequests('World'));
1945 - }).toErrorDev(['A component was suspended by an uncached promise.']);
1946 - } else {
1947 - await act(() => resolveTextRequests('World'));
1948 - }
2156 + await act(() => resolveTextRequests('World'));
2157 + assertConsoleErrorDev(
2158 + gate('enableSiblingPrerendering')
2159 + ? [
2160 + 'A component was suspended by an uncached promise. ' +
2161 + 'Creating promises inside a Client Component or hook is not yet supported, ' +
2162 + 'except via a Suspense-compatible library or framework.\n' +
2163 + ' in div (at **)\n' +
2164 + ' in App (at **)',
2165 + ]
2166 + : [],
2167 + );
2168
2169 assertLog(['Hi', 'World']);
2170 expect(root).toMatchRenderedOutput(<div>Hi World</div>);