Skip to content

Commit 206934f

Browse files
authored
Convert ReactDOMOption to createRoot (#28002)
1 parent 29fbf6f commit 206934f

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

packages/react-dom/src/__tests__/ReactDOMOption-test.js

+43-14
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@
1111

1212
describe('ReactDOMOption', () => {
1313
let React;
14-
let ReactDOM;
14+
let ReactDOMClient;
1515
let ReactDOMServer;
1616
let ReactTestUtils;
17+
let act;
1718

1819
beforeEach(() => {
1920
jest.resetModules();
2021
React = require('react');
21-
ReactDOM = require('react-dom');
22+
ReactDOMClient = require('react-dom/client');
2223
ReactDOMServer = require('react-dom/server');
2324
ReactTestUtils = require('react-dom/test-utils');
25+
act = require('internal-test-utils').act;
2426
});
2527

2628
it('should flatten children to a string', () => {
@@ -182,19 +184,28 @@ describe('ReactDOMOption', () => {
182184
expect(node.innerHTML).toBe('foobar');
183185
});
184186

185-
it('should set attribute for empty value', () => {
187+
it('should set attribute for empty value', async () => {
186188
const container = document.createElement('div');
187-
const option = ReactDOM.render(<option value="" />, container);
189+
const root = ReactDOMClient.createRoot(container);
190+
let option;
191+
await act(() => {
192+
root.render(<option value="" />);
193+
});
194+
option = container.firstChild;
188195
expect(option.hasAttribute('value')).toBe(true);
189196
expect(option.getAttribute('value')).toBe('');
190197

191-
ReactDOM.render(<option value="lava" />, container);
198+
await act(() => {
199+
root.render(<option value="lava" />);
200+
});
201+
option = container.firstChild;
192202
expect(option.hasAttribute('value')).toBe(true);
193203
expect(option.getAttribute('value')).toBe('lava');
194204
});
195205

196-
it('should allow ignoring `value` on option', () => {
206+
it('should allow ignoring `value` on option', async () => {
197207
const a = 'a';
208+
let node;
198209
const stub = (
199210
<select value="giraffe" onChange={() => {}}>
200211
<option>monkey</option>
@@ -204,15 +215,22 @@ describe('ReactDOMOption', () => {
204215
);
205216
const options = stub.props.children;
206217
const container = document.createElement('div');
207-
const node = ReactDOM.render(stub, container);
218+
const root = ReactDOMClient.createRoot(container);
219+
await act(() => {
220+
root.render(stub);
221+
});
222+
node = container.firstChild;
208223

209224
expect(node.selectedIndex).toBe(1);
210225

211-
ReactDOM.render(<select value="gorilla">{options}</select>, container);
226+
await act(() => {
227+
root.render(<select value="gorilla">{options}</select>);
228+
});
229+
node = container.firstChild;
212230
expect(node.selectedIndex).toEqual(2);
213231
});
214232

215-
it('generates a warning and hydration error when an invalid nested tag is used as a child', () => {
233+
it('generates a warning and hydration error when an invalid nested tag is used as a child', async () => {
216234
const ref = React.createRef();
217235
const children = (
218236
<select readOnly={true} value="bar">
@@ -229,16 +247,27 @@ describe('ReactDOMOption', () => {
229247
expect(container.firstChild.getAttribute('value')).toBe(null);
230248
expect(container.firstChild.getAttribute('defaultValue')).toBe(null);
231249

232-
const option = container.firstChild.firstChild;
250+
let option = container.firstChild.firstChild;
233251
expect(option.nodeName).toBe('OPTION');
234252

235253
expect(option.textContent).toBe('BarFooBaz');
236254
expect(option.selected).toBe(true);
237255

238-
expect(() => ReactDOM.hydrate(children, container)).toErrorDev([
239-
'Text content did not match. Server: "FooBaz" Client: "Foo"',
240-
'validateDOMNesting(...): <div> cannot appear as a child of <option>.',
241-
]);
256+
await expect(async () => {
257+
await act(async () => {
258+
ReactDOMClient.hydrateRoot(container, children, {
259+
onRecoverableError: () => {},
260+
});
261+
});
262+
}).toErrorDev(
263+
[
264+
'Warning: Text content did not match. Server: "FooBaz" Client: "Foo"',
265+
'Warning: An error occurred during hydration. The server HTML was replaced with client content in <div>',
266+
'Warning: validateDOMNesting(...): <div> cannot appear as a child of <option>',
267+
],
268+
{withoutStack: 1},
269+
);
270+
option = container.firstChild.firstChild;
242271

243272
expect(option.textContent).toBe('BarFooBaz');
244273
expect(option.selected).toBe(true);

scripts/jest/matchers/toWarnDev.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ const createMatcherFor = (consoleMethod, matcherName) =>
8686
// doesn't match the number of arguments.
8787
// We'll fail the test if it happens.
8888
let argIndex = 0;
89-
format.replace(/%s/g, () => argIndex++);
89+
// console.* could have been called with a non-string e.g. `console.error(new Error())`
90+
String(format).replace(/%s/g, () => argIndex++);
9091
if (argIndex !== args.length) {
9192
lastWarningWithMismatchingFormat = {
9293
format,

0 commit comments

Comments
 (0)