Skip to content

Commit

Permalink
Add a unit test for deduped owner objects
Browse files Browse the repository at this point in the history
  • Loading branch information
unstubbable committed Sep 23, 2024
1 parent 68886e8 commit fcb0bf2
Showing 1 changed file with 77 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,83 @@ describe('ReactFlightDOMBrowser', () => {
expect(container.innerHTML).toBe('<div></div>');
});

it('should handle references to deduped owner objects', async () => {
// This is replicating React components as generated by @svgr/webpack:
let path1: React.ReactNode;
let path2: React.ReactNode;

function Svg1() {
return ReactServer.createElement(
'svg',
{id: '1'},
path1 || (path1 = ReactServer.createElement('path', {})),
);
}

function Svg2() {
return ReactServer.createElement(
'svg',
{id: '2'},
path2 || (path2 = ReactServer.createElement('path', {})),
);
}

function Server() {
return ReactServer.createElement(
ReactServer.Fragment,
{},
ReactServer.createElement(Svg1),
ReactServer.createElement(Svg2),
);
}

let stream = await serverAct(() =>
ReactServerDOMServer.renderToReadableStream(<Server />, webpackMap),
);

function ClientRoot({response}) {
return use(response);
}

let response = ReactServerDOMClient.createFromReadableStream(stream);
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);

await act(() => {
root.render(<ClientRoot response={response} />);
});

const expectedHtml =
'<svg id="1"><path></path></svg><svg id="2"><path></path></svg>';

expect(container.innerHTML).toBe(expectedHtml);

// Render a second time:

// Assigning the path elements to variables in module scope (here simulated
// with the test's function scope), and rendering a second time, prevents
// the owner of the path elements (i.e. Svg1/Svg2) to be deduped. The owner
// of the path in Svg1 is fully inlined. The owner of the owner of the path
// in Svg2 is Server, which is deduped and replaced with a reference to the
// owner of the owner of the path in Svg1. This nested owner is actually
// Server from the previous render pass, which is kinda broken and libaries
// probably shouldn't generate code like this. This reference can only be
// resolved properly if owners are specifically handled when resolving
// outlined models.

stream = await serverAct(() =>
ReactServerDOMServer.renderToReadableStream(<Server />, webpackMap),
);

response = ReactServerDOMClient.createFromReadableStream(stream);

await act(() => {
root.render(<ClientRoot response={response} />);
});

expect(container.innerHTML).toBe(expectedHtml);
});

it('should progressively reveal server components', async () => {
let reportedErrors = [];

Expand Down

0 comments on commit fcb0bf2

Please sign in to comment.