1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @emails react-core
    
  8.  * @jest-environment node
    
  9.  */
    
  10. 
    
  11. 'use strict';
    
  12. 
    
  13. let React;
    
  14. let ReactFabric;
    
  15. let ReactNative;
    
  16. let UIManager;
    
  17. let createReactNativeComponentClass;
    
  18. let ReactNativePrivateInterface;
    
  19. let getNativeTagFromPublicInstance;
    
  20. 
    
  21. describe('created with ReactFabric called with ReactNative', () => {
    
  22.   beforeEach(() => {
    
  23.     jest.resetModules();
    
  24.     require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');
    
  25.     ReactNative = require('react-native-renderer');
    
  26.     jest.resetModules();
    
  27.     ReactNativePrivateInterface = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
    
  28.     UIManager =
    
  29.       require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').UIManager;
    
  30.     jest.mock('shared/ReactFeatureFlags', () =>
    
  31.       require('shared/forks/ReactFeatureFlags.native-oss'),
    
  32.     );
    
  33. 
    
  34.     React = require('react');
    
  35.     ReactFabric = require('react-native-renderer/fabric');
    
  36.     createReactNativeComponentClass =
    
  37.       require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
    
  38.         .ReactNativeViewConfigRegistry.register;
    
  39.     getNativeTagFromPublicInstance =
    
  40.       require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').getNativeTagFromPublicInstance;
    
  41.   });
    
  42. 
    
  43.   it('find Fabric instances with the RN renderer', () => {
    
  44.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  45.       validAttributes: {title: true},
    
  46.       uiViewClassName: 'RCTView',
    
  47.     }));
    
  48. 
    
  49.     const ref = React.createRef();
    
  50. 
    
  51.     class Component extends React.Component {
    
  52.       render() {
    
  53.         return <View title="foo" />;
    
  54.       }
    
  55.     }
    
  56. 
    
  57.     ReactFabric.render(<Component ref={ref} />, 11);
    
  58. 
    
  59.     const instance = ReactNative.findHostInstance_DEPRECATED(ref.current);
    
  60.     expect(getNativeTagFromPublicInstance(instance)).toBe(2);
    
  61.   });
    
  62. 
    
  63.   it('find Fabric nodes with the RN renderer', () => {
    
  64.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  65.       validAttributes: {title: true},
    
  66.       uiViewClassName: 'RCTView',
    
  67.     }));
    
  68. 
    
  69.     const ref = React.createRef();
    
  70. 
    
  71.     class Component extends React.Component {
    
  72.       render() {
    
  73.         return <View title="foo" />;
    
  74.       }
    
  75.     }
    
  76. 
    
  77.     ReactFabric.render(<Component ref={ref} />, 11);
    
  78. 
    
  79.     const handle = ReactNative.findNodeHandle(ref.current);
    
  80.     expect(handle).toBe(2);
    
  81.   });
    
  82. 
    
  83.   it('dispatches commands on Fabric nodes with the RN renderer', () => {
    
  84.     nativeFabricUIManager.dispatchCommand.mockClear();
    
  85.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  86.       validAttributes: {title: true},
    
  87.       uiViewClassName: 'RCTView',
    
  88.     }));
    
  89. 
    
  90.     const ref = React.createRef();
    
  91. 
    
  92.     ReactFabric.render(<View title="bar" ref={ref} />, 11);
    
  93.     expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
    
  94.     ReactNative.dispatchCommand(ref.current, 'myCommand', [10, 20]);
    
  95.     expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledTimes(1);
    
  96.     expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledWith(
    
  97.       expect.any(Object),
    
  98.       'myCommand',
    
  99.       [10, 20],
    
  100.     );
    
  101.     expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
    
  102.   });
    
  103. 
    
  104.   it('dispatches sendAccessibilityEvent on Fabric nodes with the RN renderer', () => {
    
  105.     nativeFabricUIManager.sendAccessibilityEvent.mockClear();
    
  106.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  107.       validAttributes: {title: true},
    
  108.       uiViewClassName: 'RCTView',
    
  109.     }));
    
  110. 
    
  111.     const ref = React.createRef();
    
  112. 
    
  113.     ReactFabric.render(<View title="bar" ref={ref} />, 11);
    
  114.     expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
    
  115.     ReactNative.sendAccessibilityEvent(ref.current, 'focus');
    
  116.     expect(nativeFabricUIManager.sendAccessibilityEvent).toHaveBeenCalledTimes(
    
  117.       1,
    
  118.     );
    
  119.     expect(nativeFabricUIManager.sendAccessibilityEvent).toHaveBeenCalledWith(
    
  120.       expect.any(Object),
    
  121.       'focus',
    
  122.     );
    
  123.     expect(UIManager.sendAccessibilityEvent).not.toBeCalled();
    
  124.   });
    
  125. });
    
  126. 
    
  127. describe('created with ReactNative called with ReactFabric', () => {
    
  128.   beforeEach(() => {
    
  129.     jest.resetModules();
    
  130.     require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');
    
  131.     ReactFabric = require('react-native-renderer/fabric');
    
  132.     jest.resetModules();
    
  133.     UIManager =
    
  134.       require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').UIManager;
    
  135.     jest.mock('shared/ReactFeatureFlags', () =>
    
  136.       require('shared/forks/ReactFeatureFlags.native-oss'),
    
  137.     );
    
  138.     ReactNative = require('react-native-renderer');
    
  139. 
    
  140.     React = require('react');
    
  141.     createReactNativeComponentClass =
    
  142.       require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
    
  143.         .ReactNativeViewConfigRegistry.register;
    
  144.   });
    
  145. 
    
  146.   it('find Paper instances with the Fabric renderer', () => {
    
  147.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  148.       validAttributes: {title: true},
    
  149.       uiViewClassName: 'RCTView',
    
  150.     }));
    
  151. 
    
  152.     const ref = React.createRef();
    
  153. 
    
  154.     class Component extends React.Component {
    
  155.       render() {
    
  156.         return <View title="foo" />;
    
  157.       }
    
  158.     }
    
  159. 
    
  160.     ReactNative.render(<Component ref={ref} />, 11);
    
  161. 
    
  162.     const instance = ReactFabric.findHostInstance_DEPRECATED(ref.current);
    
  163.     expect(instance._nativeTag).toBe(3);
    
  164.   });
    
  165. 
    
  166.   it('find Paper nodes with the Fabric renderer', () => {
    
  167.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  168.       validAttributes: {title: true},
    
  169.       uiViewClassName: 'RCTView',
    
  170.     }));
    
  171. 
    
  172.     const ref = React.createRef();
    
  173. 
    
  174.     class Component extends React.Component {
    
  175.       render() {
    
  176.         return <View title="foo" />;
    
  177.       }
    
  178.     }
    
  179. 
    
  180.     ReactNative.render(<Component ref={ref} />, 11);
    
  181. 
    
  182.     const handle = ReactFabric.findNodeHandle(ref.current);
    
  183.     expect(handle).toBe(3);
    
  184.   });
    
  185. 
    
  186.   it('dispatches commands on Paper nodes with the Fabric renderer', () => {
    
  187.     UIManager.dispatchViewManagerCommand.mockReset();
    
  188.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  189.       validAttributes: {title: true},
    
  190.       uiViewClassName: 'RCTView',
    
  191.     }));
    
  192. 
    
  193.     const ref = React.createRef();
    
  194. 
    
  195.     ReactNative.render(<View title="bar" ref={ref} />, 11);
    
  196.     expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
    
  197.     ReactFabric.dispatchCommand(ref.current, 'myCommand', [10, 20]);
    
  198.     expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledTimes(1);
    
  199.     expect(UIManager.dispatchViewManagerCommand).toHaveBeenCalledWith(
    
  200.       expect.any(Number),
    
  201.       'myCommand',
    
  202.       [10, 20],
    
  203.     );
    
  204. 
    
  205.     expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
    
  206.   });
    
  207. 
    
  208.   it('dispatches sendAccessibilityEvent on Paper nodes with the Fabric renderer', () => {
    
  209.     ReactNativePrivateInterface.legacySendAccessibilityEvent.mockReset();
    
  210.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  211.       validAttributes: {title: true},
    
  212.       uiViewClassName: 'RCTView',
    
  213.     }));
    
  214. 
    
  215.     const ref = React.createRef();
    
  216. 
    
  217.     ReactNative.render(<View title="bar" ref={ref} />, 11);
    
  218.     expect(
    
  219.       ReactNativePrivateInterface.legacySendAccessibilityEvent,
    
  220.     ).not.toBeCalled();
    
  221.     ReactFabric.sendAccessibilityEvent(ref.current, 'focus');
    
  222.     expect(
    
  223.       ReactNativePrivateInterface.legacySendAccessibilityEvent,
    
  224.     ).toHaveBeenCalledTimes(1);
    
  225.     expect(
    
  226.       ReactNativePrivateInterface.legacySendAccessibilityEvent,
    
  227.     ).toHaveBeenCalledWith(expect.any(Number), 'focus');
    
  228. 
    
  229.     expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
    
  230.   });
    
  231. });