Skip to content

Commit

Permalink
bigint test for title children
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Silbermann committed Feb 18, 2024
1 parent d42a3ca commit 1a425e3
Showing 1 changed file with 112 additions and 2 deletions.
114 changes: 112 additions & 2 deletions packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5652,6 +5652,60 @@ describe('ReactDOMFizzServer', () => {
expect(getVisibleChildren(document.head)).toEqual(<title>hello</title>);
});

it('should accept a single number child', async () => {
// a Single number child
function App() {
return (
<head>
<title>4</title>
</head>
);
}

await act(() => {
const {pipe} = renderToPipeableStream(<App />);
pipe(writable);
});
expect(getVisibleChildren(document.head)).toEqual(<title>4</title>);

const errors = [];
ReactDOMClient.hydrateRoot(container, <App />, {
onRecoverableError(error) {
errors.push(error.message);
},
});
await waitForAll([]);
expect(errors).toEqual([]);
expect(getVisibleChildren(document.head)).toEqual(<title>4</title>);
});

it('should accept a single bigint child', async () => {
// a Single number child
function App() {
return (
<head>
<title>5n</title>
</head>
);
}

await act(() => {
const {pipe} = renderToPipeableStream(<App />);
pipe(writable);
});
expect(getVisibleChildren(document.head)).toEqual(<title>5n</title>);

const errors = [];
ReactDOMClient.hydrateRoot(container, <App />, {
onRecoverableError(error) {
errors.push(error.message);
},
});
await waitForAll([]);
expect(errors).toEqual([]);
expect(getVisibleChildren(document.head)).toEqual(<title>5n</title>);
});

it('should accept children array of length 1 containing a string', async () => {
// a Single string child
function App() {
Expand Down Expand Up @@ -5694,7 +5748,7 @@ describe('ReactDOMFizzServer', () => {
pipe(writable);
});
}).toErrorDev([
'React expects the `children` prop of <title> tags to be a string, number, or object with a novel `toString` method but found an Array with length 2 instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be commong to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.',
'React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length 2 instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be commong to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.',
]);

if (gate(flags => flags.enableFloat)) {
Expand Down Expand Up @@ -5754,7 +5808,63 @@ describe('ReactDOMFizzServer', () => {
pipe(writable);
});
}).toErrorDev([
'React expects the `children` prop of <title> tags to be a string, number, or object with a novel `toString` method but found an object that appears to be a React element which never implements a suitable `toString` method. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert children of <title> tags to a single string value which is why rendering React elements is not supported. If the `children` of <title> is a React Component try moving the <title> tag into that component. If the `children` of <title> is some HTML markup change it to be Text only to be valid HTML.',
'React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an object that appears to be a React element which never implements a suitable `toString` method. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert children of <title> tags to a single string value which is why rendering React elements is not supported. If the `children` of <title> is a React Component try moving the <title> tag into that component. If the `children` of <title> is some HTML markup change it to be Text only to be valid HTML.',
]);
} else {
await expect(async () => {
await act(() => {
const {pipe} = renderToPipeableStream(<App />);
pipe(writable);
});
}).toErrorDev([
'A title element received a React element for children. In the browser title Elements can only have Text Nodes as children. If the children being rendered output more than a single text node in aggregate the browser will display markup and comments as text in the title and hydration will likely fail and fall back to client rendering',
]);
}

if (gate(flags => flags.enableFloat)) {
// object titles are toStringed when float is on
expect(getVisibleChildren(document.head)).toEqual(
<title>{'[object Object]'}</title>,
);
} else {
expect(getVisibleChildren(document.head)).toEqual(<title>hello</title>);
}

const errors = [];
ReactDOMClient.hydrateRoot(document.head, <App />, {
onRecoverableError(error) {
errors.push(error.message);
},
});
await waitForAll([]);
expect(errors).toEqual([]);
if (gate(flags => flags.enableFloat)) {
// object titles are toStringed when float is on
expect(getVisibleChildren(document.head)).toEqual(
<title>{'[object Object]'}</title>,
);
} else {
expect(getVisibleChildren(document.head)).toEqual(<title>hello</title>);
}
});

it('should warn in dev if you pass an object that does not implement toString as a child to <title>', async () => {
function App() {
return (
<head>
<title>{{}}</title>
</head>
);
}

if (gate(flags => flags.enableFloat)) {
await expect(async () => {
await act(() => {
const {pipe} = renderToPipeableStream(<App />);
pipe(writable);
});
}).toErrorDev([
'React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an object that does not implement a suitable `toString` method. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert children of <title> tags to a single string value. Using the default `toString` method available on every object is almost certainly an error. Consider whether the `children` of this <title> is an object in error and change it to a string or number value if so. Otherwise implement a `toString` method that React can use to produce a valid <title>.',
]);
} else {
await expect(async () => {
Expand Down

0 comments on commit 1a425e3

Please sign in to comment.