Skip to content

Separate unit tests for ReactFabricHostComponent #21969

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,9 @@
let React;
let ReactFabric;
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';

const DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT =
"Warning: dispatchCommand was called with a ref that isn't a " +
'native component. Use React.forwardRef to get access to the underlying native component';
Expand All @@ -42,12 +37,8 @@ describe('ReactFabric', () => {
React = require('react');
StrictMode = React.StrictMode;
ReactFabric = require('react-native-renderer/fabric');
UIManager = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
.UIManager;
createReactNativeComponentClass = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
.ReactNativeViewConfigRegistry.register;
TextInputState = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
.TextInputState;

act = require('jest-react').act;
});
Expand Down Expand Up @@ -227,44 +218,6 @@ describe('ReactFabric', () => {
).toMatchSnapshot();
});

it('should not call UIManager.updateView from ref.setNativeProps', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

UIManager.updateView.mockReset();

let viewRef;
act(() => {
ReactFabric.render(
<View
foo="bar"
ref={ref => {
viewRef = ref;
}}
/>,
11,
);
});
expect(UIManager.updateView).not.toBeCalled();

expect(() => {
viewRef.setNativeProps({});
}).toErrorDev([SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE], {
withoutStack: true,
});

expect(UIManager.updateView).not.toBeCalled();

expect(() => {
viewRef.setNativeProps({foo: 'baz'});
}).toErrorDev([SET_NATIVE_PROPS_NOT_SUPPORTED_MESSAGE], {
withoutStack: true,
});
expect(UIManager.updateView).not.toBeCalled();
});

it('should call dispatchCommand for native refs', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -386,275 +339,6 @@ describe('ReactFabric', () => {
expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
});

it('should call FabricUIManager.measure on ref.measure', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

nativeFabricUIManager.measure.mockClear();

let viewRef;
act(() => {
ReactFabric.render(
<View
ref={ref => {
viewRef = ref;
}}
/>,
11,
);
});

expect(nativeFabricUIManager.measure).not.toBeCalled();
const successCallback = jest.fn();
viewRef.measure(successCallback);
expect(nativeFabricUIManager.measure).toHaveBeenCalledTimes(1);
expect(successCallback).toHaveBeenCalledTimes(1);
expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100, 0, 0);
});

it('should no-op if calling measure on unmounted refs', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

nativeFabricUIManager.measure.mockClear();

let viewRef;
act(() => {
ReactFabric.render(
<View
ref={ref => {
viewRef = ref;
}}
/>,
11,
);
});
const dangerouslyRetainedViewRef = viewRef;
act(() => {
ReactFabric.stopSurface(11);
});

expect(nativeFabricUIManager.measure).not.toBeCalled();
const successCallback = jest.fn();
dangerouslyRetainedViewRef.measure(successCallback);
expect(nativeFabricUIManager.measure).not.toBeCalled();
expect(successCallback).not.toBeCalled();
});

it('should call FabricUIManager.measureInWindow on ref.measureInWindow', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

nativeFabricUIManager.measureInWindow.mockClear();

let viewRef;
act(() => {
ReactFabric.render(
<View
ref={ref => {
viewRef = ref;
}}
/>,
11,
);
});

expect(nativeFabricUIManager.measureInWindow).not.toBeCalled();
const successCallback = jest.fn();
viewRef.measureInWindow(successCallback);
expect(nativeFabricUIManager.measureInWindow).toHaveBeenCalledTimes(1);
expect(successCallback).toHaveBeenCalledTimes(1);
expect(successCallback).toHaveBeenCalledWith(10, 10, 100, 100);
});

it('should no-op if calling measureInWindow on unmounted refs', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

nativeFabricUIManager.measureInWindow.mockClear();

let viewRef;
act(() => {
ReactFabric.render(
<View
ref={ref => {
viewRef = ref;
}}
/>,
11,
);
});
const dangerouslyRetainedViewRef = viewRef;
act(() => {
ReactFabric.stopSurface(11);
});

expect(nativeFabricUIManager.measureInWindow).not.toBeCalled();
const successCallback = jest.fn();
dangerouslyRetainedViewRef.measureInWindow(successCallback);
expect(nativeFabricUIManager.measureInWindow).not.toBeCalled();
expect(successCallback).not.toBeCalled();
});

