Skip to content

Commit 5b3cf78

Browse files
author
Sebastian Silbermann
committed
Remove usage of ReactTestUtils from ReactFunctionComponent
1 parent adadb81 commit 5b3cf78

File tree

1 file changed

+137
-64
lines changed

1 file changed

+137
-64
lines changed

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

Lines changed: 137 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
let PropTypes;
1313
let React;
1414
let ReactDOMClient;
15-
let ReactTestUtils;
1615
let act;
1716

1817
function FunctionComponent(props) {
@@ -26,7 +25,6 @@ describe('ReactFunctionComponent', () => {
2625
React = require('react');
2726
ReactDOMClient = require('react-dom/client');
2827
act = require('internal-test-utils').act;
29-
ReactTestUtils = require('react-dom/test-utils');
3028
});
3129

3230
it('should render stateless component', async () => {
@@ -161,25 +159,33 @@ describe('ReactFunctionComponent', () => {
161159
);
162160
});
163161

164-
it('should not throw when stateless component returns undefined', () => {
162+
it('should not throw when stateless component returns undefined', async () => {
165163
function NotAComponent() {}
166-
expect(function () {
167-
ReactTestUtils.renderIntoDocument(
168-
<div>
169-
<NotAComponent />
170-
</div>,
171-
);
172-
}).not.toThrowError();
164+
const container = document.createElement('div');
165+
const root = ReactDOMClient.createRoot(container);
166+
await expect(
167+
act(() => {
168+
root.render(
169+
<div>
170+
<NotAComponent />
171+
</div>,
172+
);
173+
}),
174+
).resolves.not.toThrowError();
173175
});
174176

175-
it('should throw on string refs in pure functions', () => {
177+
it('should throw on string refs in pure functions', async () => {
176178
function Child() {
177179
return <div ref="me" />;
178180
}
179181

180-
expect(function () {
181-
ReactTestUtils.renderIntoDocument(<Child test="test" />);
182-
}).toThrowError(
182+
const container = document.createElement('div');
183+
const root = ReactDOMClient.createRoot(container);
184+
await expect(
185+
act(() => {
186+
root.render(<Child test="test" />);
187+
}),
188+
).rejects.toThrowError(
183189
__DEV__
184190
? 'Function components cannot have string refs. We recommend using useRef() instead.'
185191
: // It happens because we don't save _owner in production for
@@ -193,7 +199,7 @@ describe('ReactFunctionComponent', () => {
193199
);
194200
});
195201

196-
it('should warn when given a string ref', () => {
202+
it('should warn when given a string ref', async () => {
197203
function Indirection(props) {
198204
return <div>{props.children}</div>;
199205
}
@@ -208,9 +214,13 @@ describe('ReactFunctionComponent', () => {
208214
}
209215
}
210216

211-
expect(() =>
212-
ReactTestUtils.renderIntoDocument(<ParentUsingStringRef />),
213-
).toErrorDev(
217+
await expect(async () => {
218+
const container = document.createElement('div');
219+
const root = ReactDOMClient.createRoot(container);
220+
await act(() => {
221+
root.render(<ParentUsingStringRef />);
222+
});
223+
}).toErrorDev(
214224
'Warning: Function components cannot be given refs. ' +
215225
'Attempts to access this ref will fail. ' +
216226
'Did you mean to use React.forwardRef()?\n\n' +
@@ -222,11 +232,14 @@ describe('ReactFunctionComponent', () => {
222232
' in ParentUsingStringRef (at **)',
223233
);
224234

225-
// No additional warnings should be logged
226-
ReactTestUtils.renderIntoDocument(<ParentUsingStringRef />);
235+
const container = document.createElement('div');
236+
const root = ReactDOMClient.createRoot(container);
237+
await act(() => {
238+
root.render(<ParentUsingStringRef />);
239+
});
227240
});
228241

229-
it('should warn when given a function ref', () => {
242+
it('should warn when given a function ref', async () => {
230243
function Indirection(props) {
231244
return <div>{props.children}</div>;
232245
}
@@ -246,9 +259,13 @@ describe('ReactFunctionComponent', () => {
246259
}
247260
}
248261

249-
expect(() =>
250-
ReactTestUtils.renderIntoDocument(<ParentUsingFunctionRef />),
251-
).toErrorDev(
262+
await expect(async () => {
263+
const container = document.createElement('div');
264+
const root = ReactDOMClient.createRoot(container);
265+
await act(() => {
266+
root.render(<ParentUsingFunctionRef />);
267+
});
268+
}).toErrorDev(
252269
'Warning: Function components cannot be given refs. ' +
253270
'Attempts to access this ref will fail. ' +
254271
'Did you mean to use React.forwardRef()?\n\n' +
@@ -260,11 +277,14 @@ describe('ReactFunctionComponent', () => {
260277
' in ParentUsingFunctionRef (at **)',
261278
);
262279

263-
// No additional warnings should be logged
264-
ReactTestUtils.renderIntoDocument(<ParentUsingFunctionRef />);
280+
const container = document.createElement('div');
281+
const root = ReactDOMClient.createRoot(container);
282+
await act(() => {
283+
root.render(<ParentUsingFunctionRef />);
284+
});
265285
});
266286

267-
it('deduplicates ref warnings based on element or owner', () => {
287+
it('deduplicates ref warnings based on element or owner', async () => {
268288
// When owner uses JSX, we can use exact line location to dedupe warnings
269289
class AnonymousParentUsingJSX extends React.Component {
270290
render() {
@@ -274,15 +294,24 @@ describe('ReactFunctionComponent', () => {
274294

275295
let instance1;
276296

277-
expect(() => {
278-
instance1 = ReactTestUtils.renderIntoDocument(
279-
<AnonymousParentUsingJSX />,
280-
);
297+
await expect(async () => {
298+
const container = document.createElement('div');
299+
const root = ReactDOMClient.createRoot(container);
300+
301+
await act(() => {
302+
root.render(
303+
<AnonymousParentUsingJSX ref={current => (instance1 = current)} />,
304+
);
305+
});
281306
}).toErrorDev('Warning: Function components cannot be given refs.');
282307
// Should be deduped (offending element is on the same line):
283308
instance1.forceUpdate();
284-
// Should also be deduped (offending element is on the same line):
285-
ReactTestUtils.renderIntoDocument(<AnonymousParentUsingJSX />);
309+
let container = document.createElement('div');
310+
let root = ReactDOMClient.createRoot(container);
311+
312+
await act(() => {
313+
root.render(<AnonymousParentUsingJSX />);
314+
});
286315

287316
// When owner doesn't use JSX, and is anonymous, we warn once per internal instance.
288317
class AnonymousParentNotUsingJSX extends React.Component {
@@ -295,15 +324,22 @@ describe('ReactFunctionComponent', () => {
295324
}
296325

297326
let instance2;
298-
expect(() => {
299-
instance2 = ReactTestUtils.renderIntoDocument(
300-
<AnonymousParentNotUsingJSX />,
301-
);
327+
await expect(async () => {
328+
container = document.createElement('div');
329+
root = ReactDOMClient.createRoot(container);
330+
await act(() => {
331+
root.render(
332+
<AnonymousParentNotUsingJSX ref={current => (instance2 = current)} />,
333+
);
334+
});
302335
}).toErrorDev('Warning: Function components cannot be given refs.');
303336
// Should be deduped (same internal instance, no additional warnings)
304337
instance2.forceUpdate();
305-
// Could not be differentiated (since owner is anonymous and no source location)
306-
ReactTestUtils.renderIntoDocument(<AnonymousParentNotUsingJSX />);
338+
container = document.createElement('div');
339+
root = ReactDOMClient.createRoot(container);
340+
await act(() => {
341+
root.render(<AnonymousParentNotUsingJSX />);
342+
});
307343

308344
// When owner doesn't use JSX, but is named, we warn once per owner name
309345
class NamedParentNotUsingJSX extends React.Component {
@@ -315,19 +351,28 @@ describe('ReactFunctionComponent', () => {
315351
}
316352
}
317353
let instance3;
318-
expect(() => {
319-
instance3 = ReactTestUtils.renderIntoDocument(<NamedParentNotUsingJSX />);
354+
await expect(async () => {
355+
container = document.createElement('div');
356+
root = ReactDOMClient.createRoot(container);
357+
await act(() => {
358+
root.render(
359+
<NamedParentNotUsingJSX ref={current => (instance3 = current)} />,
360+
);
361+
});
320362
}).toErrorDev('Warning: Function components cannot be given refs.');
321363
// Should be deduped (same owner name, no additional warnings):
322364
instance3.forceUpdate();
323-
// Should also be deduped (same owner name, no additional warnings):
324-
ReactTestUtils.renderIntoDocument(<NamedParentNotUsingJSX />);
365+
container = document.createElement('div');
366+
root = ReactDOMClient.createRoot(container);
367+
await act(() => {
368+
root.render(<NamedParentNotUsingJSX />);
369+
});
325370
});
326371

327372
// This guards against a regression caused by clearing the current debug fiber.
328373
// https://github.com/facebook/react/issues/10831
329374
// @gate !disableLegacyContext || !__DEV__
330-
it('should warn when giving a function ref with context', () => {
375+
it('should warn when giving a function ref with context', async () => {
331376
function Child() {
332377
return null;
333378
}
@@ -349,7 +394,13 @@ describe('ReactFunctionComponent', () => {
349394
}
350395
}
351396

352-
expect(() => ReactTestUtils.renderIntoDocument(<Parent />)).toErrorDev(
397+
await expect(async () => {
398+
const container = document.createElement('div');
399+
const root = ReactDOMClient.createRoot(container);
400+
await act(() => {
401+
root.render(<Parent />);
402+
});
403+
}).toErrorDev(
353404
'Warning: Function components cannot be given refs. ' +
354405
'Attempts to access this ref will fail. ' +
355406
'Did you mean to use React.forwardRef()?\n\n' +
@@ -360,36 +411,40 @@ describe('ReactFunctionComponent', () => {
360411
);
361412
});
362413

363-
it('should provide a null ref', () => {
364-
function Child() {
365-
return <div />;
366-
}
367-
368-
const comp = ReactTestUtils.renderIntoDocument(<Child />);
369-
expect(comp).toBe(null);
370-
});
371-
372-
it('should use correct name in key warning', () => {
414+
it('should use correct name in key warning', async () => {
373415
function Child() {
374416
return <div>{[<span />]}</div>;
375417
}
376418

377-
expect(() => ReactTestUtils.renderIntoDocument(<Child />)).toErrorDev(
419+
await expect(async () => {
420+
const container = document.createElement('div');
421+
const root = ReactDOMClient.createRoot(container);
422+
await act(() => {
423+
root.render(<Child />);
424+
});
425+
}).toErrorDev(
378426
'Each child in a list should have a unique "key" prop.\n\n' +
379427
'Check the render method of `Child`.',
380428
);
381429
});
382430

383431
// TODO: change this test after we deprecate default props support
384432
// for function components
385-
it('should support default props and prop types', () => {
433+
it('should support default props and prop types', async () => {
386434
function Child(props) {
387435
return <div>{props.test}</div>;
388436
}
389437
Child.defaultProps = {test: 2};
390438
Child.propTypes = {test: PropTypes.string};
391439

392-
expect(() => ReactTestUtils.renderIntoDocument(<Child />)).toErrorDev([
440+
await expect(async () => {
441+
const container = document.createElement('div');
442+
const root = ReactDOMClient.createRoot(container);
443+
444+
await act(() => {
445+
root.render(<Child />);
446+
});
447+
}).toErrorDev([
393448
'Warning: Child: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.',
394449
'Warning: Failed prop type: Invalid prop `test` of type `number` ' +
395450
'supplied to `Child`, expected `string`.\n' +
@@ -427,28 +482,46 @@ describe('ReactFunctionComponent', () => {
427482
expect(el.textContent).toBe('en');
428483
});
429484

430-
it('should work with arrow functions', () => {
485+
it('should work with arrow functions', async () => {
431486
let Child = function () {
432487
return <div />;
433488
};
434489
// Will create a new bound function without a prototype, much like a native
435490
// arrow function.
436491
Child = Child.bind(this);
437492

438-
expect(() => ReactTestUtils.renderIntoDocument(<Child />)).not.toThrow();
493+
await expect(async () => {
494+
const container = document.createElement('div');
495+
const root = ReactDOMClient.createRoot(container);
496+
await act(() => {
497+
root.render(<Child />);
498+
});
499+
}).not.toThrow();
439500
});
440501

441-
it('should allow simple functions to return null', () => {
502+
it('should allow simple functions to return null', async () => {
442503
const Child = function () {
443504
return null;
444505
};
445-
expect(() => ReactTestUtils.renderIntoDocument(<Child />)).not.toThrow();
506+
await expect(async () => {
507+
const container = document.createElement('div');
508+
const root = ReactDOMClient.createRoot(container);
509+
await act(() => {
510+
root.render(<Child />);
511+
});
512+
}).not.toThrow();
446513
});
447514

448-
it('should allow simple functions to return false', () => {
515+
it('should allow simple functions to return false', async () => {
449516
function Child() {
450517
return false;
451518
}
452-
expect(() => ReactTestUtils.renderIntoDocument(<Child />)).not.toThrow();
519+
const container = document.createElement('div');
520+
const root = ReactDOMClient.createRoot(container);
521+
await expect(
522+
act(() => {
523+
root.render(<Child />);
524+
}),
525+
).resolves.not.toThrow();
453526
});
454527
});

0 commit comments

Comments
 (0)