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 ReactNoop;
    
  15. let waitForAll;
    
  16. 
    
  17. // This is a new feature in Fiber so I put it in its own test file. It could
    
  18. // probably move to one of the other test files once it is official.
    
  19. describe('ReactTopLevelFragment', function () {
    
  20.   beforeEach(function () {
    
  21.     jest.resetModules();
    
  22.     React = require('react');
    
  23.     ReactNoop = require('react-noop-renderer');
    
  24. 
    
  25.     const InternalTestUtils = require('internal-test-utils');
    
  26.     waitForAll = InternalTestUtils.waitForAll;
    
  27.   });
    
  28. 
    
  29.   it('should render a simple fragment at the top of a component', async function () {
    
  30.     function Fragment() {
    
  31.       return [<div key="a">Hello</div>, <div key="b">World</div>];
    
  32.     }
    
  33.     ReactNoop.render(<Fragment />);
    
  34.     await waitForAll([]);
    
  35.   });
    
  36. 
    
  37.   it('should preserve state when switching from a single child', async function () {
    
  38.     let instance = null;
    
  39. 
    
  40.     class Stateful extends React.Component {
    
  41.       render() {
    
  42.         instance = this;
    
  43.         return <div>Hello</div>;
    
  44.       }
    
  45.     }
    
  46. 
    
  47.     function Fragment({condition}) {
    
  48.       return condition ? (
    
  49.         <Stateful key="a" />
    
  50.       ) : (
    
  51.         [<Stateful key="a" />, <div key="b">World</div>]
    
  52.       );
    
  53.     }
    
  54.     ReactNoop.render(<Fragment />);
    
  55.     await waitForAll([]);
    
  56. 
    
  57.     const instanceA = instance;
    
  58. 
    
  59.     expect(instanceA).not.toBe(null);
    
  60. 
    
  61.     ReactNoop.render(<Fragment condition={true} />);
    
  62.     await waitForAll([]);
    
  63. 
    
  64.     const instanceB = instance;
    
  65. 
    
  66.     expect(instanceB).toBe(instanceA);
    
  67.   });
    
  68. 
    
  69.   it('should not preserve state when switching to a nested array', async function () {
    
  70.     let instance = null;
    
  71. 
    
  72.     class Stateful extends React.Component {
    
  73.       render() {
    
  74.         instance = this;
    
  75.         return <div>Hello</div>;
    
  76.       }
    
  77.     }
    
  78. 
    
  79.     function Fragment({condition}) {
    
  80.       return condition ? (
    
  81.         <Stateful key="a" />
    
  82.       ) : (
    
  83.         [[<Stateful key="a" />, <div key="b">World</div>], <div key="c" />]
    
  84.       );
    
  85.     }
    
  86.     ReactNoop.render(<Fragment />);
    
  87.     await waitForAll([]);
    
  88. 
    
  89.     const instanceA = instance;
    
  90. 
    
  91.     expect(instanceA).not.toBe(null);
    
  92. 
    
  93.     ReactNoop.render(<Fragment condition={true} />);
    
  94.     await waitForAll([]);
    
  95. 
    
  96.     const instanceB = instance;
    
  97. 
    
  98.     expect(instanceB).not.toBe(instanceA);
    
  99.   });
    
  100. 
    
  101.   it('preserves state if an implicit key slot switches from/to null', async function () {
    
  102.     let instance = null;
    
  103. 
    
  104.     class Stateful extends React.Component {
    
  105.       render() {
    
  106.         instance = this;
    
  107.         return <div>World</div>;
    
  108.       }
    
  109.     }
    
  110. 
    
  111.     function Fragment({condition}) {
    
  112.       return condition
    
  113.         ? [null, <Stateful key="a" />]
    
  114.         : [<div key="b">Hello</div>, <Stateful key="a" />];
    
  115.     }
    
  116.     ReactNoop.render(<Fragment />);
    
  117.     await waitForAll([]);
    
  118. 
    
  119.     const instanceA = instance;
    
  120. 
    
  121.     expect(instanceA).not.toBe(null);
    
  122. 
    
  123.     ReactNoop.render(<Fragment condition={true} />);
    
  124.     await waitForAll([]);
    
  125. 
    
  126.     const instanceB = instance;
    
  127. 
    
  128.     expect(instanceB).toBe(instanceA);
    
  129. 
    
  130.     ReactNoop.render(<Fragment condition={false} />);
    
  131.     await waitForAll([]);
    
  132. 
    
  133.     const instanceC = instance;
    
  134. 
    
  135.     expect(instanceC === instanceA).toBe(true);
    
  136.   });
    
  137. 
    
  138.   it('should preserve state in a reorder', async function () {
    
  139.     let instance = null;
    
  140. 
    
  141.     class Stateful extends React.Component {
    
  142.       render() {
    
  143.         instance = this;
    
  144.         return <div>Hello</div>;
    
  145.       }
    
  146.     }
    
  147. 
    
  148.     function Fragment({condition}) {
    
  149.       return condition
    
  150.         ? [[<div key="b">World</div>, <Stateful key="a" />]]
    
  151.         : [[<Stateful key="a" />, <div key="b">World</div>], <div key="c" />];
    
  152.     }
    
  153.     ReactNoop.render(<Fragment />);
    
  154.     await waitForAll([]);
    
  155. 
    
  156.     const instanceA = instance;
    
  157. 
    
  158.     expect(instanceA).not.toBe(null);
    
  159. 
    
  160.     ReactNoop.render(<Fragment condition={true} />);
    
  161.     await waitForAll([]);
    
  162. 
    
  163.     const instanceB = instance;
    
  164. 
    
  165.     expect(instanceB).toBe(instanceA);
    
  166.   });
    
  167. });