From 59d3aca68638319c88d685ce22cac76a03cfe493 Mon Sep 17 00:00:00 2001 From: Timothy Yung Date: Thu, 8 Jul 2021 15:02:02 -0700 Subject: [PATCH] Use `act()` in ReactFabric tests (#21839) --- .../__tests__/ReactFabric-test.internal.js | 462 +++++++++++------- 1 file changed, 274 insertions(+), 188 deletions(-) diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index a935da5e4df63..b77ed9903aa02 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -16,6 +16,7 @@ let createReactNativeComponentClass; let UIManager; let StrictMode; let TextInputState; +let act; const SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE = 'Warning: setNativeProps is not currently supported in Fabric'; @@ -47,6 +48,9 @@ describe('ReactFabric', () => { .ReactNativeViewConfigRegistry.register; TextInputState = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .TextInputState; + + const ReactTestRenderer = require('react-test-renderer'); + act = ReactTestRenderer.act; }); it('should be able to create and render a native component', () => { @@ -55,7 +59,9 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - ReactFabric.render(, 1); + act(() => { + ReactFabric.render(, 1); + }); expect(nativeFabricUIManager.createNode).toBeCalled(); expect(nativeFabricUIManager.appendChild).not.toBeCalled(); expect(nativeFabricUIManager.completeRoot).toBeCalled(); @@ -71,11 +77,15 @@ describe('ReactFabric', () => { nativeFabricUIManager.createNode.mockReturnValue(firstNode); - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); expect(nativeFabricUIManager.createNode).toHaveBeenCalledTimes(1); - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); expect(nativeFabricUIManager.createNode).toHaveBeenCalledTimes(1); expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes( @@ -97,7 +107,9 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTText', })); - ReactFabric.render(1, 11); + act(() => { + ReactFabric.render(1, 11); + }); expect(nativeFabricUIManager.cloneNode).not.toBeCalled(); expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled(); expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled(); @@ -106,7 +118,9 @@ describe('ReactFabric', () => { ).not.toBeCalled(); // If no properties have changed, we shouldn't call cloneNode. - ReactFabric.render(1, 11); + act(() => { + ReactFabric.render(1, 11); + }); expect(nativeFabricUIManager.cloneNode).not.toBeCalled(); expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled(); expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled(); @@ -115,7 +129,9 @@ describe('ReactFabric', () => { ).not.toBeCalled(); // Only call cloneNode for the changed property (and not for text). - ReactFabric.render(1, 11); + act(() => { + ReactFabric.render(1, 11); + }); expect(nativeFabricUIManager.cloneNode).not.toBeCalled(); expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled(); expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes( @@ -126,7 +142,9 @@ describe('ReactFabric', () => { ).not.toBeCalled(); // Only call cloneNode for the changed text (and no other properties). - ReactFabric.render(2, 11); + act(() => { + ReactFabric.render(2, 11); + }); expect(nativeFabricUIManager.cloneNode).not.toBeCalled(); expect( nativeFabricUIManager.cloneNodeWithNewChildren, @@ -139,7 +157,9 @@ describe('ReactFabric', () => { ).not.toBeCalled(); // Call cloneNode for both changed text and properties. - ReactFabric.render(3, 11); + act(() => { + ReactFabric.render(3, 11); + }); expect(nativeFabricUIManager.cloneNode).not.toBeCalled(); expect( nativeFabricUIManager.cloneNodeWithNewChildren, @@ -158,12 +178,14 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTText', })); - ReactFabric.render( - - 1 - , - 11, - ); + act(() => { + ReactFabric.render( + + 1 + , + 11, + ); + }); expect(nativeFabricUIManager.cloneNode).not.toBeCalled(); expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled(); expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled(); @@ -171,12 +193,14 @@ describe('ReactFabric', () => { nativeFabricUIManager.cloneNodeWithNewChildrenAndProps, ).not.toBeCalled(); - ReactFabric.render( - - 1 - , - 11, - ); + act(() => { + ReactFabric.render( + + 1 + , + 11, + ); + }); expect( nativeFabricUIManager.cloneNodeWithNewProps.mock.calls[0][1], ).toEqual({ @@ -186,12 +210,14 @@ describe('ReactFabric', () => { nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(), ).toMatchSnapshot(); - ReactFabric.render( - - 2 - , - 11, - ); + act(() => { + ReactFabric.render( + + 2 + , + 11, + ); + }); expect( nativeFabricUIManager.cloneNodeWithNewChildrenAndProps.mock.calls[0][1], ).toEqual({ @@ -211,15 +237,17 @@ describe('ReactFabric', () => { UIManager.updateView.mockReset(); let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + act(() => { + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); + }); expect(UIManager.updateView).not.toBeCalled(); expect(() => { @@ -247,14 +275,16 @@ describe('ReactFabric', () => { nativeFabricUIManager.dispatchCommand.mockClear(); let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + act(() => { + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); + }); expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]); @@ -274,14 +304,16 @@ describe('ReactFabric', () => { nativeFabricUIManager.dispatchCommand.mockReset(); let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + act(() => { + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); + }); expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled(); expect(() => { @@ -302,14 +334,16 @@ describe('ReactFabric', () => { nativeFabricUIManager.sendAccessibilityEvent.mockClear(); let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + act(() => { + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); + }); expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled(); ReactFabric.sendAccessibilityEvent(viewRef, 'focus'); @@ -332,14 +366,16 @@ describe('ReactFabric', () => { nativeFabricUIManager.sendAccessibilityEvent.mockReset(); let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + act(() => { + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); + }); expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled(); expect(() => { @@ -360,14 +396,16 @@ describe('ReactFabric', () => { nativeFabricUIManager.measure.mockClear(); let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + act(() => { + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); + }); expect(nativeFabricUIManager.measure).not.toBeCalled(); const successCallback = jest.fn(); @@ -386,14 +424,16 @@ describe('ReactFabric', () => { nativeFabricUIManager.measureInWindow.mockClear(); let viewRef; - ReactFabric.render( - { - viewRef = ref; - }} - />, - 11, - ); + act(() => { + ReactFabric.render( + { + viewRef = ref; + }} + />, + 11, + ); + }); expect(nativeFabricUIManager.measureInWindow).not.toBeCalled(); const successCallback = jest.fn(); @@ -413,22 +453,24 @@ describe('ReactFabric', () => { let viewRef; let otherRef; - ReactFabric.render( - - { - viewRef = ref; - }} - /> - { - otherRef = ref; - }} - /> - , - 11, - ); + act(() => { + ReactFabric.render( + + { + viewRef = ref; + }} + /> + { + otherRef = ref; + }} + /> + , + 11, + ); + }); expect(nativeFabricUIManager.measureLayout).not.toBeCalled(); const successCallback = jest.fn(); @@ -483,12 +525,16 @@ describe('ReactFabric', () => { const before = 'abcdefghijklmnopqrst'; const after = 'mxhpgwfralkeoivcstzy'; - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); expect( nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(), ).toMatchSnapshot(); - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); expect( nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(), ).toMatchSnapshot(); @@ -521,12 +567,14 @@ describe('ReactFabric', () => { const ref = React.createRef(); // Wrap in a host node. - ReactFabric.render( - - - , - 11, - ); + act(() => { + ReactFabric.render( + + + , + 11, + ); + }); expect( nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(), ).toMatchSnapshot(); @@ -552,7 +600,9 @@ describe('ReactFabric', () => { } } - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); expect(mockArgs.length).toEqual(0); }); @@ -572,12 +622,14 @@ describe('ReactFabric', () => { ); }); - ReactFabric.render( - - - , - 22, - ); + act(() => { + ReactFabric.render( + + + , + 22, + ); + }); expect(snapshots).toMatchSnapshot(); }); @@ -595,19 +647,23 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - ReactFabric.render( - - - , - 11, - ); + act(() => { + ReactFabric.render( + + + , + 11, + ); + }); - ReactFabric.render( - - - , - 11, - ); + act(() => { + ReactFabric.render( + + + , + 11, + ); + }); }); it('should throw for text not inside of a ancestor', () => { @@ -624,18 +680,22 @@ describe('ReactFabric', () => { uiViewClassName: 'RCTView', })); - expect(() => ReactFabric.render(this should warn, 11)).toThrow( - 'Text strings must be rendered within a component.', - ); + expect(() => { + act(() => { + ReactFabric.render(this should warn, 11); + }); + }).toThrow('Text strings must be rendered within a component.'); - expect(() => - ReactFabric.render( - - hi hello hi - , - 11, - ), - ).toThrow('Text strings must be rendered within a component.'); + expect(() => { + act(() => { + ReactFabric.render( + + hi hello hi + , + 11, + ); + }); + }).toThrow('Text strings must be rendered within a component.'); }); it('should not throw for text inside of an indirect ancestor', () => { @@ -646,12 +706,14 @@ describe('ReactFabric', () => { const Indirection = () => 'Hi'; - ReactFabric.render( - - - , - 11, - ); + act(() => { + ReactFabric.render( + + + , + 11, + ); + }); }); it('dispatches events to the last committed props', () => { @@ -668,7 +730,9 @@ describe('ReactFabric', () => { const touchStart = jest.fn(); const touchStart2 = jest.fn(); - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); expect(nativeFabricUIManager.createNode.mock.calls.length).toBe(1); expect(nativeFabricUIManager.registerEventHandler.mock.calls.length).toBe( @@ -698,7 +762,9 @@ describe('ReactFabric', () => { expect(touchStart).toBeCalled(); expect(touchStart2).not.toBeCalled(); - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); // Intentionally dispatch to the same instanceHandle again. dispatchEvent(instanceHandle, 'topTouchStart', touchEvent); @@ -742,33 +808,35 @@ describe('ReactFabric', () => { const ref1 = React.createRef(); const ref2 = React.createRef(); - ReactFabric.render( - - { - expect(ref1.current).not.toBeNull(); - // Check for referential equality - expect(ref1.current).toBe(event.target); - expect(ref1.current).toBe(event.currentTarget); - }} - onStartShouldSetResponder={() => true} - /> - { - expect(ref2.current).not.toBeNull(); - // Check for referential equality - expect(ref2.current).toBe(event.target); - expect(ref2.current).toBe(event.currentTarget); - }} - onStartShouldSetResponder={() => true} - /> - , - 1, - ); + act(() => { + ReactFabric.render( + + { + expect(ref1.current).not.toBeNull(); + // Check for referential equality + expect(ref1.current).toBe(event.target); + expect(ref1.current).toBe(event.currentTarget); + }} + onStartShouldSetResponder={() => true} + /> + { + expect(ref2.current).not.toBeNull(); + // Check for referential equality + expect(ref2.current).toBe(event.target); + expect(ref2.current).toBe(event.currentTarget); + }} + onStartShouldSetResponder={() => true} + /> + , + 1, + ); + }); const [ dispatchEvent, @@ -823,7 +891,12 @@ describe('ReactFabric', () => { } } - ReactFabric.render( (parent = n)} />, 11); + act(() => { + ReactFabric.render( + (parent = n)} />, + 11, + ); + }); let match; expect( @@ -855,12 +928,14 @@ describe('ReactFabric', () => { } } - ReactFabric.render( - - (parent = n)} /> - , - 11, - ); + act(() => { + ReactFabric.render( + + (parent = n)} /> + , + 11, + ); + }); let match; expect( @@ -896,7 +971,12 @@ describe('ReactFabric', () => { } } - ReactFabric.render( (parent = n)} />, 11); + act(() => { + ReactFabric.render( + (parent = n)} />, + 11, + ); + }); let match; expect(() => (match = ReactFabric.findNodeHandle(parent))).toErrorDev([ @@ -926,12 +1006,14 @@ describe('ReactFabric', () => { } } - ReactFabric.render( - - (parent = n)} /> - , - 11, - ); + act(() => { + ReactFabric.render( + + (parent = n)} /> + , + 11, + ); + }); let match; expect(() => (match = ReactFabric.findNodeHandle(parent))).toErrorDev([ @@ -953,7 +1035,9 @@ describe('ReactFabric', () => { })); const viewRef = React.createRef(); - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); expect(TextInputState.blurTextInput).not.toBeCalled(); @@ -970,7 +1054,9 @@ describe('ReactFabric', () => { })); const viewRef = React.createRef(); - ReactFabric.render(, 11); + act(() => { + ReactFabric.render(, 11); + }); expect(TextInputState.focusTextInput).not.toBeCalled();