main
js 167 lines 3.96 KB
Raw
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 });