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 ReactNativePrivateInterface;
    
  16. let createReactNativeComponentClass;
    
  17. let StrictMode;
    
  18. let act;
    
  19. 
    
  20. const DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT =
    
  21.   "Warning: dispatchCommand was called with a ref that isn't a " +
    
  22.   'native component. Use React.forwardRef to get access to the underlying native component';
    
  23. 
    
  24. const SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT =
    
  25.   "sendAccessibilityEvent was called with a ref that isn't a " +
    
  26.   'native component. Use React.forwardRef to get access to the underlying native component';
    
  27. 
    
  28. jest.mock('shared/ReactFeatureFlags', () =>
    
  29.   require('shared/forks/ReactFeatureFlags.native-oss'),
    
  30. );
    
  31. 
    
  32. describe('ReactFabric', () => {
    
  33.   beforeEach(() => {
    
  34.     jest.resetModules();
    
  35. 
    
  36.     require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');
    
  37. 
    
  38.     React = require('react');
    
  39.     StrictMode = React.StrictMode;
    
  40.     ReactFabric = require('react-native-renderer/fabric');
    
  41.     ReactNativePrivateInterface = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
    
  42.     createReactNativeComponentClass =
    
  43.       require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
    
  44.         .ReactNativeViewConfigRegistry.register;
    
  45.     act = require('internal-test-utils').act;
    
  46.   });
    
  47. 
    
  48.   it('should be able to create and render a native component', async () => {
    
  49.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  50.       validAttributes: {foo: true},
    
  51.       uiViewClassName: 'RCTView',
    
  52.     }));
    
  53. 
    
  54.     await act(() => {
    
  55.       ReactFabric.render(<View foo="test" />, 1);
    
  56.     });
    
  57.     expect(nativeFabricUIManager.createNode).toBeCalled();
    
  58.     expect(nativeFabricUIManager.appendChild).not.toBeCalled();
    
  59.     expect(nativeFabricUIManager.completeRoot).toBeCalled();
    
  60.   });
    
  61. 
    
  62.   it('should be able to create and update a native component', async () => {
    
  63.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  64.       validAttributes: {foo: true},
    
  65.       uiViewClassName: 'RCTView',
    
  66.     }));
    
  67. 
    
  68.     const firstNode = {};
    
  69. 
    
  70.     nativeFabricUIManager.createNode.mockReturnValue(firstNode);
    
  71. 
    
  72.     await act(() => {
    
  73.       ReactFabric.render(<View foo="foo" />, 11);
    
  74.     });
    
  75. 
    
  76.     expect(nativeFabricUIManager.createNode).toHaveBeenCalledTimes(1);
    
  77. 
    
  78.     await act(() => {
    
  79.       ReactFabric.render(<View foo="bar" />, 11);
    
  80.     });
    
  81. 
    
  82.     expect(nativeFabricUIManager.createNode).toHaveBeenCalledTimes(1);
    
  83.     expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes(
    
  84.       1,
    
  85.     );
    
  86.     expect(nativeFabricUIManager.cloneNodeWithNewProps.mock.calls[0][0]).toBe(
    
  87.       firstNode,
    
  88.     );
    
  89.     expect(
    
  90.       nativeFabricUIManager.cloneNodeWithNewProps.mock.calls[0][1],
    
  91.     ).toEqual({
    
  92.       foo: 'bar',
    
  93.     });
    
  94.   });
    
  95. 
    
  96.   it('should not call FabricUIManager.cloneNode after render for properties that have not changed', async () => {
    
  97.     const Text = createReactNativeComponentClass('RCTText', () => ({
    
  98.       validAttributes: {foo: true},
    
  99.       uiViewClassName: 'RCTText',
    
  100.     }));
    
  101. 
    
  102.     await act(() => {
    
  103.       ReactFabric.render(<Text foo="a">1</Text>, 11);
    
  104.     });
    
  105.     expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
    
  106.     expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled();
    
  107.     expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled();
    
  108.     expect(
    
  109.       nativeFabricUIManager.cloneNodeWithNewChildrenAndProps,
    
  110.     ).not.toBeCalled();
    
  111. 
    
  112.     // If no properties have changed, we shouldn't call cloneNode.
    
  113.     await act(() => {
    
  114.       ReactFabric.render(<Text foo="a">1</Text>, 11);
    
  115.     });
    
  116.     expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
    
  117.     expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled();
    
  118.     expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled();
    
  119.     expect(
    
  120.       nativeFabricUIManager.cloneNodeWithNewChildrenAndProps,
    
  121.     ).not.toBeCalled();
    
  122. 
    
  123.     // Only call cloneNode for the changed property (and not for text).
    
  124.     await act(() => {
    
  125.       ReactFabric.render(<Text foo="b">1</Text>, 11);
    
  126.     });
    
  127.     expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
    
  128.     expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled();
    
  129.     expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes(
    
  130.       1,
    
  131.     );
    
  132.     expect(
    
  133.       nativeFabricUIManager.cloneNodeWithNewChildrenAndProps,
    
  134.     ).not.toBeCalled();
    
  135. 
    
  136.     // Only call cloneNode for the changed text (and no other properties).
    
  137.     await act(() => {
    
  138.       ReactFabric.render(<Text foo="b">2</Text>, 11);
    
  139.     });
    
  140.     expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
    
  141.     expect(
    
  142.       nativeFabricUIManager.cloneNodeWithNewChildren,
    
  143.     ).toHaveBeenCalledTimes(1);
    
  144.     expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes(
    
  145.       1,
    
  146.     );
    
  147.     expect(
    
  148.       nativeFabricUIManager.cloneNodeWithNewChildrenAndProps,
    
  149.     ).not.toBeCalled();
    
  150. 
    
  151.     // Call cloneNode for both changed text and properties.
    
  152.     await act(() => {
    
  153.       ReactFabric.render(<Text foo="c">3</Text>, 11);
    
  154.     });
    
  155.     expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
    
  156.     expect(
    
  157.       nativeFabricUIManager.cloneNodeWithNewChildren,
    
  158.     ).toHaveBeenCalledTimes(1);
    
  159.     expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes(
    
  160.       1,
    
  161.     );
    
  162.     expect(
    
  163.       nativeFabricUIManager.cloneNodeWithNewChildrenAndProps,
    
  164.     ).toHaveBeenCalledTimes(1);
    
  165.   });
    
  166. 
    
  167.   it('should only pass props diffs to FabricUIManager.cloneNode', async () => {
    
  168.     const Text = createReactNativeComponentClass('RCTText', () => ({
    
  169.       validAttributes: {foo: true, bar: true},
    
  170.       uiViewClassName: 'RCTText',
    
  171.     }));
    
  172. 
    
  173.     await act(() => {
    
  174.       ReactFabric.render(
    
  175.         <Text foo="a" bar="a">
    
  176.           1
    
  177.         </Text>,
    
  178.         11,
    
  179.       );
    
  180.     });
    
  181.     expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
    
  182.     expect(nativeFabricUIManager.cloneNodeWithNewChildren).not.toBeCalled();
    
  183.     expect(nativeFabricUIManager.cloneNodeWithNewProps).not.toBeCalled();
    
  184.     expect(
    
  185.       nativeFabricUIManager.cloneNodeWithNewChildrenAndProps,
    
  186.     ).not.toBeCalled();
    
  187. 
    
  188.     await act(() => {
    
  189.       ReactFabric.render(
    
  190.         <Text foo="a" bar="b">
    
  191.           1
    
  192.         </Text>,
    
  193.         11,
    
  194.       );
    
  195.     });
    
  196.     expect(
    
  197.       nativeFabricUIManager.cloneNodeWithNewProps.mock.calls[0][1],
    
  198.     ).toEqual({
    
  199.       bar: 'b',
    
  200.     });
    
  201.     expect(
    
  202.       nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
    
  203.     ).toMatchSnapshot();
    
  204. 
    
  205.     await act(() => {
    
  206.       ReactFabric.render(
    
  207.         <Text foo="b" bar="b">
    
  208.           2
    
  209.         </Text>,
    
  210.         11,
    
  211.       );
    
  212.     });
    
  213.     const argIndex = gate(flags => flags.passChildrenWhenCloningPersistedNodes)
    
  214.       ? 2
    
  215.       : 1;
    
  216.     expect(
    
  217.       nativeFabricUIManager.cloneNodeWithNewChildrenAndProps.mock.calls[0][
    
  218.         argIndex
    
  219.       ],
    
  220.     ).toEqual({
    
  221.       foo: 'b',
    
  222.     });
    
  223.     expect(
    
  224.       nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
    
  225.     ).toMatchSnapshot();
    
  226.   });
    
  227. 
    
  228.   it('should not clone nodes without children when updating props', async () => {
    
  229.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  230.       validAttributes: {foo: true},
    
  231.       uiViewClassName: 'RCTView',
    
  232.     }));
    
  233. 
    
  234.     const Component = ({foo}) => (
    
  235.       <View>
    
  236.         <View foo={foo} />
    
  237.       </View>
    
  238.     );
    
  239. 
    
  240.     await act(() => ReactFabric.render(<Component foo={true} />, 11));
    
  241.     expect(nativeFabricUIManager.completeRoot).toBeCalled();
    
  242.     jest.clearAllMocks();
    
  243. 
    
  244.     await act(() => ReactFabric.render(<Component foo={false} />, 11));
    
  245.     expect(nativeFabricUIManager.cloneNode).not.toBeCalled();
    
  246.     expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledTimes(
    
  247.       1,
    
  248.     );
    
  249.     expect(nativeFabricUIManager.cloneNodeWithNewProps).toHaveBeenCalledWith(
    
  250.       expect.anything(),
    
  251.       {foo: false},
    
  252.     );
    
  253. 
    
  254.     expect(
    
  255.       nativeFabricUIManager.cloneNodeWithNewChildren,
    
  256.     ).toHaveBeenCalledTimes(1);
    
  257.     if (gate(flags => flags.passChildrenWhenCloningPersistedNodes)) {
    
  258.       expect(
    
  259.         nativeFabricUIManager.cloneNodeWithNewChildren,
    
  260.       ).toHaveBeenCalledWith(expect.anything(), [
    
  261.         expect.objectContaining({props: {foo: false}}),
    
  262.       ]);
    
  263.       expect(nativeFabricUIManager.appendChild).not.toBeCalled();
    
  264.     } else {
    
  265.       expect(
    
  266.         nativeFabricUIManager.cloneNodeWithNewChildren,
    
  267.       ).toHaveBeenCalledWith(expect.anything());
    
  268.       expect(nativeFabricUIManager.appendChild).toHaveBeenCalledTimes(1);
    
  269.     }
    
  270.     expect(
    
  271.       nativeFabricUIManager.cloneNodeWithNewChildrenAndProps,
    
  272.     ).not.toBeCalled();
    
  273.     expect(nativeFabricUIManager.completeRoot).toBeCalled();
    
  274.   });
    
  275. 
    
  276.   it('should call dispatchCommand for native refs', async () => {
    
  277.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  278.       validAttributes: {foo: true},
    
  279.       uiViewClassName: 'RCTView',
    
  280.     }));
    
  281. 
    
  282.     nativeFabricUIManager.dispatchCommand.mockClear();
    
  283. 
    
  284.     let viewRef;
    
  285.     await act(() => {
    
  286.       ReactFabric.render(
    
  287.         <View
    
  288.           ref={ref => {
    
  289.             viewRef = ref;
    
  290.           }}
    
  291.         />,
    
  292.         11,
    
  293.       );
    
  294.     });
    
  295. 
    
  296.     expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
    
  297.     ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]);
    
  298.     expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledTimes(1);
    
  299.     expect(nativeFabricUIManager.dispatchCommand).toHaveBeenCalledWith(
    
  300.       expect.any(Object),
    
  301.       'updateCommand',
    
  302.       [10, 20],
    
  303.     );
    
  304.   });
    
  305. 
    
  306.   it('should warn and no-op if calling dispatchCommand on non native refs', async () => {
    
  307.     class BasicClass extends React.Component {
    
  308.       render() {
    
  309.         return <React.Fragment />;
    
  310.       }
    
  311.     }
    
  312. 
    
  313.     nativeFabricUIManager.dispatchCommand.mockReset();
    
  314. 
    
  315.     let viewRef;
    
  316.     await act(() => {
    
  317.       ReactFabric.render(
    
  318.         <BasicClass
    
  319.           ref={ref => {
    
  320.             viewRef = ref;
    
  321.           }}
    
  322.         />,
    
  323.         11,
    
  324.       );
    
  325.     });
    
  326. 
    
  327.     expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
    
  328.     expect(() => {
    
  329.       ReactFabric.dispatchCommand(viewRef, 'updateCommand', [10, 20]);
    
  330.     }).toErrorDev([DISPATCH_COMMAND_REQUIRES_HOST_COMPONENT], {
    
  331.       withoutStack: true,
    
  332.     });
    
  333. 
    
  334.     expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
    
  335.   });
    
  336. 
    
  337.   it('should call sendAccessibilityEvent for native refs', async () => {
    
  338.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  339.       validAttributes: {foo: true},
    
  340.       uiViewClassName: 'RCTView',
    
  341.     }));
    
  342. 
    
  343.     nativeFabricUIManager.sendAccessibilityEvent.mockClear();
    
  344. 
    
  345.     let viewRef;
    
  346.     await act(() => {
    
  347.       ReactFabric.render(
    
  348.         <View
    
  349.           ref={ref => {
    
  350.             viewRef = ref;
    
  351.           }}
    
  352.         />,
    
  353.         11,
    
  354.       );
    
  355.     });
    
  356. 
    
  357.     expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
    
  358.     ReactFabric.sendAccessibilityEvent(viewRef, 'focus');
    
  359.     expect(nativeFabricUIManager.sendAccessibilityEvent).toHaveBeenCalledTimes(
    
  360.       1,
    
  361.     );
    
  362.     expect(nativeFabricUIManager.sendAccessibilityEvent).toHaveBeenCalledWith(
    
  363.       expect.any(Object),
    
  364.       'focus',
    
  365.     );
    
  366.   });
    
  367. 
    
  368.   it('should warn and no-op if calling sendAccessibilityEvent on non native refs', async () => {
    
  369.     class BasicClass extends React.Component {
    
  370.       render() {
    
  371.         return <React.Fragment />;
    
  372.       }
    
  373.     }
    
  374. 
    
  375.     nativeFabricUIManager.sendAccessibilityEvent.mockReset();
    
  376. 
    
  377.     let viewRef;
    
  378.     await act(() => {
    
  379.       ReactFabric.render(
    
  380.         <BasicClass
    
  381.           ref={ref => {
    
  382.             viewRef = ref;
    
  383.           }}
    
  384.         />,
    
  385.         11,
    
  386.       );
    
  387.     });
    
  388. 
    
  389.     expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
    
  390.     expect(() => {
    
  391.       ReactFabric.sendAccessibilityEvent(viewRef, 'eventTypeName');
    
  392.     }).toErrorDev([SEND_ACCESSIBILITY_EVENT_REQUIRES_HOST_COMPONENT], {
    
  393.       withoutStack: true,
    
  394.     });
    
  395. 
    
  396.     expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
    
  397.   });
    
  398. 
    
  399.   it('returns the correct instance and calls it in the callback', () => {
    
  400.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  401.       validAttributes: {foo: true},
    
  402.       uiViewClassName: 'RCTView',
    
  403.     }));
    
  404. 
    
  405.     let a;
    
  406.     let b;
    
  407.     const c = ReactFabric.render(
    
  408.       <View foo="foo" ref={v => (a = v)} />,
    
  409.       11,
    
  410.       function () {
    
  411.         b = this;
    
  412.       },
    
  413.     );
    
  414. 
    
  415.     expect(a).toBeTruthy();
    
  416.     expect(a).toBe(b);
    
  417.     expect(a).toBe(c);
    
  418.   });
    
  419. 
    
  420.   it('renders and reorders children', async () => {
    
  421.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  422.       validAttributes: {title: true},
    
  423.       uiViewClassName: 'RCTView',
    
  424.     }));
    
  425. 
    
  426.     class Component extends React.Component {
    
  427.       render() {
    
  428.         const chars = this.props.chars.split('');
    
  429.         return (
    
  430.           <View>
    
  431.             {chars.map(text => (
    
  432.               <View key={text} title={text} />
    
  433.             ))}
    
  434.           </View>
    
  435.         );
    
  436.       }
    
  437.     }
    
  438. 
    
  439.     // Mini multi-child stress test: lots of reorders, some adds, some removes.
    
  440.     const before = 'abcdefghijklmnopqrst';
    
  441.     const after = 'mxhpgwfralkeoivcstzy';
    
  442. 
    
  443.     await act(() => {
    
  444.       ReactFabric.render(<Component chars={before} />, 11);
    
  445.     });
    
  446.     expect(
    
  447.       nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
    
  448.     ).toMatchSnapshot();
    
  449. 
    
  450.     await act(() => {
    
  451.       ReactFabric.render(<Component chars={after} />, 11);
    
  452.     });
    
  453.     expect(
    
  454.       nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
    
  455.     ).toMatchSnapshot();
    
  456.   });
    
  457. 
    
  458.   it('recreates host parents even if only children changed', async () => {
    
  459.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  460.       validAttributes: {title: true},
    
  461.       uiViewClassName: 'RCTView',
    
  462.     }));
    
  463. 
    
  464.     const before = 'abcdefghijklmnopqrst';
    
  465.     const after = 'mxhpgwfralkeoivcstzy';
    
  466. 
    
  467.     class Component extends React.Component {
    
  468.       state = {
    
  469.         chars: before,
    
  470.       };
    
  471.       render() {
    
  472.         const chars = this.state.chars.split('');
    
  473.         return (
    
  474.           <View>
    
  475.             {chars.map(text => (
    
  476.               <View key={text} title={text} />
    
  477.             ))}
    
  478.           </View>
    
  479.         );
    
  480.       }
    
  481.     }
    
  482. 
    
  483.     const ref = React.createRef();
    
  484.     // Wrap in a host node.
    
  485.     await act(() => {
    
  486.       ReactFabric.render(
    
  487.         <View>
    
  488.           <Component ref={ref} />
    
  489.         </View>,
    
  490.         11,
    
  491.       );
    
  492.     });
    
  493.     expect(
    
  494.       nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
    
  495.     ).toMatchSnapshot();
    
  496. 
    
  497.     // Call setState() so that we skip over the top-level host node.
    
  498.     // It should still get recreated despite a bailout.
    
  499.     ref.current.setState({
    
  500.       chars: after,
    
  501.     });
    
  502.     expect(
    
  503.       nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
    
  504.     ).toMatchSnapshot();
    
  505.   });
    
  506. 
    
  507.   it('calls setState with no arguments', async () => {
    
  508.     let mockArgs;
    
  509.     class Component extends React.Component {
    
  510.       componentDidMount() {
    
  511.         this.setState({}, (...args) => (mockArgs = args));
    
  512.       }
    
  513.       render() {
    
  514.         return false;
    
  515.       }
    
  516.     }
    
  517. 
    
  518.     await act(() => {
    
  519.       ReactFabric.render(<Component />, 11);
    
  520.     });
    
  521.     expect(mockArgs.length).toEqual(0);
    
  522.   });
    
  523. 
    
  524.   it('should call complete after inserting children', async () => {
    
  525.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  526.       validAttributes: {foo: true},
    
  527.       uiViewClassName: 'RCTView',
    
  528.     }));
    
  529. 
    
  530.     const snapshots = [];
    
  531.     nativeFabricUIManager.completeRoot.mockImplementation(
    
  532.       function (rootTag, newChildSet) {
    
  533.         snapshots.push(
    
  534.           nativeFabricUIManager.__dumpChildSetForJestTestsOnly(newChildSet),
    
  535.         );
    
  536.       },
    
  537.     );
    
  538. 
    
  539.     await act(() => {
    
  540.       ReactFabric.render(
    
  541.         <View foo="a">
    
  542.           <View foo="b" />
    
  543.         </View>,
    
  544.         22,
    
  545.       );
    
  546.     });
    
  547.     expect(snapshots).toMatchSnapshot();
    
  548.   });
    
  549. 
    
  550.   it('should not throw when <View> is used inside of a <Text> ancestor', async () => {
    
  551.     const Image = createReactNativeComponentClass('RCTImage', () => ({
    
  552.       validAttributes: {},
    
  553.       uiViewClassName: 'RCTImage',
    
  554.     }));
    
  555.     const Text = createReactNativeComponentClass('RCTText', () => ({
    
  556.       validAttributes: {},
    
  557.       uiViewClassName: 'RCTText',
    
  558.     }));
    
  559.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  560.       validAttributes: {},
    
  561.       uiViewClassName: 'RCTView',
    
  562.     }));
    
  563. 
    
  564.     await act(() => {
    
  565.       ReactFabric.render(
    
  566.         <Text>
    
  567.           <View />
    
  568.         </Text>,
    
  569.         11,
    
  570.       );
    
  571.     });
    
  572. 
    
  573.     await act(() => {
    
  574.       ReactFabric.render(
    
  575.         <Text>
    
  576.           <Image />
    
  577.         </Text>,
    
  578.         11,
    
  579.       );
    
  580.     });
    
  581.   });
    
  582. 
    
  583.   it('should console error for text not inside of a <Text> ancestor', async () => {
    
  584.     const ScrollView = createReactNativeComponentClass('RCTScrollView', () => ({
    
  585.       validAttributes: {},
    
  586.       uiViewClassName: 'RCTScrollView',
    
  587.     }));
    
  588.     const Text = createReactNativeComponentClass('RCTText', () => ({
    
  589.       validAttributes: {},
    
  590.       uiViewClassName: 'RCTText',
    
  591.     }));
    
  592.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  593.       validAttributes: {},
    
  594.       uiViewClassName: 'RCTView',
    
  595.     }));
    
  596. 
    
  597.     await expect(async () => {
    
  598.       await act(() => {
    
  599.         ReactFabric.render(<View>this should warn</View>, 11);
    
  600.       });
    
  601.     }).toErrorDev(['Text strings must be rendered within a <Text> component.']);
    
  602. 
    
  603.     await expect(async () => {
    
  604.       await act(() => {
    
  605.         ReactFabric.render(
    
  606.           <Text>
    
  607.             <ScrollView>hi hello hi</ScrollView>
    
  608.           </Text>,
    
  609.           11,
    
  610.         );
    
  611.       });
    
  612.     }).toErrorDev(['Text strings must be rendered within a <Text> component.']);
    
  613.   });
    
  614. 
    
  615.   it('should not throw for text inside of an indirect <Text> ancestor', async () => {
    
  616.     const Text = createReactNativeComponentClass('RCTText', () => ({
    
  617.       validAttributes: {},
    
  618.       uiViewClassName: 'RCTText',
    
  619.     }));
    
  620. 
    
  621.     const Indirection = () => 'Hi';
    
  622. 
    
  623.     await act(() => {
    
  624.       ReactFabric.render(
    
  625.         <Text>
    
  626.           <Indirection />
    
  627.         </Text>,
    
  628.         11,
    
  629.       );
    
  630.     });
    
  631.   });
    
  632. 
    
  633.   it('dispatches events to the last committed props', async () => {
    
  634.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  635.       validAttributes: {},
    
  636.       uiViewClassName: 'RCTView',
    
  637.       directEventTypes: {
    
  638.         topTouchStart: {
    
  639.           registrationName: 'onTouchStart',
    
  640.         },
    
  641.       },
    
  642.     }));
    
  643. 
    
  644.     const touchStart = jest.fn();
    
  645.     const touchStart2 = jest.fn();
    
  646. 
    
  647.     await act(() => {
    
  648.       ReactFabric.render(<View onTouchStart={touchStart} />, 11);
    
  649.     });
    
  650. 
    
  651.     expect(nativeFabricUIManager.createNode.mock.calls.length).toBe(1);
    
  652.     expect(nativeFabricUIManager.registerEventHandler.mock.calls.length).toBe(
    
  653.       1,
    
  654.     );
    
  655. 
    
  656.     const [, , , , instanceHandle] =
    
  657.       nativeFabricUIManager.createNode.mock.calls[0];
    
  658.     const [dispatchEvent] =
    
  659.       nativeFabricUIManager.registerEventHandler.mock.calls[0];
    
  660. 
    
  661.     const touchEvent = {
    
  662.       touches: [],
    
  663.       changedTouches: [],
    
  664.     };
    
  665. 
    
  666.     expect(touchStart).not.toBeCalled();
    
  667. 
    
  668.     dispatchEvent(instanceHandle, 'topTouchStart', touchEvent);
    
  669. 
    
  670.     expect(touchStart).toBeCalled();
    
  671.     expect(touchStart2).not.toBeCalled();
    
  672. 
    
  673.     await act(() => {
    
  674.       ReactFabric.render(<View onTouchStart={touchStart2} />, 11);
    
  675.     });
    
  676. 
    
  677.     // Intentionally dispatch to the same instanceHandle again.
    
  678.     dispatchEvent(instanceHandle, 'topTouchStart', touchEvent);
    
  679. 
    
  680.     // The current semantics dictate that we always dispatch to the last committed
    
  681.     // props even though the actual scheduling of the event could have happened earlier.
    
  682.     // This could change in the future.
    
  683.     expect(touchStart2).toBeCalled();
    
  684.   });
    
  685. 
    
  686.   describe('skipBubbling', () => {
    
  687.     it('should skip bubbling to ancestor if specified', async () => {
    
  688.       const View = createReactNativeComponentClass('RCTView', () => ({
    
  689.         validAttributes: {},
    
  690.         uiViewClassName: 'RCTView',
    
  691.         bubblingEventTypes: {
    
  692.           topDefaultBubblingEvent: {
    
  693.             phasedRegistrationNames: {
    
  694.               captured: 'onDefaultBubblingEventCapture',
    
  695.               bubbled: 'onDefaultBubblingEvent',
    
  696.             },
    
  697.           },
    
  698.           topBubblingEvent: {
    
  699.             phasedRegistrationNames: {
    
  700.               captured: 'onBubblingEventCapture',
    
  701.               bubbled: 'onBubblingEvent',
    
  702.               skipBubbling: false,
    
  703.             },
    
  704.           },
    
  705.           topSkipBubblingEvent: {
    
  706.             phasedRegistrationNames: {
    
  707.               captured: 'onSkippedBubblingEventCapture',
    
  708.               bubbled: 'onSkippedBubblingEvent',
    
  709.               skipBubbling: true,
    
  710.             },
    
  711.           },
    
  712.         },
    
  713.       }));
    
  714.       const ancestorBubble = jest.fn();
    
  715.       const ancestorCapture = jest.fn();
    
  716.       const targetBubble = jest.fn();
    
  717.       const targetCapture = jest.fn();
    
  718. 
    
  719.       const event = {};
    
  720. 
    
  721.       await act(() => {
    
  722.         ReactFabric.render(
    
  723.           <View
    
  724.             onSkippedBubblingEventCapture={ancestorCapture}
    
  725.             onDefaultBubblingEventCapture={ancestorCapture}
    
  726.             onBubblingEventCapture={ancestorCapture}
    
  727.             onSkippedBubblingEvent={ancestorBubble}
    
  728.             onDefaultBubblingEvent={ancestorBubble}
    
  729.             onBubblingEvent={ancestorBubble}>
    
  730.             <View
    
  731.               onSkippedBubblingEventCapture={targetCapture}
    
  732.               onDefaultBubblingEventCapture={targetCapture}
    
  733.               onBubblingEventCapture={targetCapture}
    
  734.               onSkippedBubblingEvent={targetBubble}
    
  735.               onDefaultBubblingEvent={targetBubble}
    
  736.               onBubblingEvent={targetBubble}
    
  737.             />
    
  738.           </View>,
    
  739.           11,
    
  740.         );
    
  741.       });
    
  742. 
    
  743.       expect(nativeFabricUIManager.createNode.mock.calls.length).toBe(2);
    
  744.       expect(nativeFabricUIManager.registerEventHandler.mock.calls.length).toBe(
    
  745.         1,
    
  746.       );
    
  747.       const [, , , , childInstance] =
    
  748.         nativeFabricUIManager.createNode.mock.calls[0];
    
  749.       const [dispatchEvent] =
    
  750.         nativeFabricUIManager.registerEventHandler.mock.calls[0];
    
  751. 
    
  752.       dispatchEvent(childInstance, 'topDefaultBubblingEvent', event);
    
  753.       expect(targetBubble).toHaveBeenCalledTimes(1);
    
  754.       expect(targetCapture).toHaveBeenCalledTimes(1);
    
  755.       expect(ancestorCapture).toHaveBeenCalledTimes(1);
    
  756.       expect(ancestorBubble).toHaveBeenCalledTimes(1);
    
  757.       ancestorBubble.mockReset();
    
  758.       ancestorCapture.mockReset();
    
  759.       targetBubble.mockReset();
    
  760.       targetCapture.mockReset();
    
  761. 
    
  762.       dispatchEvent(childInstance, 'topBubblingEvent', event);
    
  763.       expect(targetBubble).toHaveBeenCalledTimes(1);
    
  764.       expect(targetCapture).toHaveBeenCalledTimes(1);
    
  765.       expect(ancestorCapture).toHaveBeenCalledTimes(1);
    
  766.       expect(ancestorBubble).toHaveBeenCalledTimes(1);
    
  767.       ancestorBubble.mockReset();
    
  768.       ancestorCapture.mockReset();
    
  769.       targetBubble.mockReset();
    
  770.       targetCapture.mockReset();
    
  771. 
    
  772.       dispatchEvent(childInstance, 'topSkipBubblingEvent', event);
    
  773.       expect(targetBubble).toHaveBeenCalledTimes(1);
    
  774.       expect(targetCapture).toHaveBeenCalledTimes(1);
    
  775.       expect(ancestorCapture).toHaveBeenCalledTimes(1);
    
  776.       expect(ancestorBubble).not.toBeCalled();
    
  777.     });
    
  778.   });
    
  779. 
    
  780.   it('dispatches event with target as instance', async () => {
    
  781.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  782.       validAttributes: {
    
  783.         id: true,
    
  784.       },
    
  785.       uiViewClassName: 'RCTView',
    
  786.       directEventTypes: {
    
  787.         topTouchStart: {
    
  788.           registrationName: 'onTouchStart',
    
  789.         },
    
  790.         topTouchEnd: {
    
  791.           registrationName: 'onTouchEnd',
    
  792.         },
    
  793.       },
    
  794.     }));
    
  795. 
    
  796.     function getViewById(id) {
    
  797.       const [reactTag, , , , instanceHandle] =
    
  798.         nativeFabricUIManager.createNode.mock.calls.find(
    
  799.           args => args[3] && args[3].id === id,
    
  800.         );
    
  801. 
    
  802.       return {reactTag, instanceHandle};
    
  803.     }
    
  804. 
    
  805.     const ref1 = React.createRef();
    
  806.     const ref2 = React.createRef();
    
  807. 
    
  808.     await act(() => {
    
  809.       ReactFabric.render(
    
  810.         <View id="parent">
    
  811.           <View
    
  812.             ref={ref1}
    
  813.             id="one"
    
  814.             onResponderStart={event => {
    
  815.               expect(ref1.current).not.toBeNull();
    
  816.               // Check for referential equality
    
  817.               expect(ref1.current).toBe(event.target);
    
  818.               expect(ref1.current).toBe(event.currentTarget);
    
  819.             }}
    
  820.             onStartShouldSetResponder={() => true}
    
  821.           />
    
  822.           <View
    
  823.             ref={ref2}
    
  824.             id="two"
    
  825.             onResponderStart={event => {
    
  826.               expect(ref2.current).not.toBeNull();
    
  827.               // Check for referential equality
    
  828.               expect(ref2.current).toBe(event.target);
    
  829.               expect(ref2.current).toBe(event.currentTarget);
    
  830.             }}
    
  831.             onStartShouldSetResponder={() => true}
    
  832.           />
    
  833.         </View>,
    
  834.         1,
    
  835.       );
    
  836.     });
    
  837. 
    
  838.     const [dispatchEvent] =
    
  839.       nativeFabricUIManager.registerEventHandler.mock.calls[0];
    
  840. 
    
  841.     dispatchEvent(getViewById('one').instanceHandle, 'topTouchStart', {
    
  842.       target: getViewById('one').reactTag,
    
  843.       identifier: 17,
    
  844.       touches: [],
    
  845.       changedTouches: [],
    
  846.     });
    
  847.     dispatchEvent(getViewById('one').instanceHandle, 'topTouchEnd', {
    
  848.       target: getViewById('one').reactTag,
    
  849.       identifier: 17,
    
  850.       touches: [],
    
  851.       changedTouches: [],
    
  852.     });
    
  853. 
    
  854.     dispatchEvent(getViewById('two').instanceHandle, 'topTouchStart', {
    
  855.       target: getViewById('two').reactTag,
    
  856.       identifier: 17,
    
  857.       touches: [],
    
  858.       changedTouches: [],
    
  859.     });
    
  860. 
    
  861.     dispatchEvent(getViewById('two').instanceHandle, 'topTouchEnd', {
    
  862.       target: getViewById('two').reactTag,
    
  863.       identifier: 17,
    
  864.       touches: [],
    
  865.       changedTouches: [],
    
  866.     });
    
  867. 
    
  868.     expect.assertions(6);
    
  869.   });
    
  870. 
    
  871.   it('findHostInstance_DEPRECATED should warn if used to find a host component inside StrictMode', async () => {
    
  872.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  873.       validAttributes: {foo: true},
    
  874.       uiViewClassName: 'RCTView',
    
  875.     }));
    
  876. 
    
  877.     let parent = undefined;
    
  878.     let child = undefined;
    
  879. 
    
  880.     class ContainsStrictModeChild extends React.Component {
    
  881.       render() {
    
  882.         return (
    
  883.           <StrictMode>
    
  884.             <View ref={n => (child = n)} />
    
  885.           </StrictMode>
    
  886.         );
    
  887.       }
    
  888.     }
    
  889. 
    
  890.     await act(() => {
    
  891.       ReactFabric.render(
    
  892.         <ContainsStrictModeChild ref={n => (parent = n)} />,
    
  893.         11,
    
  894.       );
    
  895.     });
    
  896. 
    
  897.     let match;
    
  898.     expect(
    
  899.       () => (match = ReactFabric.findHostInstance_DEPRECATED(parent)),
    
  900.     ).toErrorDev([
    
  901.       'Warning: findHostInstance_DEPRECATED is deprecated in StrictMode. ' +
    
  902.         'findHostInstance_DEPRECATED was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' +
    
  903.         'Instead, add a ref directly to the element you want to reference. ' +
    
  904.         'Learn more about using refs safely here: ' +
    
  905.         'https://reactjs.org/link/strict-mode-find-node' +
    
  906.         '\n    in RCTView (at **)' +
    
  907.         '\n    in ContainsStrictModeChild (at **)',
    
  908.     ]);
    
  909.     expect(match).toBe(child);
    
  910.   });
    
  911. 
    
  912.   it('findHostInstance_DEPRECATED should warn if passed a component that is inside StrictMode', async () => {
    
  913.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  914.       validAttributes: {foo: true},
    
  915.       uiViewClassName: 'RCTView',
    
  916.     }));
    
  917. 
    
  918.     let parent = undefined;
    
  919.     let child = undefined;
    
  920. 
    
  921.     class IsInStrictMode extends React.Component {
    
  922.       render() {
    
  923.         return <View ref={n => (child = n)} />;
    
  924.       }
    
  925.     }
    
  926. 
    
  927.     await act(() => {
    
  928.       ReactFabric.render(
    
  929.         <StrictMode>
    
  930.           <IsInStrictMode ref={n => (parent = n)} />
    
  931.         </StrictMode>,
    
  932.         11,
    
  933.       );
    
  934.     });
    
  935. 
    
  936.     let match;
    
  937.     expect(
    
  938.       () => (match = ReactFabric.findHostInstance_DEPRECATED(parent)),
    
  939.     ).toErrorDev([
    
  940.       'Warning: findHostInstance_DEPRECATED is deprecated in StrictMode. ' +
    
  941.         'findHostInstance_DEPRECATED was passed an instance of IsInStrictMode which is inside StrictMode. ' +
    
  942.         'Instead, add a ref directly to the element you want to reference. ' +
    
  943.         'Learn more about using refs safely here: ' +
    
  944.         'https://reactjs.org/link/strict-mode-find-node' +
    
  945.         '\n    in RCTView (at **)' +
    
  946.         '\n    in IsInStrictMode (at **)',
    
  947.     ]);
    
  948.     expect(match).toBe(child);
    
  949.   });
    
  950. 
    
  951.   it('findNodeHandle should warn if used to find a host component inside StrictMode', async () => {
    
  952.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  953.       validAttributes: {foo: true},
    
  954.       uiViewClassName: 'RCTView',
    
  955.     }));
    
  956. 
    
  957.     let parent = undefined;
    
  958.     let child = undefined;
    
  959. 
    
  960.     class ContainsStrictModeChild extends React.Component {
    
  961.       render() {
    
  962.         return (
    
  963.           <StrictMode>
    
  964.             <View ref={n => (child = n)} />
    
  965.           </StrictMode>
    
  966.         );
    
  967.       }
    
  968.     }
    
  969. 
    
  970.     await act(() => {
    
  971.       ReactFabric.render(
    
  972.         <ContainsStrictModeChild ref={n => (parent = n)} />,
    
  973.         11,
    
  974.       );
    
  975.     });
    
  976. 
    
  977.     let match;
    
  978.     expect(() => (match = ReactFabric.findNodeHandle(parent))).toErrorDev([
    
  979.       'Warning: findNodeHandle is deprecated in StrictMode. ' +
    
  980.         'findNodeHandle was passed an instance of ContainsStrictModeChild which renders StrictMode children. ' +
    
  981.         'Instead, add a ref directly to the element you want to reference. ' +
    
  982.         'Learn more about using refs safely here: ' +
    
  983.         'https://reactjs.org/link/strict-mode-find-node' +
    
  984.         '\n    in RCTView (at **)' +
    
  985.         '\n    in ContainsStrictModeChild (at **)',
    
  986.     ]);
    
  987.     expect(match).toBe(
    
  988.       ReactNativePrivateInterface.getNativeTagFromPublicInstance(child),
    
  989.     );
    
  990.   });
    
  991. 
    
  992.   it('findNodeHandle should warn if passed a component that is inside StrictMode', async () => {
    
  993.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  994.       validAttributes: {foo: true},
    
  995.       uiViewClassName: 'RCTView',
    
  996.     }));
    
  997. 
    
  998.     let parent = undefined;
    
  999.     let child = undefined;
    
  1000. 
    
  1001.     class IsInStrictMode extends React.Component {
    
  1002.       render() {
    
  1003.         return <View ref={n => (child = n)} />;
    
  1004.       }
    
  1005.     }
    
  1006. 
    
  1007.     await act(() => {
    
  1008.       ReactFabric.render(
    
  1009.         <StrictMode>
    
  1010.           <IsInStrictMode ref={n => (parent = n)} />
    
  1011.         </StrictMode>,
    
  1012.         11,
    
  1013.       );
    
  1014.     });
    
  1015. 
    
  1016.     let match;
    
  1017.     expect(() => (match = ReactFabric.findNodeHandle(parent))).toErrorDev([
    
  1018.       'Warning: findNodeHandle is deprecated in StrictMode. ' +
    
  1019.         'findNodeHandle was passed an instance of IsInStrictMode which is inside StrictMode. ' +
    
  1020.         'Instead, add a ref directly to the element you want to reference. ' +
    
  1021.         'Learn more about using refs safely here: ' +
    
  1022.         'https://reactjs.org/link/strict-mode-find-node' +
    
  1023.         '\n    in RCTView (at **)' +
    
  1024.         '\n    in IsInStrictMode (at **)',
    
  1025.     ]);
    
  1026.     expect(match).toBe(
    
  1027.       ReactNativePrivateInterface.getNativeTagFromPublicInstance(child),
    
  1028.     );
    
  1029.   });
    
  1030. 
    
  1031.   it('should no-op if calling sendAccessibilityEvent on unmounted refs', async () => {
    
  1032.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  1033.       validAttributes: {foo: true},
    
  1034.       uiViewClassName: 'RCTView',
    
  1035.     }));
    
  1036. 
    
  1037.     nativeFabricUIManager.sendAccessibilityEvent.mockReset();
    
  1038. 
    
  1039.     let viewRef;
    
  1040.     await act(() => {
    
  1041.       ReactFabric.render(
    
  1042.         <View
    
  1043.           ref={ref => {
    
  1044.             viewRef = ref;
    
  1045.           }}
    
  1046.         />,
    
  1047.         11,
    
  1048.       );
    
  1049.     });
    
  1050.     const dangerouslyRetainedViewRef = viewRef;
    
  1051.     await act(() => {
    
  1052.       ReactFabric.stopSurface(11);
    
  1053.     });
    
  1054. 
    
  1055.     ReactFabric.sendAccessibilityEvent(
    
  1056.       dangerouslyRetainedViewRef,
    
  1057.       'eventTypeName',
    
  1058.     );
    
  1059. 
    
  1060.     expect(nativeFabricUIManager.sendAccessibilityEvent).not.toBeCalled();
    
  1061.   });
    
  1062. 
    
  1063.   it('getNodeFromInternalInstanceHandle should return the correct shadow node', async () => {
    
  1064.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  1065.       validAttributes: {foo: true},
    
  1066.       uiViewClassName: 'RCTView',
    
  1067.     }));
    
  1068. 
    
  1069.     await act(() => {
    
  1070.       ReactFabric.render(<View foo="test" />, 1);
    
  1071.     });
    
  1072. 
    
  1073.     const internalInstanceHandle =
    
  1074.       nativeFabricUIManager.createNode.mock.calls[0][4];
    
  1075.     expect(internalInstanceHandle).toEqual(expect.any(Object));
    
  1076. 
    
  1077.     const expectedShadowNode =
    
  1078.       nativeFabricUIManager.createNode.mock.results[0].value;
    
  1079.     expect(expectedShadowNode).toEqual(expect.any(Object));
    
  1080. 
    
  1081.     const node = ReactFabric.getNodeFromInternalInstanceHandle(
    
  1082.       internalInstanceHandle,
    
  1083.     );
    
  1084.     expect(node).toBe(expectedShadowNode);
    
  1085.   });
    
  1086. 
    
  1087.   it('getPublicInstanceFromInternalInstanceHandle should provide public instances for HostComponent', async () => {
    
  1088.     const View = createReactNativeComponentClass('RCTView', () => ({
    
  1089.       validAttributes: {foo: true},
    
  1090.       uiViewClassName: 'RCTView',
    
  1091.     }));
    
  1092. 
    
  1093.     let viewRef;
    
  1094.     await act(() => {
    
  1095.       ReactFabric.render(
    
  1096.         <View
    
  1097.           foo="test"
    
  1098.           ref={ref => {
    
  1099.             viewRef = ref;
    
  1100.           }}
    
  1101.         />,
    
  1102.         1,
    
  1103.       );
    
  1104.     });
    
  1105. 
    
  1106.     const internalInstanceHandle =
    
  1107.       nativeFabricUIManager.createNode.mock.calls[0][4];
    
  1108.     expect(internalInstanceHandle).toEqual(expect.any(Object));
    
  1109. 
    
  1110.     const publicInstance =
    
  1111.       ReactFabric.getPublicInstanceFromInternalInstanceHandle(
    
  1112.         internalInstanceHandle,
    
  1113.       );
    
  1114.     expect(publicInstance).toBe(viewRef);
    
  1115.   });
    
  1116. 
    
  1117.   it('getPublicInstanceFromInternalInstanceHandle should provide public instances for HostText', async () => {
    
  1118.     jest.spyOn(ReactNativePrivateInterface, 'createPublicTextInstance');
    
  1119. 
    
  1120.     const RCTText = createReactNativeComponentClass('RCTText', () => ({
    
  1121.       validAttributes: {},
    
  1122.       uiViewClassName: 'RCTText',
    
  1123.     }));
    
  1124. 
    
  1125.     await act(() => {
    
  1126.       ReactFabric.render(<RCTText>Text content</RCTText>, 1);
    
  1127.     });
    
  1128. 
    
  1129.     // Access the internal instance handle used to create the text node.
    
  1130.     const internalInstanceHandle =
    
  1131.       nativeFabricUIManager.createNode.mock.calls[0][4];
    
  1132.     expect(internalInstanceHandle).toEqual(expect.any(Object));
    
  1133. 
    
  1134.     // Text public instances should be created lazily.
    
  1135.     expect(
    
  1136.       ReactNativePrivateInterface.createPublicTextInstance,
    
  1137.     ).not.toHaveBeenCalled();
    
  1138. 
    
  1139.     const publicInstance =
    
  1140.       ReactFabric.getPublicInstanceFromInternalInstanceHandle(
    
  1141.         internalInstanceHandle,
    
  1142.       );
    
  1143. 
    
  1144.     // We just requested the text public instance, so it should have been created at this point.
    
  1145.     expect(
    
  1146.       ReactNativePrivateInterface.createPublicTextInstance,
    
  1147.     ).toHaveBeenCalledTimes(1);
    
  1148.     expect(
    
  1149.       ReactNativePrivateInterface.createPublicTextInstance,
    
  1150.     ).toHaveBeenCalledWith(internalInstanceHandle);
    
  1151. 
    
  1152.     const expectedPublicInstance =
    
  1153.       ReactNativePrivateInterface.createPublicTextInstance.mock.results[0]
    
  1154.         .value;
    
  1155.     expect(publicInstance).toBe(expectedPublicInstance);
    
  1156.   });
    
  1157. });