From be76c13fd64f8d1a8020bdaf5a2224a5c6a0aa95 Mon Sep 17 00:00:00 2001 From: Josh Story Date: Fri, 2 Feb 2024 13:58:03 -0800 Subject: [PATCH] Update ReactDOMServerSuspense-test to not use legacy rendering APIs Updates ReactDOMServerSuspense-test to not use legacy rendering APIs. Previously this test was relying on suspending in the legacy renderer to throw during server rendering as well as during client rendering. With the advent of concurrent roots on the client however this doesn't make sense and it only makes sense on the server when using legacy apis like renderToString. I have removed the use of ReactDOMServerIntegrationTestUtils in this test suite and limited the tests to server tests using renderToString to keep as much parity with what was being tested before while dropping anything that no longer makes sense to assert on concurrent client roots --- .../ReactDOMServerSuspense-test.internal.js | 150 +++++++----------- 1 file changed, 56 insertions(+), 94 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMServerSuspense-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerSuspense-test.internal.js index 2a0e1f68a72b2..37da49cca16db 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerSuspense-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerSuspense-test.internal.js @@ -9,44 +9,24 @@ 'use strict'; -const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); - let React; -let ReactDOM; let ReactDOMClient; let ReactDOMServer; -let ReactTestUtils; let act; let SuspenseList; -function initModules() { - // Reset warning cache. - jest.resetModules(); - - React = require('react'); - ReactDOM = require('react-dom'); - ReactDOMClient = require('react-dom/client'); - ReactDOMServer = require('react-dom/server'); - ReactTestUtils = require('react-dom/test-utils'); - act = require('internal-test-utils').act; - if (gate(flags => flags.enableSuspenseList)) { - SuspenseList = React.unstable_SuspenseList; - } - - // Make them available to the helpers. - return { - ReactDOM, - ReactDOMServer, - ReactTestUtils, - }; -} - -const {itThrowsWhenRendering, resetModules, serverRender} = - ReactDOMServerIntegrationUtils(initModules); - describe('ReactDOMServerSuspense', () => { beforeEach(() => { - resetModules(); + // Reset warning cache. + jest.resetModules(); + + React = require('react'); + ReactDOMClient = require('react-dom/client'); + ReactDOMServer = require('react-dom/server'); + act = require('internal-test-utils').act; + if (gate(flags => flags.enableSuspenseList)) { + SuspenseList = React.unstable_SuspenseList; + } }); function Text(props) { @@ -97,42 +77,42 @@ describe('ReactDOMServerSuspense', () => { } it('should render the children when no promise is thrown', async () => { - const c = await serverRender( -
- }> - - -
, + const container = document.createElement('div'); + const html = ReactDOMServer.renderToString( + }> + + , ); - expect(getVisibleChildren(c)).toEqual(
Children
); + container.innerHTML = html; + expect(getVisibleChildren(container)).toEqual(
Children
); }); it('should render the fallback when a promise thrown', async () => { - const c = await serverRender( -
- }> - - -
, + const container = document.createElement('div'); + const html = ReactDOMServer.renderToString( + }> + + , ); - expect(getVisibleChildren(c)).toEqual(
Fallback
); + container.innerHTML = html; + expect(getVisibleChildren(container)).toEqual(
Fallback
); }); it('should work with nested suspense components', async () => { - const c = await serverRender( -
- }> -
- - }> - - -
-
-
, + const container = document.createElement('div'); + const html = ReactDOMServer.renderToString( + }> +
+ + }> + + +
+
, ); + container.innerHTML = html; - expect(getVisibleChildren(c)).toEqual( + expect(getVisibleChildren(container)).toEqual(
Children
Fallback
@@ -152,56 +132,38 @@ describe('ReactDOMServerSuspense', () => { ); - const element = await serverRender(example); - const parent = element.parentNode; - const divA = parent.children[0]; + const container = document.createElement('div'); + const html = ReactDOMServer.renderToString(example); + container.innerHTML = html; + + const divA = container.children[0]; expect(divA.tagName).toBe('DIV'); expect(divA.textContent).toBe('A'); - const divB = parent.children[1]; + const divB = container.children[1]; expect(divB.tagName).toBe('DIV'); expect(divB.textContent).toBe('B'); await act(() => { - ReactDOMClient.hydrateRoot(parent, example); + ReactDOMClient.hydrateRoot(container, example); }); - const parent2 = element.parentNode; - const divA2 = parent2.children[0]; - const divB2 = parent2.children[1]; + const divA2 = container.children[0]; + const divB2 = container.children[1]; expect(divA).toBe(divA2); expect(divB).toBe(divB2); }); - // TODO: Remove this in favor of @gate pragma - if (__EXPERIMENTAL__) { - itThrowsWhenRendering( - 'a suspending component outside a Suspense node', - async render => { - await render( -
- - - -
, - 1, - ); - }, - 'A component suspended while responding to synchronous input.', - ); - - itThrowsWhenRendering( - 'a suspending component without a Suspense above', - async render => { - await render( -
- -
, - 1, - ); - }, - 'A component suspended while responding to synchronous input.', - ); - } + it('it throws when rendering a suspending component outside a Suspense node', async () => { + expect(() => { + ReactDOMServer.renderToString( +
+ + + +
, + ); + }).toThrow('A component suspended while responding to synchronous input.'); + }); it('does not get confused by throwing null', () => { function Bad() {