main
js 156 lines 3.93 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 ReactNoopPersistent;
15 let act;
16
17 describe('ReactPersistentUpdatesMinimalism', () => {
18 beforeEach(() => {
19 jest.resetModules();
20 React = require('react');
21 ReactNoopPersistent = require('react-noop-renderer/persistent');
22 act = require('internal-test-utils').act;
23 });
24
25 it('should render a simple component', async () => {
26 function Child() {
27 return <div>Hello World</div>;
28 }
29
30 function Parent() {
31 return <Child />;
32 }
33
34 ReactNoopPersistent.startTrackingHostCounters();
35 await act(() => ReactNoopPersistent.render(<Parent />));
36 expect(ReactNoopPersistent.stopTrackingHostCounters()).toEqual({
37 hostCloneCounter: 0,
38 });
39
40 ReactNoopPersistent.startTrackingHostCounters();
41 await act(() => ReactNoopPersistent.render(<Parent />));
42 expect(ReactNoopPersistent.stopTrackingHostCounters()).toEqual({
43 hostCloneCounter: 1,
44 });
45 });
46
47 it('should not diff referentially equal host elements', async () => {
48 function Leaf(props) {
49 return (
50 <span>
51 hello
52 <b />
53 {props.name}
54 </span>
55 );
56 }
57
58 const constEl = (
59 <div>
60 <Leaf name="world" />
61 </div>
62 );
63
64 function Child() {
65 return constEl;
66 }
67
68 function Parent() {
69 return <Child />;
70 }
71
72 ReactNoopPersistent.startTrackingHostCounters();
73 await act(() => ReactNoopPersistent.render(<Parent />));
74 expect(ReactNoopPersistent.stopTrackingHostCounters()).toEqual({
75 hostCloneCounter: 0,
76 });
77
78 ReactNoopPersistent.startTrackingHostCounters();
79 await act(() => ReactNoopPersistent.render(<Parent />));
80 expect(ReactNoopPersistent.stopTrackingHostCounters()).toEqual({
81 hostCloneCounter: 0,
82 });
83 });
84
85 it('should not diff parents of setState targets', async () => {
86 let childInst;
87
88 function Leaf(props) {
89 return (
90 <span>
91 hello
92 <b />
93 {props.name}
94 </span>
95 );
96 }
97
98 class Child extends React.Component {
99 state = {name: 'Batman'};
100 render() {
101 childInst = this;
102 return (
103 <div>
104 <Leaf name={this.state.name} />
105 </div>
106 );
107 }
108 }
109
110 function Parent() {
111 return (
112 <section>
113 <div>
114 <Leaf name="world" />
115 <Child />
116 <hr />
117 <Leaf name="world" />
118 </div>
119 </section>
120 );
121 }
122
123 ReactNoopPersistent.startTrackingHostCounters();
124 await act(() => ReactNoopPersistent.render(<Parent />));
125 expect(ReactNoopPersistent.stopTrackingHostCounters()).toEqual({
126 hostCloneCounter: 0,
127 });
128
129 ReactNoopPersistent.startTrackingHostCounters();
130 await act(() => childInst.setState({name: 'Robin'}));
131 expect(ReactNoopPersistent.stopTrackingHostCounters()).toEqual({
132 // section
133 // section > div
134 // section > div > Child > div
135 // section > div > Child > Leaf > span
136 // section > div > Child > Leaf > span > b
137 hostCloneCounter: 5,
138 });
139
140 ReactNoopPersistent.startTrackingHostCounters();
141 await act(() => ReactNoopPersistent.render(<Parent />));
142 expect(ReactNoopPersistent.stopTrackingHostCounters()).toEqual({
143 // Parent > section
144 // Parent > section > div
145 // Parent > section > div > Leaf > span
146 // Parent > section > div > Leaf > span > b
147 // Parent > section > div > Child > div
148 // Parent > section > div > Child > div > Leaf > span
149 // Parent > section > div > Child > div > Leaf > span > b
150 // Parent > section > div > hr
151 // Parent > section > div > Leaf > span
152 // Parent > section > div > Leaf > span > b
153 hostCloneCounter: 10,
154 });
155 });
156 });