'use strict';
import * as React from 'react';
beforeEach(() => {
jest.resetModules();
jest.restoreAllMocks();
require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');
});
async function mockRenderKeys(keyLists) {
const ReactFabric = require('react-native-renderer/fabric');
const createReactNativeComponentClass =
require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
.ReactNativeViewConfigRegistry.register;
const act = require('internal-test-utils').act;
const mockContainerTag = 11;
const MockView = createReactNativeComponentClass('RCTMockView', () => ({
validAttributes: {foo: true},
uiViewClassName: 'RCTMockView',
}));
const result = [];
for (let i = 0; i < keyLists.length; i++) {
const keyList = keyLists[i];
if (Array.isArray(keyList)) {
const refs = keyList.map(key => undefined);
await act(() => {
ReactFabric.render(
<MockView>
{keyList.map((key, index) => (
<MockView
key={key}
ref={ref => {
refs[index] = ref;
}}
/>
))}
</MockView>,
mockContainerTag,
);
});
result.push([...refs]);
continue;
}
if (keyList == null) {
await act(() => {
ReactFabric.stopSurface(mockContainerTag);
});
result.push(null);
continue;
}
throw new TypeError(
`Invalid 'keyLists' element of type ${typeof keyList}.`,
);
}
return result;
}
describe('blur', () => {
test('blur() invokes TextInputState', async () => {
const {
TextInputState,
} = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
const [[fooRef]] = await mockRenderKeys([['foo']]);
fooRef.blur();
expect(TextInputState.blurTextInput.mock.calls).toEqual([[fooRef]]);
});
});
describe('focus', () => {
test('focus() invokes TextInputState', async () => {
const {
TextInputState,
} = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
const [[fooRef]] = await mockRenderKeys([['foo']]);
fooRef.focus();
expect(TextInputState.focusTextInput.mock.calls).toEqual([[fooRef]]);
});
});
describe('measure', () => {
test('component.measure(...) invokes callback', async () => {
const [[fooRef]] = await mockRenderKeys([['foo']]);
const callback = jest.fn();
fooRef.measure(callback);
expect(nativeFabricUIManager.measure).toHaveBeenCalledTimes(1);
expect(callback.mock.calls).toEqual([[10, 10, 100, 100, 0, 0]]);
});
test('unmounted.measure(...) does nothing', async () => {
const [[fooRef]] = await mockRenderKeys([['foo'], null]);
const callback = jest.fn();
fooRef.measure(callback);
expect(nativeFabricUIManager.measure).not.toHaveBeenCalled();
expect(callback).not.toHaveBeenCalled();
});
});
describe('measureInWindow', () => {
test('component.measureInWindow(...) invokes callback', async () => {
const [[fooRef]] = await mockRenderKeys([['foo']]);
const callback = jest.fn();
fooRef.measureInWindow(callback);
expect(nativeFabricUIManager.measureInWindow).toHaveBeenCalledTimes(1);
expect(callback.mock.calls).toEqual([[10, 10, 100, 100]]);
});
test('unmounted.measureInWindow(...) does nothing', async () => {
const [[fooRef]] = await mockRenderKeys([['foo'], null]);
const callback = jest.fn();
fooRef.measureInWindow(callback);
expect(nativeFabricUIManager.measureInWindow).not.toHaveBeenCalled();
expect(callback).not.toHaveBeenCalled();
});
});
describe('measureLayout', () => {
test('component.measureLayout(component, ...) invokes callback', async () => {
const [[fooRef, barRef]] = await mockRenderKeys([['foo', 'bar']]);
const successCallback = jest.fn();
const failureCallback = jest.fn();
fooRef.measureLayout(barRef, successCallback, failureCallback);
expect(nativeFabricUIManager.measureLayout).toHaveBeenCalledTimes(1);
expect(successCallback.mock.calls).toEqual([[1, 1, 100, 100]]);
});
test('unmounted.measureLayout(component, ...) does nothing', async () => {
const [[fooRef, barRef]] = await mockRenderKeys([
['foo', 'bar'],
['foo', null],
]);
const successCallback = jest.fn();
const failureCallback = jest.fn();
fooRef.measureLayout(barRef, successCallback, failureCallback);
expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled();
expect(successCallback).not.toHaveBeenCalled();
});
test('component.measureLayout(unmounted, ...) does nothing', async () => {
const [[fooRef, barRef]] = await mockRenderKeys([
['foo', 'bar'],
[null, 'bar'],
]);
const successCallback = jest.fn();
const failureCallback = jest.fn();
fooRef.measureLayout(barRef, successCallback, failureCallback);
expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled();
expect(successCallback).not.toHaveBeenCalled();
});
test('unmounted.measureLayout(unmounted, ...) does nothing', async () => {
const [[fooRef, barRef]] = await mockRenderKeys([['foo', 'bar'], null]);
const successCallback = jest.fn();
const failureCallback = jest.fn();
fooRef.measureLayout(barRef, successCallback, failureCallback);
expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled();
expect(successCallback).not.toHaveBeenCalled();
});
});
describe('unstable_getBoundingClientRect', () => {
test('component.unstable_getBoundingClientRect() returns DOMRect', async () => {
const [[fooRef]] = await mockRenderKeys([['foo']]);
const rect = fooRef.unstable_getBoundingClientRect();
expect(nativeFabricUIManager.getBoundingClientRect).toHaveBeenCalledTimes(
1,
);
expect(rect.toJSON()).toMatchObject({
x: 10,
y: 10,
width: 100,
height: 100,
});
});
test('unmounted.unstable_getBoundingClientRect() returns empty DOMRect', async () => {
const [[fooRef]] = await mockRenderKeys([['foo'], null]);
const rect = fooRef.unstable_getBoundingClientRect();
expect(nativeFabricUIManager.getBoundingClientRect).not.toHaveBeenCalled();
expect(rect.toJSON()).toMatchObject({x: 0, y: 0, width: 0, height: 0});
});
});
describe('setNativeProps', () => {
test('setNativeProps(...) invokes setNativeProps on Fabric UIManager', async () => {
const {
UIManager,
} = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
const [[fooRef]] = await mockRenderKeys([['foo']]);
fooRef.setNativeProps({foo: 'baz'});
expect(UIManager.updateView).not.toBeCalled();
expect(nativeFabricUIManager.setNativeProps).toHaveBeenCalledTimes(1);
});
});