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.  * @flow
    
  8.  */
    
  9. 
    
  10. const {printOwnersList} = require('../devtools/utils');
    
  11. 
    
  12. describe('Store owners list', () => {
    
  13.   let React;
    
  14.   let act;
    
  15.   let legacyRender;
    
  16.   let store;
    
  17. 
    
  18.   beforeEach(() => {
    
  19.     store = global.store;
    
  20.     store.collapseNodesByDefault = false;
    
  21. 
    
  22.     React = require('react');
    
  23. 
    
  24.     const utils = require('./utils');
    
  25.     act = utils.act;
    
  26.     legacyRender = utils.legacyRender;
    
  27.   });
    
  28. 
    
  29.   function getFormattedOwnersList(elementID) {
    
  30.     const ownersList = store.getOwnersListForElement(elementID);
    
  31.     return printOwnersList(ownersList);
    
  32.   }
    
  33. 
    
  34.   it('should drill through intermediate components', () => {
    
  35.     const Root = () => (
    
  36.       <Intermediate>
    
  37.         <div>
    
  38.           <Leaf />
    
  39.         </div>
    
  40.       </Intermediate>
    
  41.     );
    
  42.     const Wrapper = ({children}) => children;
    
  43.     const Leaf = () => <div>Leaf</div>;
    
  44.     const Intermediate = ({children}) => <Wrapper>{children}</Wrapper>;
    
  45. 
    
  46.     act(() => legacyRender(<Root />, document.createElement('div')));
    
  47.     expect(store).toMatchInlineSnapshot(`
    
  48.       [root]
    
  49.         ▾ <Root>
    
  50.           ▾ <Intermediate>
    
  51.             ▾ <Wrapper>
    
  52.                 <Leaf>
    
  53.     `);
    
  54. 
    
  55.     const rootID = store.getElementIDAtIndex(0);
    
  56.     expect(getFormattedOwnersList(rootID)).toMatchInlineSnapshot(`
    
  57.       "  ▾ <Root>
    
  58.           ▾ <Intermediate>
    
  59.               <Leaf>"
    
  60.     `);
    
  61. 
    
  62.     const intermediateID = store.getElementIDAtIndex(1);
    
  63.     expect(getFormattedOwnersList(intermediateID)).toMatchInlineSnapshot(`
    
  64.       "  ▾ <Intermediate>
    
  65.           ▾ <Wrapper>"
    
  66.     `);
    
  67.   });
    
  68. 
    
  69.   it('should drill through interleaved intermediate components', () => {
    
  70.     const Root = () => [
    
  71.       <Intermediate key="intermediate">
    
  72.         <Leaf />
    
  73.       </Intermediate>,
    
  74.       <Leaf key="leaf" />,
    
  75.     ];
    
  76.     const Wrapper = ({children}) => children;
    
  77.     const Leaf = () => <div>Leaf</div>;
    
  78.     const Intermediate = ({children}) => [
    
  79.       <Leaf key="leaf" />,
    
  80.       <Wrapper key="wrapper">{children}</Wrapper>,
    
  81.     ];
    
  82. 
    
  83.     act(() => legacyRender(<Root />, document.createElement('div')));
    
  84.     expect(store).toMatchInlineSnapshot(`
    
  85.       [root]
    
  86.         ▾ <Root>
    
  87.           ▾ <Intermediate key="intermediate">
    
  88.               <Leaf key="leaf">
    
  89.             ▾ <Wrapper key="wrapper">
    
  90.                 <Leaf>
    
  91.             <Leaf key="leaf">
    
  92.     `);
    
  93. 
    
  94.     const rootID = store.getElementIDAtIndex(0);
    
  95.     expect(getFormattedOwnersList(rootID)).toMatchInlineSnapshot(`
    
  96.       "  ▾ <Root>
    
  97.           ▾ <Intermediate key="intermediate">
    
  98.               <Leaf>
    
  99.             <Leaf key="leaf">"
    
  100.     `);
    
  101. 
    
  102.     const intermediateID = store.getElementIDAtIndex(1);
    
  103.     expect(getFormattedOwnersList(intermediateID)).toMatchInlineSnapshot(`
    
  104.       "  ▾ <Intermediate key="intermediate">
    
  105.             <Leaf key="leaf">
    
  106.           ▾ <Wrapper key="wrapper">"
    
  107.     `);
    
  108.   });
    
  109. 
    
  110.   it('should show the proper owners list order and contents after insertions and deletions', () => {
    
  111.     const Root = ({includeDirect, includeIndirect}) => (
    
  112.       <div>
    
  113.         {includeDirect ? <Leaf /> : null}
    
  114.         {includeIndirect ? (
    
  115.           <Intermediate>
    
  116.             <Leaf />
    
  117.           </Intermediate>
    
  118.         ) : null}
    
  119.       </div>
    
  120.     );
    
  121.     const Wrapper = ({children}) => children;
    
  122.     const Leaf = () => <div>Leaf</div>;
    
  123.     const Intermediate = ({children}) => <Wrapper>{children}</Wrapper>;
    
  124. 
    
  125.     const container = document.createElement('div');
    
  126. 
    
  127.     act(() =>
    
  128.       legacyRender(
    
  129.         <Root includeDirect={false} includeIndirect={true} />,
    
  130.         container,
    
  131.       ),
    
  132.     );
    
  133. 
    
  134.     const rootID = store.getElementIDAtIndex(0);
    
  135.     expect(store).toMatchInlineSnapshot(`
    
  136.       [root]
    
  137.         ▾ <Root>
    
  138.           ▾ <Intermediate>
    
  139.             ▾ <Wrapper>
    
  140.                 <Leaf>
    
  141.     `);
    
  142.     expect(getFormattedOwnersList(rootID)).toMatchInlineSnapshot(`
    
  143.       "  ▾ <Root>
    
  144.           ▾ <Intermediate>
    
  145.               <Leaf>"
    
  146.     `);
    
  147. 
    
  148.     act(() =>
    
  149.       legacyRender(
    
  150.         <Root includeDirect={true} includeIndirect={true} />,
    
  151.         container,
    
  152.       ),
    
  153.     );
    
  154.     expect(store).toMatchInlineSnapshot(`
    
  155.       [root]
    
  156.         ▾ <Root>
    
  157.             <Leaf>
    
  158.           ▾ <Intermediate>
    
  159.             ▾ <Wrapper>
    
  160.                 <Leaf>
    
  161.     `);
    
  162.     expect(getFormattedOwnersList(rootID)).toMatchInlineSnapshot(`
    
  163.       "  ▾ <Root>
    
  164.             <Leaf>
    
  165.           ▾ <Intermediate>
    
  166.               <Leaf>"
    
  167.     `);
    
  168. 
    
  169.     act(() =>
    
  170.       legacyRender(
    
  171.         <Root includeDirect={true} includeIndirect={false} />,
    
  172.         container,
    
  173.       ),
    
  174.     );
    
  175.     expect(store).toMatchInlineSnapshot(`
    
  176.       [root]
    
  177.         ▾ <Root>
    
  178.             <Leaf>
    
  179.     `);
    
  180.     expect(getFormattedOwnersList(rootID)).toMatchInlineSnapshot(`
    
  181.       "  ▾ <Root>
    
  182.             <Leaf>"
    
  183.     `);
    
  184. 
    
  185.     act(() =>
    
  186.       legacyRender(
    
  187.         <Root includeDirect={false} includeIndirect={false} />,
    
  188.         container,
    
  189.       ),
    
  190.     );
    
  191.     expect(store).toMatchInlineSnapshot(`
    
  192.       [root]
    
  193.           <Root>
    
  194.     `);
    
  195.     expect(getFormattedOwnersList(rootID)).toMatchInlineSnapshot(
    
  196.       `"    <Root>"`,
    
  197.     );
    
  198.   });
    
  199. 
    
  200.   it('should show the proper owners list ordering after reordered children', () => {
    
  201.     const Root = ({ascending}) =>
    
  202.       ascending
    
  203.         ? [<Leaf key="A" />, <Leaf key="B" />, <Leaf key="C" />]
    
  204.         : [<Leaf key="C" />, <Leaf key="B" />, <Leaf key="A" />];
    
  205.     const Leaf = () => <div>Leaf</div>;
    
  206. 
    
  207.     const container = document.createElement('div');
    
  208.     act(() => legacyRender(<Root ascending={true} />, container));
    
  209. 
    
  210.     const rootID = store.getElementIDAtIndex(0);
    
  211.     expect(store).toMatchInlineSnapshot(`
    
  212.       [root]
    
  213.         ▾ <Root>
    
  214.             <Leaf key="A">
    
  215.             <Leaf key="B">
    
  216.             <Leaf key="C">
    
  217.     `);
    
  218.     expect(getFormattedOwnersList(rootID)).toMatchInlineSnapshot(`
    
  219.       "  ▾ <Root>
    
  220.             <Leaf key="A">
    
  221.             <Leaf key="B">
    
  222.             <Leaf key="C">"
    
  223.     `);
    
  224. 
    
  225.     act(() => legacyRender(<Root ascending={false} />, container));
    
  226.     expect(store).toMatchInlineSnapshot(`
    
  227.       [root]
    
  228.         ▾ <Root>
    
  229.             <Leaf key="C">
    
  230.             <Leaf key="B">
    
  231.             <Leaf key="A">
    
  232.     `);
    
  233.     expect(getFormattedOwnersList(rootID)).toMatchInlineSnapshot(`
    
  234.       "  ▾ <Root>
    
  235.             <Leaf key="C">
    
  236.             <Leaf key="B">
    
  237.             <Leaf key="A">"
    
  238.     `);
    
  239.   });
    
  240. });