@samitouri / QOS-React-2 / commits / ec4d26ceb8

ReactDOM: Remove every test-util except `act()` (#28541)

Sebastian Silbermann committed Mar 27, 2024 at 16:04 UTC ec4d26ceb8bbb622188c858b6b3d1a5f1e86f2f7
9 files changed +164 -5
packages/react-dom/src/__tests__/ReactTestUtils-test.js
+35 -5
@@ -31,6 +31,7 @@ describe('ReactTestUtils', () => {
31 expect(Object.keys(ReactTestUtils.Simulate).sort()).toMatchSnapshot();
32 });
33
34 + // @gate !disableDOMTestUtils
35 it('gives Jest mocks a passthrough implementation with mockComponent()', async () => {
36 class MockedComponent extends React.Component {
37 render() {
@@ -60,6 +61,7 @@ describe('ReactTestUtils', () => {
61 expect(container.textContent).toBe('Hello');
62 });
63
64 + // @gate !disableDOMTestUtils
65 it('can scryRenderedComponentsWithType', async () => {
66 class Child extends React.Component {
67 render() {
@@ -88,6 +90,7 @@ describe('ReactTestUtils', () => {
90 expect(scryResults.length).toBe(1);
91 });
92
93 + // @gate !disableDOMTestUtils
94 it('can scryRenderedDOMComponentsWithClass with TextComponent', async () => {
95 class Wrapper extends React.Component {
96 render() {
@@ -112,6 +115,7 @@ describe('ReactTestUtils', () => {
115 expect(scryResults.length).toBe(0);
116 });
117
118 + // @gate !disableDOMTestUtils
119 it('can scryRenderedDOMComponentsWithClass with className contains \\n', async () => {
120 class Wrapper extends React.Component {
121 render() {
@@ -136,6 +140,7 @@ describe('ReactTestUtils', () => {
140 expect(scryResults.length).toBe(1);
141 });
142
143 + // @gate !disableDOMTestUtils
144 it('can scryRenderedDOMComponentsWithClass with multiple classes', async () => {
145 class Wrapper extends React.Component {
146 render() {
@@ -187,6 +192,7 @@ describe('ReactTestUtils', () => {
192 expect(scryResults5.length).toBe(0);
193 });
194
195 + // @gate !disableDOMTestUtils
196 it('traverses children in the correct order', async () => {
197 class Wrapper extends React.Component {
198 render() {
@@ -225,6 +231,7 @@ describe('ReactTestUtils', () => {
231 expect(log).toEqual(['orangepurple', 'orange', 'purple']);
232 });
233
234 + // @gate !disableDOMTestUtils
235 it('should support injected wrapper components as DOM components', async () => {
236 const injectedDOMComponents = [
237 'button',
@@ -291,6 +298,7 @@ describe('ReactTestUtils', () => {
298 expect(ReactTestUtils.isDOMComponent(component.bodyRef.current)).toBe(true);
299 });
300
301 + // @gate !disableDOMTestUtils
302 it('can scry with stateless components involved', async () => {
303 const Function = () => (
304 <div>
@@ -320,6 +328,7 @@ describe('ReactTestUtils', () => {
328 expect(hrs.length).toBe(2);
329 });
330
331 + // @gate !disableDOMTestUtils
332 it('provides a clear error when passing invalid objects to scry', () => {
333 // This is probably too relaxed but it's existing behavior.
334 ReactTestUtils.findAllInRenderedTree(null, 'span');
@@ -377,6 +386,7 @@ describe('ReactTestUtils', () => {
386 });
387
388 describe('Simulate', () => {
389 + // @gate !disableDOMTestUtils
390 it('should change the value of an input field', async () => {
391 const obj = {
392 handler: function (e) {
@@ -399,6 +409,7 @@ describe('ReactTestUtils', () => {
409 );
410 });
411
412 + // @gate !disableDOMTestUtils
413 it('should change the value of an input field in a component', async () => {
414 class SomeComponent extends React.Component {
415 inputRef = React.createRef();
@@ -442,6 +453,7 @@ describe('ReactTestUtils', () => {
453 );
454 });
455
456 + // @gate !disableDOMTestUtils
457 it('should not warn when used with extra properties', async () => {
458 const CLIENT_X = 100;
459
@@ -468,6 +480,7 @@ describe('ReactTestUtils', () => {
480 });
481 });
482
483 + // @gate !disableDOMTestUtils
484 it('should set the type of the event', async () => {
485 let event;
486 const stub = jest.fn().mockImplementation(e => {
@@ -488,6 +501,7 @@ describe('ReactTestUtils', () => {
501 expect(event.nativeEvent.type).toBe('keydown');
502 });
503
504 + // @gate !disableDOMTestUtils
505 it('should work with renderIntoDocument', async () => {
506 const onChange = jest.fn();
507
@@ -520,6 +534,7 @@ describe('ReactTestUtils', () => {
534 );
535 });
536
537 + // @gate !disableDOMTestUtils
538 it('should have mouse enter simulated by test utils', async () => {
539 const idCallOrder = [];
540 const recordID = function (id) {
@@ -560,8 +575,17 @@ describe('ReactTestUtils', () => {
575 });
576 expect(idCallOrder).toEqual([CHILD]);
577 });
578 +
579 + // @gate disableDOMTestUtils
580 + it('throws', async () => {
581 + expect(ReactTestUtils.Simulate.click).toThrow(
582 + '`Simulate` was removed from `react-dom/test-utils`. ' +
583 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
584 + );
585 + });
586 });
587
588 + // @gate !disableDOMTestUtils
589 it('should call setState callback with no arguments', async () => {
590 let mockArgs;
591 class Component extends React.Component {
@@ -573,14 +597,12 @@ describe('ReactTestUtils', () => {
597 }
598 }
599
576 - const container = document.createElement('div');
577 - const root = ReactDOMClient.createRoot(container);
578 - await act(() => {
579 - root.render(<Component />);
580 - });
600 + ReactTestUtils.renderIntoDocument(<Component />);
601
602 expect(mockArgs.length).toEqual(0);
603 });
604 +
605 + // @gate !disableDOMTestUtils
606 it('should find rendered component with type in document', async () => {
607 class MyComponent extends React.Component {
608 render() {
@@ -602,4 +624,12 @@ describe('ReactTestUtils', () => {
624
625 expect(renderedComponentType).toBe(instance);
626 });
627 +
628 + // @gate disableDOMTestUtils
629 + it('throws on every removed function', async () => {
630 + expect(ReactTestUtils.isDOMComponent).toThrow(
631 + '`isDOMComponent` was removed from `react-dom/test-utils`. ' +
632 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
633 + );
634 + });
635 });
packages/react-dom/src/test-utils/ReactTestUtils.js
+120
@@ -21,6 +21,7 @@ import {
21 } from 'react-reconciler/src/ReactWorkTags';
22 import {SyntheticEvent} from 'react-dom-bindings/src/events/SyntheticEvent';
23 import {ELEMENT_NODE} from 'react-dom-bindings/src/client/HTMLNodeType';
24 +import {disableDOMTestUtils} from 'shared/ReactFeatureFlags';
25 import assign from 'shared/assign';
26 import isArray from 'shared/isArray';
27
@@ -126,6 +127,13 @@ function validateClassInstance(inst, methodName) {
127 * @lends ReactTestUtils
128 */
129 function renderIntoDocument(element) {
130 + if (disableDOMTestUtils) {
131 + throw new Error(
132 + '`renderIntoDocument` was removed from `react-dom/test-utils`. ' +
133 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
134 + );
135 + }
136 +
137 const div = document.createElement('div');
138 // None of our tests actually require attaching the container to the
139 // DOM, and doing so creates a mess that we rely on test isolation to
@@ -136,22 +144,57 @@ function renderIntoDocument(element) {
144 }
145
146 function isElement(element) {
147 + if (disableDOMTestUtils) {
148 + throw new Error(
149 + '`isElement` was removed from `react-dom/test-utils`. ' +
150 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
151 + );
152 + }
153 +
154 return React.isValidElement(element);
155 }
156
157 function isElementOfType(inst, convenienceConstructor) {
158 + if (disableDOMTestUtils) {
159 + throw new Error(
160 + '`isElementOfType` was removed from `react-dom/test-utils`. ' +
161 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
162 + );
163 + }
164 +
165 return React.isValidElement(inst) && inst.type === convenienceConstructor;
166 }
167
168 function isDOMComponent(inst) {
169 + if (disableDOMTestUtils) {
170 + throw new Error(
171 + '`isDOMComponent` was removed from `react-dom/test-utils`. ' +
172 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
173 + );
174 + }
175 +
176 return !!(inst && inst.nodeType === ELEMENT_NODE && inst.tagName);
177 }
178
179 function isDOMComponentElement(inst) {
180 + if (disableDOMTestUtils) {
181 + throw new Error(
182 + '`isDOMComponentElement` was removed from `react-dom/test-utils`. ' +
183 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
184 + );
185 + }
186 +
187 return !!(inst && React.isValidElement(inst) && !!inst.tagName);
188 }
189
190 function isCompositeComponent(inst) {
191 + if (disableDOMTestUtils) {
192 + throw new Error(
193 + '`isCompositeComponent` was removed from `react-dom/test-utils`. ' +
194 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
195 + );
196 + }
197 +
198 if (isDOMComponent(inst)) {
199 // Accessing inst.setState warns; just return false as that'll be what
200 // this returns when we have DOM nodes as refs directly
@@ -165,6 +208,13 @@ function isCompositeComponent(inst) {
208 }
209
210 function isCompositeComponentWithType(inst, type) {
211 + if (disableDOMTestUtils) {
212 + throw new Error(
213 + '`isCompositeComponentWithType` was removed from `react-dom/test-utils`. ' +
214 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
215 + );
216 + }
217 +
218 if (!isCompositeComponent(inst)) {
219 return false;
220 }
@@ -174,6 +224,13 @@ function isCompositeComponentWithType(inst, type) {
224 }
225
226 function findAllInRenderedTree(inst, test) {
227 + if (disableDOMTestUtils) {
228 + throw new Error(
229 + '`findAllInRenderedTree` was removed from `react-dom/test-utils`. ' +
230 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
231 + );
232 + }
233 +
234 validateClassInstance(inst, 'findAllInRenderedTree');
235 if (!inst) {
236 return [];
@@ -188,6 +245,13 @@ function findAllInRenderedTree(inst, test) {
245 * @return {array} an array of all the matches.
246 */
247 function scryRenderedDOMComponentsWithClass(root, classNames) {
248 + if (disableDOMTestUtils) {
249 + throw new Error(
250 + '`scryRenderedDOMComponentsWithClass` was removed from `react-dom/test-utils`. ' +
251 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
252 + );
253 + }
254 +
255 validateClassInstance(root, 'scryRenderedDOMComponentsWithClass');
256 return findAllInRenderedTree(root, function (inst) {
257 if (isDOMComponent(inst)) {
@@ -223,6 +287,13 @@ function scryRenderedDOMComponentsWithClass(root, classNames) {
287 * @return {!ReactDOMComponent} The one match.
288 */
289 function findRenderedDOMComponentWithClass(root, className) {
290 + if (disableDOMTestUtils) {
291 + throw new Error(
292 + '`findRenderedDOMComponentWithClass` was removed from `react-dom/test-utils`. ' +
293 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
294 + );
295 + }
296 +
297 validateClassInstance(root, 'findRenderedDOMComponentWithClass');
298 const all = scryRenderedDOMComponentsWithClass(root, className);
299 if (all.length !== 1) {
@@ -243,6 +314,13 @@ function findRenderedDOMComponentWithClass(root, className) {
314 * @return {array} an array of all the matches.
315 */
316 function scryRenderedDOMComponentsWithTag(root, tagName) {
317 + if (disableDOMTestUtils) {
318 + throw new Error(
319 + '`scryRenderedDOMComponentsWithTag` was removed from `react-dom/test-utils`. ' +
320 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
321 + );
322 + }
323 +
324 validateClassInstance(root, 'scryRenderedDOMComponentsWithTag');
325 return findAllInRenderedTree(root, function (inst) {
326 return (
@@ -259,6 +337,13 @@ function scryRenderedDOMComponentsWithTag(root, tagName) {
337 * @return {!ReactDOMComponent} The one match.
338 */
339 function findRenderedDOMComponentWithTag(root, tagName) {
340 + if (disableDOMTestUtils) {
341 + throw new Error(
342 + '`findRenderedDOMComponentWithTag` was removed from `react-dom/test-utils`. ' +
343 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
344 + );
345 + }
346 +
347 validateClassInstance(root, 'findRenderedDOMComponentWithTag');
348 const all = scryRenderedDOMComponentsWithTag(root, tagName);
349 if (all.length !== 1) {
@@ -278,6 +363,13 @@ function findRenderedDOMComponentWithTag(root, tagName) {
363 * @return {array} an array of all the matches.
364 */
365 function scryRenderedComponentsWithType(root, componentType) {
366 + if (disableDOMTestUtils) {
367 + throw new Error(
368 + '`scryRenderedComponentsWithType` was removed from `react-dom/test-utils`. ' +
369 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
370 + );
371 + }
372 +
373 validateClassInstance(root, 'scryRenderedComponentsWithType');
374 return findAllInRenderedTree(root, function (inst) {
375 return isCompositeComponentWithType(inst, componentType);
@@ -291,6 +383,13 @@ function scryRenderedComponentsWithType(root, componentType) {
383 * @return {!ReactComponent} The one match.
384 */
385 function findRenderedComponentWithType(root, componentType) {
386 + if (disableDOMTestUtils) {
387 + throw new Error(
388 + '`findRenderedComponentWithType` was removed from `react-dom/test-utils`. ' +
389 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
390 + );
391 + }
392 +
393 validateClassInstance(root, 'findRenderedComponentWithType');
394 const all = scryRenderedComponentsWithType(root, componentType);
395 if (all.length !== 1) {
@@ -319,6 +418,13 @@ function findRenderedComponentWithType(root, componentType) {
418 * @return {object} the ReactTestUtils object (for chaining)
419 */
420 function mockComponent(module, mockTagName) {
421 + if (disableDOMTestUtils) {
422 + throw new Error(
423 + '`mockComponent` was removed from `react-dom/test-utils`. ' +
424 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
425 + );
426 + }
427 +
428 if (__DEV__) {
429 if (!hasWarnedAboutDeprecatedMockComponent) {
430 hasWarnedAboutDeprecatedMockComponent = true;
@@ -340,6 +446,13 @@ function mockComponent(module, mockTagName) {
446 }
447
448 function nativeTouchData(x, y) {
449 + if (disableDOMTestUtils) {
450 + throw new Error(
451 + '`nativeTouchData` was removed from `react-dom/test-utils`. ' +
452 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
453 + );
454 + }
455 +
456 return {
457 touches: [{pageX: x, pageY: y}],
458 };
@@ -578,6 +691,13 @@ const directDispatchEventTypes = new Set([
691 */
692 function makeSimulator(eventType) {
693 return function (domNode, eventData) {
694 + if (disableDOMTestUtils) {
695 + throw new Error(
696 + '`Simulate` was removed from `react-dom/test-utils`. ' +
697 + 'See https://react.dev/warnings/react-dom-test-utils for more info.',
698 + );
699 + }
700 +
701 if (React.isValidElement(domNode)) {
702 throw new Error(
703 'TestUtils.Simulate expected a DOM node as the first argument but received ' +
packages/shared/ReactFeatureFlags.js
+2
@@ -187,6 +187,8 @@ export const enableReactTestRendererWarning = __NEXT_MAJOR__;
187 // before removing them in stable in the next Major
188 export const disableLegacyMode = __NEXT_MAJOR__;
189
190 +export const disableDOMTestUtils = __NEXT_MAJOR__;
191 +
192 // HTML boolean attributes need a special PropertyInfoRecord.
193 // Between support of these attributes in browsers and React supporting them as
194 // boolean props library users can use them as `<div someBooleanAttribute="" />`.
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -100,6 +100,7 @@ export const disableStringRefs = false;
100
101 export const enableReactTestRendererWarning = false;
102 export const disableLegacyMode = false;
103 +export const disableDOMTestUtils = false;
104
105 // Flow magic to verify the exports of this file match the original version.
106 ((((null: any): ExportsType): FeatureFlagsType): ExportsType);
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -21,6 +21,7 @@ const __TODO_NEXT_RN_MAJOR__ = false;
21 export const enableRefAsProp = __TODO_NEXT_RN_MAJOR__;
22 export const disableStringRefs = __TODO_NEXT_RN_MAJOR__;
23 export const disableLegacyMode = __TODO_NEXT_RN_MAJOR__;
24 +export const disableDOMTestUtils = __TODO_NEXT_RN_MAJOR__;
25 export const enableBigIntSupport = __TODO_NEXT_RN_MAJOR__;
26 export const useModernStrictMode = __TODO_NEXT_RN_MAJOR__;
27 export const enableReactTestRendererWarning = __TODO_NEXT_RN_MAJOR__;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -92,6 +92,7 @@ export const disableStringRefs = __NEXT_MAJOR__;
92 export const enableBigIntSupport = __NEXT_MAJOR__;
93 export const disableLegacyMode = __NEXT_MAJOR__;
94 export const disableLegacyContext = __NEXT_MAJOR__;
95 +export const disableDOMTestUtils = __NEXT_MAJOR__;
96 export const enableNewBooleanProps = __NEXT_MAJOR__;
97 export const disableModulePatternComponents = __NEXT_MAJOR__;
98 export const enableRenderableContext = __NEXT_MAJOR__;
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+1
@@ -87,6 +87,7 @@ export const disableStringRefs = false;
87
88 export const enableReactTestRendererWarning = false;
89 export const disableLegacyMode = false;
90 +export const disableDOMTestUtils = false;
91
92 export const enableBigIntSupport = false;
93
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -89,6 +89,7 @@ export const disableStringRefs = false;
89
90 export const enableReactTestRendererWarning = false;
91 export const disableLegacyMode = false;
92 +export const disableDOMTestUtils = false;
93
94 export const enableBigIntSupport = true;
95
packages/shared/forks/ReactFeatureFlags.www.js
+2
@@ -121,5 +121,7 @@ export const disableStringRefs = false;
121
122 export const disableLegacyMode = false;
123
124 +export const disableDOMTestUtils = false;
125 +
126 // Flow magic to verify the exports of this file match the original version.
127 ((((null: any): ExportsType): FeatureFlagsType): ExportsType);