@samitouri / QOS-React-2 / commits / 59d3aca686

Use `act()` in ReactFabric tests (#21839)

Timothy Yung committed Jul 8, 2021 at 15:02 UTC 59d3aca68638319c88d685ce22cac76a03cfe493
1 file changed +274 -188
packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js
+274 -188
@@ -16,6 +16,7 @@ let createReactNativeComponentClass;
16 let UIManager;
17 let StrictMode;
18 let TextInputState;
19 +let act;
20
21 const SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE =
22 'Warning: setNativeProps is not currently supported in Fabric';
@@ -47,6 +48,9 @@ describe('ReactFabric', () => {
48 .ReactNativeViewConfigRegistry.register;
49 TextInputState = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
50 .TextInputState;
51 +
52 + const ReactTestRenderer = require('react-test-renderer');
53 + act = ReactTestRenderer.act;
54 });
55
56 it('should be able to create and render a native component', () => {
@@ -55,7 +59,9 @@ describe('ReactFabric', () => {
59 uiViewClassName: 'RCTView',
60 }));
61
58 - ReactFabric.render(<View foo="test" />, 1);
62 + act(() => {
63 + ReactFabric.render(<View foo="test" />, 1);
64 + });
65 expect(nativeFabricUIManager.createNode).toBeCalled();
66 expect(nativeFabricUIManager.appendChild).not.toBeCalled();
67 expect(nativeFabricUIManager.completeRoot).toBeCalled();
@@ -71,11 +77,15 @@ describe('ReactFabric', () => {
77
78 nativeFabricUIManager.createNode.mockReturnValue(firstNode);
79
74 - ReactFabric.render(<View foo="foo" />, 11);
80 + act(() => {
81 + ReactFabric.render(<View foo="foo" />, 11);
82 + });
83
84 expect(nativeFabricUIManager.createNode).toHaveBeenCalledTimes(1);
85
78 - ReactFabric.render(<View foo="bar" />, 11);
86 + act(() => {
87 + ReactFabric.render(<View foo="bar" />, 11);
88 + });
89
90 expect(nativeFabricUIManager.createNode).toHaveBeenCalledTimes(1);
91 expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes(
@@ -97,7 +107,9 @@ describe('ReactFabric', () => {
107 uiViewClassName: 'RCTText',
108 }));
109
100 - ReactFabric.render(<Text foo="a">1</Text>, 11);
110 + act(() => {
111 + ReactFabric.render(<Text foo="a">1</Text>, 11);
112 + });
113 expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
114 expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled();
115 expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled();
@@ -106,7 +118,9 @@ describe('ReactFabric', () => {
118 ).not.toBeCalled();
119
120 // If no properties have changed, we shouldn't call cloneNode.
109 - ReactFabric.render(<Text foo="a">1</Text>, 11);
121 + act(() => {
122 + ReactFabric.render(<Text foo="a">1</Text>, 11);
123 + });
124 expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
125 expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled();
126 expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled();
@@ -115,7 +129,9 @@ describe('ReactFabric', () => {
129 ).not.toBeCalled();
130
131 // Only call cloneNode for the changed property (and not for text).
118 - ReactFabric.render(<Text foo="b">1</Text>, 11);
132 + act(() => {
133 + ReactFabric.render(<Text foo="b">1</Text>, 11);
134 + });
135 expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
136 expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled();
137 expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes(
@@ -126,7 +142,9 @@ describe('ReactFabric', () => {
142 ).not.toBeCalled();
143
144 // Only call cloneNode for the changed text (and no other properties).
129 - ReactFabric.render(<Text foo="b">2</Text>, 11);
145 + act(() => {
146 + ReactFabric.render(<Text foo="b">2</Text>, 11);
147 + });
148 expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
149 expect(
150 nativeFabricUIManager.cloneNodeWithNewChildren,
@@ -139,7 +157,9 @@ describe('ReactFabric', () => {
157 ).not.toBeCalled();
158
159 // Call cloneNode for both changed text and properties.
142 - ReactFabric.render(<Text foo="c">3</Text>, 11);
160 + act(() => {
161 + ReactFabric.render(<Text foo="c">3</Text>, 11);
162 + });
163 expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
164 expect(
165 nativeFabricUIManager.cloneNodeWithNewChildren,
@@ -158,12 +178,14 @@ describe('ReactFabric', () => {
178 uiViewClassName: 'RCTText',
179 }));
180
161 - ReactFabric.render(
162 - <Text foo="a" bar="a">
163 - 1
164 - </Text>,
165 - 11,
166 - );
181 + act(() => {
182 + ReactFabric.render(
183 + <Text foo="a" bar="a">
184 + 1
185 + </Text>,
186 + 11,
187 + );
188 + });
189 expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
190 expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled();
191 expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled();
@@ -171,12 +193,14 @@ describe('ReactFabric', () => {
193 nativeFabricUIManager.cloneNodeWithNewChildrenAndProps,
194 ).not.toBeCalled();
195
174 - ReactFabric.render(
175 - <Text foo="a" bar="b">
176 - 1
177 - </Text>,
178 - 11,
179 - );
196 + act(() => {
197 + ReactFabric.render(
198 + <Text foo="a" bar="b">
199 + 1
200 + </Text>,
201 + 11,
202 + );
203 + });
204 expect(
205 nativeFabricUIManager.cloneNodeWithNewProps.mock.calls[0][1],
206 ).toEqual({
@@ -186,12 +210,14 @@ describe('ReactFabric', () => {
210 nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
211 ).toMatchSnapshot();
212
189 - ReactFabric.render(
190 - <Text foo="b" bar="b">
191 - 2
192 - </Text>,
193 - 11,
194 - );
213 + act(() => {
214 + ReactFabric.render(
215 + <Text foo="b" bar="b">
216 + 2
217 + </Text>,
218 + 11,
219 + );
220 + });
221 expect(
222 nativeFabricUIManager.cloneNodeWithNewChildrenAndProps.mock.calls[0][1],
223 ).toEqual({
@@ -211,15 +237,17 @@ describe('ReactFabric', () => {
237 UIManager.updateView.mockReset();
238
239 let viewRef;
214 - ReactFabric.render(
215 - <View
216 - foo="bar"
217 - ref={ref => {
218 - viewRef = ref;
219 - }}
220 - />,
221 - 11,
222 - );
240 + act(() => {
241 + ReactFabric.render(
242 + <View
243 + foo="bar"
244 + ref={ref => {
245 + viewRef = ref;
246 + }}
247 + />,
248 + 11,
249 + );
250 + });
251 expect(UIManager.updateView).not.toBeCalled();
252
253 expect(() => {
@@ -247,14 +275,16 @@ describe('ReactFabric', () => {
275 nativeFabricUIManager.dispatchCommand.mockClear();
276
277 let viewRef;
250 - ReactFabric.render(
251 - <View
252 - ref={ref => {
253 - viewRef = ref;
254 - }}
255 - />,
256 - 11,
257 - );
278 + act(() => {
279 + ReactFabric.render(
280 + <View
281 + ref={ref => {
282 + viewRef = ref;
283 + }}
284 + />,
285 + 11,
286 + );
287 + });
288
289 expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
290 ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]);
@@ -274,14 +304,16 @@ describe('ReactFabric', () => {
304 nativeFabricUIManager.dispatchCommand.mockReset();
305
306 let viewRef;
277 - ReactFabric.render(
278 - <BasicClass
279 - ref={ref => {
280 - viewRef = ref;
281 - }}
282 - />,
283 - 11,
284 - );
307 + act(() => {
308 + ReactFabric.render(
309 + <BasicClass
310 + ref={ref => {
311 + viewRef = ref;
312 + }}
313 + />,
314 + 11,
315 + );
316 + });
317
318 expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
319 expect(() => {
@@ -302,14 +334,16 @@ describe('ReactFabric', () => {
334 nativeFabricUIManager.sendAccessibilityEvent.mockClear();
335
336 let viewRef;
305 - ReactFabric.render(
306 - <View
307 - ref={ref => {
308 - viewRef = ref;
309 - }}
310 - />,
311 - 11,
312 - );
337 + act(() => {
338 + ReactFabric.render(
339 + <View
340 + ref={ref => {
341 + viewRef = ref;
342 + }}
343 + />,
344 + 11,
345 + );
346 + });
347
348 expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
349 ReactFabric.sendAccessibilityEvent(viewRef, 'focus');
@@ -332,14 +366,16 @@ describe('ReactFabric', () => {
366 nativeFabricUIManager.sendAccessibilityEvent.mockReset();
367
368 let viewRef;
335 - ReactFabric.render(
336 - <BasicClass
337 - ref={ref => {
338 - viewRef = ref;
339 - }}
340 - />,
341 - 11,
342 - );
369 + act(() => {
370 + ReactFabric.render(
371 + <BasicClass
372 + ref={ref => {
373 + viewRef = ref;
374 + }}
375 + />,
376 + 11,
377 + );
378 + });
379
380 expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
381 expect(() => {
@@ -360,14 +396,16 @@ describe('ReactFabric', () => {
396 nativeFabricUIManager.measure.mockClear();
397
398 let viewRef;
363 - ReactFabric.render(
364 - <View
365 - ref={ref => {
366 - viewRef = ref;
367 - }}
368 - />,
369 - 11,
370 - );
399 + act(() => {
400 + ReactFabric.render(
401 + <View
402 + ref={ref => {
403 + viewRef = ref;
404 + }}
405 + />,
406 + 11,
407 + );
408 + });
409
410 expect(nativeFabricUIManager.measure).not.toBeCalled();
411 const successCallback = jest.fn();
@@ -386,14 +424,16 @@ describe('ReactFabric', () => {
424 nativeFabricUIManager.measureInWindow.mockClear();
425
426 let viewRef;
389 - ReactFabric.render(
390 - <View
391 - ref={ref => {
392 - viewRef = ref;
393 - }}
394 - />,
395 - 11,
396 - );
427 + act(() => {
428 + ReactFabric.render(
429 + <View
430 + ref={ref => {
431 + viewRef = ref;
432 + }}
433 + />,
434 + 11,
435 + );
436 + });
437
438 expect(nativeFabricUIManager.measureInWindow).not.toBeCalled();
439 const successCallback = jest.fn();
@@ -413,22 +453,24 @@ describe('ReactFabric', () => {
453
454 let viewRef;
455 let otherRef;
416 - ReactFabric.render(
417 - <View>
418 - <View
419 - foo="bar"
420 - ref={ref => {
421 - viewRef = ref;
422 - }}
423 - />
424 - <View
425 - ref={ref => {
426 - otherRef = ref;
427 - }}
428 - />
429 - </View>,
430 - 11,
431 - );
456 + act(() => {
457 + ReactFabric.render(
458 + <View>
459 + <View
460 + foo="bar"
461 + ref={ref => {
462 + viewRef = ref;
463 + }}
464 + />
465 + <View
466 + ref={ref => {
467 + otherRef = ref;
468 + }}
469 + />
470 + </View>,
471 + 11,
472 + );
473 + });
474
475 expect(nativeFabricUIManager.measureLayout).not.toBeCalled();
476 const successCallback = jest.fn();
@@ -483,12 +525,16 @@ describe('ReactFabric', () => {
525 const before = 'abcdefghijklmnopqrst';
526 const after = 'mxhpgwfralkeoivcstzy';
527
486 - ReactFabric.render(<Component chars={before} />, 11);
528 + act(() => {
529 + ReactFabric.render(<Component chars={before} />, 11);
530 + });
531 expect(
532 nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
533 ).toMatchSnapshot();
534
491 - ReactFabric.render(<Component chars={after} />, 11);
535 + act(() => {
536 + ReactFabric.render(<Component chars={after} />, 11);
537 + });
538 expect(
539 nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
540 ).toMatchSnapshot();
@@ -521,12 +567,14 @@ describe('ReactFabric', () => {
567
568 const ref = React.createRef();
569 // Wrap in a host node.
524 - ReactFabric.render(
525 - <View>
526 - <Component ref={ref} />
527 - </View>,
528 - 11,
529 - );
570 + act(() => {
571 + ReactFabric.render(
572 + <View>
573 + <Component ref={ref} />
574 + </View>,
575 + 11,
576 + );
577 + });
578 expect(
579 nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
580 ).toMatchSnapshot();
@@ -552,7 +600,9 @@ describe('ReactFabric', () => {
600 }
601 }
602
555 - ReactFabric.render(<Component />, 11);
603 + act(() => {
604 + ReactFabric.render(<Component />, 11);
605 + });
606 expect(mockArgs.length).toEqual(0);
607 });
608
@@ -572,12 +622,14 @@ describe('ReactFabric', () => {
622 );
623 });
624
575 - ReactFabric.render(
576 - <View foo="a">
577 - <View foo="b" />
578 - </View>,
579 - 22,
580 - );
625 + act(() => {
626 + ReactFabric.render(
627 + <View foo="a">
628 + <View foo="b" />
629 + </View>,
630 + 22,
631 + );
632 + });
633 expect(snapshots).toMatchSnapshot();
634 });
635
@@ -595,19 +647,23 @@ describe('ReactFabric', () => {
647 uiViewClassName: 'RCTView',
648 }));
649
598 - ReactFabric.render(
599 - <Text>
600 - <View />
601 - </Text>,
602 - 11,
603 - );
650 + act(() => {
651 + ReactFabric.render(
652 + <Text>
653 + <View />
654 + </Text>,
655 + 11,
656 + );
657 + });
658
605 - ReactFabric.render(
606 - <Text>
607 - <Image />
608 - </Text>,
609 - 11,
610 - );
659 + act(() => {
660 + ReactFabric.render(
661 + <Text>
662 + <Image />
663 + </Text>,
664 + 11,
665 + );
666 + });
667 });
668
669 it('should throw for text not inside of a <Text> ancestor', () => {
@@ -624,18 +680,22 @@ describe('ReactFabric', () => {
680 uiViewClassName: 'RCTView',
681 }));
682
627 - expect(() => ReactFabric.render(<View>this should warn</View>, 11)).toThrow(
628 - 'Text strings must be rendered within a <Text> component.',
629 - );
683 + expect(() => {
684 + act(() => {
685 + ReactFabric.render(<View>this should warn</View>, 11);
686 + });
687 + }).toThrow('Text strings must be rendered within a <Text> component.');
688
631 - expect(() =>
632 - ReactFabric.render(
633 - <Text>
634 - <ScrollView>hi hello hi</ScrollView>
635 - </Text>,
636 - 11,
637 - ),
638 - ).toThrow('Text strings must be rendered within a <Text> component.');
689 + expect(() => {
690 + act(() => {
691 + ReactFabric.render(
692 + <Text>
693 + <ScrollView>hi hello hi</ScrollView>
694 + </Text>,
695 + 11,
696 + );
697 + });
698 + }).toThrow('Text strings must be rendered within a <Text> component.');
699 });
700
701 it('should not throw for text inside of an indirect <Text> ancestor', () => {
@@ -646,12 +706,14 @@ describe('ReactFabric', () => {
706
707 const Indirection = () => 'Hi';
708
649 - ReactFabric.render(
650 - <Text>
651 - <Indirection />
652 - </Text>,
653 - 11,
654 - );
709 + act(() => {
710 + ReactFabric.render(
711 + <Text>
712 + <Indirection />
713 + </Text>,
714 + 11,
715 + );
716 + });
717 });
718
719 it('dispatches events to the last committed props', () => {
@@ -668,7 +730,9 @@ describe('ReactFabric', () => {
730 const touchStart = jest.fn();
731 const touchStart2 = jest.fn();
732
671 - ReactFabric.render(<View onTouchStart={touchStart} />, 11);
733 + act(() => {
734 + ReactFabric.render(<View onTouchStart={touchStart} />, 11);
735 + });
736
737 expect(nativeFabricUIManager.createNode.mock.calls.length).toBe(1);
738 expect(nativeFabricUIManager.registerEventHandler.mock.calls.length).toBe(
@@ -698,7 +762,9 @@ describe('ReactFabric', () => {
762 expect(touchStart).toBeCalled();
763 expect(touchStart2).not.toBeCalled();
764
701 - ReactFabric.render(<View onTouchStart={touchStart2} />, 11);
765 + act(() => {
766 + ReactFabric.render(<View onTouchStart={touchStart2} />, 11);
767 + });
768
769 // Intentionally dispatch to the same instanceHandle again.
770 dispatchEvent(instanceHandle, 'topTouchStart', touchEvent);
@@ -742,33 +808,35 @@ describe('ReactFabric', () => {
808 const ref1 = React.createRef();
809 const ref2 = React.createRef();
810
745 - ReactFabric.render(
746 - <View id="parent">
747 - <View
748 - ref={ref1}
749 - id="one"
750 - onResponderStart={event => {
751 - expect(ref1.current).not.toBeNull();
752 - // Check for referential equality
753 - expect(ref1.current).toBe(event.target);
754 - expect(ref1.current).toBe(event.currentTarget);
755 - }}
756 - onStartShouldSetResponder={() => true}
757 - />
758 - <View
759 - ref={ref2}
760 - id="two"
761 - onResponderStart={event => {
762 - expect(ref2.current).not.toBeNull();
763 - // Check for referential equality
764 - expect(ref2.current).toBe(event.target);
765 - expect(ref2.current).toBe(event.currentTarget);
766 - }}
767 - onStartShouldSetResponder={() => true}
768 - />
769 - </View>,
770 - 1,
771 - );
811 + act(() => {
812 + ReactFabric.render(
813 + <View id="parent">
814 + <View
815 + ref={ref1}
816 + id="one"
817 + onResponderStart={event => {
818 + expect(ref1.current).not.toBeNull();
819 + // Check for referential equality
820 + expect(ref1.current).toBe(event.target);
821 + expect(ref1.current).toBe(event.currentTarget);
822 + }}
823 + onStartShouldSetResponder={() => true}
824 + />
825 + <View
826 + ref={ref2}
827 + id="two"
828 + onResponderStart={event => {
829 + expect(ref2.current).not.toBeNull();
830 + // Check for referential equality
831 + expect(ref2.current).toBe(event.target);
832 + expect(ref2.current).toBe(event.currentTarget);
833 + }}
834 + onStartShouldSetResponder={() => true}
835 + />
836 + </View>,
837 + 1,
838 + );
839 + });
840
841 const [
842 dispatchEvent,
@@ -823,7 +891,12 @@ describe('ReactFabric', () => {
891 }
892 }
893
826 - ReactFabric.render(<ContainsStrictModeChild ref={n => (parent = n)} />, 11);
894 + act(() => {
895 + ReactFabric.render(
896 + <ContainsStrictModeChild ref={n => (parent = n)} />,
897 + 11,
898 + );
899 + });
900
901 let match;
902 expect(
@@ -855,12 +928,14 @@ describe('ReactFabric', () => {
928 }
929 }
930
858 - ReactFabric.render(
859 - <StrictMode>
860 - <IsInStrictMode ref={n => (parent = n)} />
861 - </StrictMode>,
862 - 11,
863 - );
931 + act(() => {
932 + ReactFabric.render(
933 + <StrictMode>
934 + <IsInStrictMode ref={n => (parent = n)} />
935 + </StrictMode>,
936 + 11,
937 + );
938 + });
939
940 let match;
941 expect(
@@ -896,7 +971,12 @@ describe('ReactFabric', () => {
971 }
972 }
973
899 - ReactFabric.render(<ContainsStrictModeChild ref={n => (parent = n)} />, 11);
974 + act(() => {
975 + ReactFabric.render(
976 + <ContainsStrictModeChild ref={n => (parent = n)} />,
977 + 11,
978 + );
979 + });
980
981 let match;
982 expect(() => (match = ReactFabric.findNodeHandle(parent))).toErrorDev([
@@ -926,12 +1006,14 @@ describe('ReactFabric', () => {
1006 }
1007 }
1008
929 - ReactFabric.render(
930 - <StrictMode>
931 - <IsInStrictMode ref={n => (parent = n)} />
932 - </StrictMode>,
933 - 11,
934 - );
1009 + act(() => {
1010 + ReactFabric.render(
1011 + <StrictMode>
1012 + <IsInStrictMode ref={n => (parent = n)} />
1013 + </StrictMode>,
1014 + 11,
1015 + );
1016 + });
1017
1018 let match;
1019 expect(() => (match = ReactFabric.findNodeHandle(parent))).toErrorDev([
@@ -953,7 +1035,9 @@ describe('ReactFabric', () => {
1035 }));
1036
1037 const viewRef = React.createRef();
956 - ReactFabric.render(<View ref={viewRef} />, 11);
1038 + act(() => {
1039 + ReactFabric.render(<View ref={viewRef} />, 11);
1040 + });
1041
1042 expect(TextInputState.blurTextInput).not.toBeCalled();
1043
@@ -970,7 +1054,9 @@ describe('ReactFabric', () => {
1054 }));
1055
1056 const viewRef = React.createRef();
973 - ReactFabric.render(<View ref={viewRef} />, 11);
1057 + act(() => {
1058 + ReactFabric.render(<View ref={viewRef} />, 11);
1059 + });
1060
1061 expect(TextInputState.focusTextInput).not.toBeCalled();
1062