it('should support ref in ref.measureLayout', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

nativeFabricUIManager.measureLayout.mockClear();

let viewRef;
let otherRef;
act(() => {
ReactFabric.render(
<View>
<View
foo="bar"
ref={ref => {
viewRef = ref;
}}
/>
<View
ref={ref => {
otherRef = ref;
}}
/>
</View>,
11,
);
});

expect(nativeFabricUIManager.measureLayout).not.toBeCalled();
const successCallback = jest.fn();
const failureCallback = jest.fn();
viewRef.measureLayout(otherRef, successCallback, failureCallback);
expect(nativeFabricUIManager.measureLayout).toHaveBeenCalledTimes(1);
expect(successCallback).toHaveBeenCalledTimes(1);
expect(successCallback).toHaveBeenCalledWith(1, 1, 100, 100);
});

it('should no-op if calling measureLayout on unmounted "from" ref', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

nativeFabricUIManager.measureLayout.mockClear();

let viewRef;
let otherRef;
act(() => {
ReactFabric.render(
<View>
<View
foo="bar"
ref={ref => {
viewRef = ref;
}}
/>
<View
ref={ref => {
otherRef = ref;
}}
/>
</View>,
11,
);
});
const dangerouslyRetainedOtherRef = otherRef;
act(() => {
ReactFabric.render(
<View>
<View
foo="bar"
ref={ref => {
viewRef = ref;
}}
/>
{null}
</View>,
11,
);
});

expect(nativeFabricUIManager.measureLayout).not.toBeCalled();
const successCallback = jest.fn();
const failureCallback = jest.fn();
viewRef.measureLayout(
dangerouslyRetainedOtherRef,
successCallback,
failureCallback,
);
expect(nativeFabricUIManager.measureLayout).not.toBeCalled();
expect(successCallback).not.toBeCalled();
expect(failureCallback).not.toBeCalled();
});

it('should no-op if calling measureLayout on unmounted "to" ref', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

nativeFabricUIManager.measureLayout.mockClear();

let viewRef;
let otherRef;
act(() => {
ReactFabric.render(
<View>
<View
foo="bar"
ref={ref => {
viewRef = ref;
}}
/>
<View
ref={ref => {
otherRef = ref;
}}
/>
</View>,
11,
);
});
const dangerouslyRetainedViewRef = viewRef;
act(() => {
ReactFabric.render(
<View>
{null}
<View
ref={ref => {
otherRef = ref;
}}
/>
</View>,
11,
);
});

expect(nativeFabricUIManager.measureLayout).not.toBeCalled();
const successCallback = jest.fn();
const failureCallback = jest.fn();
dangerouslyRetainedViewRef.measureLayout(
otherRef,
successCallback,
failureCallback,
);
expect(nativeFabricUIManager.measureLayout).not.toBeCalled();
expect(successCallback).not.toBeCalled();
expect(failureCallback).not.toBeCalled();
});

it('returns the correct instance and calls it in the callback', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down Expand Up @@ -1202,44 +886,6 @@ describe('ReactFabric', () => {
expect(match).toBe(child._nativeTag);
});

it('blur on host component calls TextInputState', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

const viewRef = React.createRef();
act(() => {
ReactFabric.render(<View ref={viewRef} />, 11);
});

expect(TextInputState.blurTextInput).not.toBeCalled();

viewRef.current.blur();

expect(TextInputState.blurTextInput).toHaveBeenCalledTimes(1);
expect(TextInputState.blurTextInput).toHaveBeenCalledWith(viewRef.current);
});

it('focus on host component calls TextInputState', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTView',
}));

const viewRef = React.createRef();
act(() => {
ReactFabric.render(<View ref={viewRef} />, 11);
});

expect(TextInputState.focusTextInput).not.toBeCalled();

viewRef.current.focus();

expect(TextInputState.focusTextInput).toHaveBeenCalledTimes(1);
expect(TextInputState.focusTextInput).toHaveBeenCalledWith(viewRef.current);
});

it('should no-op if calling sendAccessibilityEvent on unmounted refs', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {foo: true},
Expand Down
Loading