Skip to content

Commit 9ff8f59

Browse files
eps1lonAndyPengc12
authored andcommitted
Remove usage of ReactTestUtils from ReactContextValidator (facebook#28329)
1 parent 836a025 commit 9ff8f59

File tree

1 file changed

+146
-63
lines changed

1 file changed

+146
-63
lines changed

packages/react/src/__tests__/ReactContextValidator-test.js

Lines changed: 146 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
let PropTypes;
1919
let React;
2020
let ReactDOMClient;
21-
let ReactTestUtils;
2221
let act;
2322

2423
describe('ReactContextValidator', () => {
@@ -28,15 +27,14 @@ describe('ReactContextValidator', () => {
2827
PropTypes = require('prop-types');
2928
React = require('react');
3029
ReactDOMClient = require('react-dom/client');
31-
ReactTestUtils = require('react-dom/test-utils');
3230
act = require('internal-test-utils').act;
3331
});
3432

3533
// TODO: This behavior creates a runtime dependency on propTypes. We should
3634
// ensure that this is not required for ES6 classes with Flow.
3735

3836
// @gate !disableLegacyContext
39-
it('should filter out context not in contextTypes', () => {
37+
it('should filter out context not in contextTypes', async () => {
4038
class Component extends React.Component {
4139
render() {
4240
return <div />;
@@ -65,9 +63,14 @@ describe('ReactContextValidator', () => {
6563
bar: PropTypes.number,
6664
};
6765

68-
const instance = ReactTestUtils.renderIntoDocument(
69-
<ComponentInFooBarContext />,
70-
);
66+
let instance;
67+
const container = document.createElement('div');
68+
const root = ReactDOMClient.createRoot(container);
69+
await act(() => {
70+
root.render(
71+
<ComponentInFooBarContext ref={current => (instance = current)} />,
72+
);
73+
});
7174
expect(instance.childRef.current.context).toEqual({foo: 'abc'});
7275
});
7376

@@ -160,7 +163,7 @@ describe('ReactContextValidator', () => {
160163
// TODO (bvaughn) Remove this test and the associated behavior in the future.
161164
// It has only been added in Fiber to match the (unintentional) behavior in Stack.
162165
// @gate !disableLegacyContext || !__DEV__
163-
it('should warn (but not error) if getChildContext method is missing', () => {
166+
it('should warn (but not error) if getChildContext method is missing', async () => {
164167
class ComponentA extends React.Component {
165168
static childContextTypes = {
166169
foo: PropTypes.string.isRequired,
@@ -178,16 +181,32 @@ describe('ReactContextValidator', () => {
178181
}
179182
}
180183

181-
expect(() => ReactTestUtils.renderIntoDocument(<ComponentA />)).toErrorDev(
184+
await expect(async () => {
185+
const container = document.createElement('div');
186+
const root = ReactDOMClient.createRoot(container);
187+
await act(() => {
188+
root.render(<ComponentA />);
189+
});
190+
}).toErrorDev(
182191
'Warning: ComponentA.childContextTypes is specified but there is no ' +
183192
'getChildContext() method on the instance. You can either define ' +
184193
'getChildContext() on ComponentA or remove childContextTypes from it.',
185194
);
186195

187196
// Warnings should be deduped by component type
188-
ReactTestUtils.renderIntoDocument(<ComponentA />);
197+
let container = document.createElement('div');
198+
let root = ReactDOMClient.createRoot(container);
199+
await act(() => {
200+
root.render(<ComponentA />);
201+
});
189202

190-
expect(() => ReactTestUtils.renderIntoDocument(<ComponentB />)).toErrorDev(
203+
await expect(async () => {
204+
container = document.createElement('div');
205+
root = ReactDOMClient.createRoot(container);
206+
await act(() => {
207+
root.render(<ComponentB />);
208+
});
209+
}).toErrorDev(
191210
'Warning: ComponentB.childContextTypes is specified but there is no ' +
192211
'getChildContext() method on the instance. You can either define ' +
193212
'getChildContext() on ComponentB or remove childContextTypes from it.',
@@ -197,7 +216,7 @@ describe('ReactContextValidator', () => {
197216
// TODO (bvaughn) Remove this test and the associated behavior in the future.
198217
// It has only been added in Fiber to match the (unintentional) behavior in Stack.
199218
// @gate !disableLegacyContext
200-
it('should pass parent context if getChildContext method is missing', () => {
219+
it('should pass parent context if getChildContext method is missing', async () => {
201220
class ParentContextProvider extends React.Component {
202221
static childContextTypes = {
203222
foo: PropTypes.string,
@@ -233,9 +252,13 @@ describe('ReactContextValidator', () => {
233252
foo: PropTypes.string.isRequired,
234253
};
235254

236-
expect(() =>
237-
ReactTestUtils.renderIntoDocument(<ParentContextProvider />),
238-
).toErrorDev([
255+
await expect(async () => {
256+
const container = document.createElement('div');
257+
const root = ReactDOMClient.createRoot(container);
258+
await act(() => {
259+
root.render(<ParentContextProvider />);
260+
});
261+
}).toErrorDev([
239262
'Warning: MiddleMissingContext.childContextTypes is specified but there is no ' +
240263
'getChildContext() method on the instance. You can either define getChildContext() ' +
241264
'on MiddleMissingContext or remove childContextTypes from it.',
@@ -366,7 +389,7 @@ describe('ReactContextValidator', () => {
366389
});
367390

368391
// @gate !disableLegacyContext || !__DEV__
369-
it('should warn if both contextType and contextTypes are defined', () => {
392+
it('should warn if both contextType and contextTypes are defined', async () => {
370393
const Context = React.createContext();
371394

372395
class ParentContextProvider extends React.Component {
@@ -402,38 +425,50 @@ describe('ReactContextValidator', () => {
402425
}
403426
}
404427

405-
expect(() =>
406-
ReactTestUtils.renderIntoDocument(
407-
<ParentContextProvider>
408-
<ComponentA />
409-
</ParentContextProvider>,
410-
),
411-
).toErrorDev(
428+
await expect(async () => {
429+
const container = document.createElement('div');
430+
const root = ReactDOMClient.createRoot(container);
431+
await act(() => {
432+
root.render(
433+
<ParentContextProvider>
434+
<ComponentA />
435+
</ParentContextProvider>,
436+
);
437+
});
438+
}).toErrorDev(
412439
'Warning: ComponentA declares both contextTypes and contextType static properties. ' +
413440
'The legacy contextTypes property will be ignored.',
414441
);
415442

416443
// Warnings should be deduped by component type
417-
ReactTestUtils.renderIntoDocument(
418-
<ParentContextProvider>
419-
<ComponentA />
420-
</ParentContextProvider>,
421-
);
422-
423-
expect(() =>
424-
ReactTestUtils.renderIntoDocument(
444+
let container = document.createElement('div');
445+
let root = ReactDOMClient.createRoot(container);
446+
await act(() => {
447+
root.render(
425448
<ParentContextProvider>
426-
<ComponentB />
449+
<ComponentA />
427450
</ParentContextProvider>,
428-
),
429-
).toErrorDev(
451+
);
452+
});
453+
454+
await expect(async () => {
455+
container = document.createElement('div');
456+
root = ReactDOMClient.createRoot(container);
457+
await act(() => {
458+
root.render(
459+
<ParentContextProvider>
460+
<ComponentB />
461+
</ParentContextProvider>,
462+
);
463+
});
464+
}).toErrorDev(
430465
'Warning: ComponentB declares both contextTypes and contextType static properties. ' +
431466
'The legacy contextTypes property will be ignored.',
432467
);
433468
});
434469

435470
// @gate enableRenderableContext || !__DEV__
436-
it('should warn if an invalid contextType is defined', () => {
471+
it('should warn if an invalid contextType is defined', async () => {
437472
const Context = React.createContext();
438473
class ComponentA extends React.Component {
439474
static contextType = Context.Consumer;
@@ -442,40 +477,54 @@ describe('ReactContextValidator', () => {
442477
}
443478
}
444479

445-
expect(() => {
446-
ReactTestUtils.renderIntoDocument(<ComponentA />);
480+
await expect(async () => {
481+
const container = document.createElement('div');
482+
const root = ReactDOMClient.createRoot(container);
483+
await act(() => {
484+
root.render(<ComponentA />);
485+
});
447486
}).toErrorDev(
448487
'Warning: ComponentA defines an invalid contextType. ' +
449488
'contextType should point to the Context object returned by React.createContext(). ' +
450489
'Did you accidentally pass the Context.Consumer instead?',
451490
);
452491

453-
// Warnings should be deduped by component type
454-
ReactTestUtils.renderIntoDocument(<ComponentA />);
492+
let container = document.createElement('div');
493+
let root = ReactDOMClient.createRoot(container);
494+
await act(() => {
495+
root.render(<ComponentA />);
496+
});
455497

456498
class ComponentB extends React.Component {
457499
static contextType = Context.Provider;
458500
render() {
459501
return <div />;
460502
}
461503
}
462-
// This doesn't warn since Context.Provider === Context now.
463-
ReactTestUtils.renderIntoDocument(<ComponentB />);
504+
container = document.createElement('div');
505+
root = ReactDOMClient.createRoot(container);
506+
await act(() => {
507+
root.render(<ComponentB />);
508+
});
464509
});
465510

466-
it('should not warn when class contextType is null', () => {
511+
it('should not warn when class contextType is null', async () => {
467512
class Foo extends React.Component {
468513
static contextType = null; // Handy for conditional declaration
469514
render() {
470515
return this.context.hello.world;
471516
}
472517
}
473-
expect(() => {
474-
ReactTestUtils.renderIntoDocument(<Foo />);
475-
}).toThrow("Cannot read property 'world' of undefined");
518+
await expect(async () => {
519+
const container = document.createElement('div');
520+
const root = ReactDOMClient.createRoot(container);
521+
await act(() => {
522+
root.render(<Foo />);
523+
});
524+
}).rejects.toThrow("Cannot read properties of undefined (reading 'world')");
476525
});
477526

478-
it('should warn when class contextType is undefined', () => {
527+
it('should warn when class contextType is undefined', async () => {
479528
class Foo extends React.Component {
480529
// This commonly happens with circular deps
481530
// https://github.com/facebook/react/issues/13969
@@ -485,10 +534,16 @@ describe('ReactContextValidator', () => {
485534
}
486535
}
487536

488-
expect(() => {
489-
expect(() => {
490-
ReactTestUtils.renderIntoDocument(<Foo />);
491-
}).toThrow("Cannot read property 'world' of undefined");
537+
await expect(async () => {
538+
await expect(async () => {
539+
const container = document.createElement('div');
540+
const root = ReactDOMClient.createRoot(container);
541+
await act(() => {
542+
root.render(<Foo />);
543+
});
544+
}).rejects.toThrow(
545+
"Cannot read properties of undefined (reading 'world')",
546+
);
492547
}).toErrorDev(
493548
'Foo defines an invalid contextType. ' +
494549
'contextType should point to the Context object returned by React.createContext(). ' +
@@ -499,7 +554,7 @@ describe('ReactContextValidator', () => {
499554
);
500555
});
501556

502-
it('should warn when class contextType is an object', () => {
557+
it('should warn when class contextType is an object', async () => {
503558
class Foo extends React.Component {
504559
// Can happen due to a typo
505560
static contextType = {
@@ -511,37 +566,49 @@ describe('ReactContextValidator', () => {
511566
}
512567
}
513568

514-
expect(() => {
515-
expect(() => {
516-
ReactTestUtils.renderIntoDocument(<Foo />);
517-
}).toThrow("Cannot read property 'hello' of undefined");
569+
await expect(async () => {
570+
await expect(async () => {
571+
const container = document.createElement('div');
572+
const root = ReactDOMClient.createRoot(container);
573+
await act(() => {
574+
root.render(<Foo />);
575+
});
576+
}).rejects.toThrow(
577+
"Cannot read properties of undefined (reading 'hello')",
578+
);
518579
}).toErrorDev(
519580
'Foo defines an invalid contextType. ' +
520581
'contextType should point to the Context object returned by React.createContext(). ' +
521582
'However, it is set to an object with keys {x, y}.',
522583
);
523584
});
524585

525-
it('should warn when class contextType is a primitive', () => {
586+
it('should warn when class contextType is a primitive', async () => {
526587
class Foo extends React.Component {
527588
static contextType = 'foo';
528589
render() {
529590
return this.context.hello.world;
530591
}
531592
}
532593

533-
expect(() => {
534-
expect(() => {
535-
ReactTestUtils.renderIntoDocument(<Foo />);
536-
}).toThrow("Cannot read property 'world' of undefined");
594+
await expect(async () => {
595+
await expect(async () => {
596+
const container = document.createElement('div');
597+
const root = ReactDOMClient.createRoot(container);
598+
await act(() => {
599+
root.render(<Foo />);
600+
});
601+
}).rejects.toThrow(
602+
"Cannot read properties of undefined (reading 'world')",
603+
);
537604
}).toErrorDev(
538605
'Foo defines an invalid contextType. ' +
539606
'contextType should point to the Context object returned by React.createContext(). ' +
540607
'However, it is set to a string.',
541608
);
542609
});
543610

544-
it('should warn if you define contextType on a function component', () => {
611+
it('should warn if you define contextType on a function component', async () => {
545612
const Context = React.createContext();
546613

547614
function ComponentA() {
@@ -554,14 +621,30 @@ describe('ReactContextValidator', () => {
554621
}
555622
ComponentB.contextType = Context;
556623

557-
expect(() => ReactTestUtils.renderIntoDocument(<ComponentA />)).toErrorDev(
624+
await expect(async () => {
625+
const container = document.createElement('div');
626+
const root = ReactDOMClient.createRoot(container);
627+
await act(() => {
628+
root.render(<ComponentA />);
629+
});
630+
}).toErrorDev(
558631
'Warning: ComponentA: Function components do not support contextType.',
559632
);
560633

561634
// Warnings should be deduped by component type
562-
ReactTestUtils.renderIntoDocument(<ComponentA />);
635+
let container = document.createElement('div');
636+
let root = ReactDOMClient.createRoot(container);
637+
await act(() => {
638+
root.render(<ComponentA />);
639+
});
563640

564-
expect(() => ReactTestUtils.renderIntoDocument(<ComponentB />)).toErrorDev(
641+
await expect(async () => {
642+
container = document.createElement('div');
643+
root = ReactDOMClient.createRoot(container);
644+
await act(() => {
645+
root.render(<ComponentB />);
646+
});
647+
}).toErrorDev(
565648
'Warning: ComponentB: Function components do not support contextType.',
566649
);
567650
});

0 commit comments

Comments
 (0)