1
-/**
2
- * Copyright 2016-present, Facebook, Inc.
3
- * All rights reserved.
4
- *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
8
- *
9
- * @emails react-core
10
- */
11
-
12
-'use strict';
13
-
14
-var ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
15
-var describeStack = ReactNativeFeatureFlags.useFiber ? describe.skip : describe;
16
-
17
-// These tests are only relevant for the Stack version of the tree hook.
18
-// This file is for RN. There is a sibling file that has some tree hook
19
-// tests that are still relevant in Fiber.
20
-// TODO: remove this file when we delete Stack.
21
-
22
-describeStack('ReactComponentTreeHook', () => {
23
- var React;
24
- var ReactNative;
25
- var ReactInstanceMap;
26
- var ReactComponentTreeHook;
27
- var ReactComponentTreeTestUtils;
28
- var createReactNativeComponentClass;
29
- var View;
30
- var Image;
31
- var Text;
32
- var PropTypes;
33
-
34
- beforeEach(() => {
35
- jest.resetModules();
36
-
37
- PropTypes = require('prop-types');
38
- React = require('react');
39
- ReactNative = require('react-native');
40
- ReactInstanceMap = require('ReactInstanceMap');
41
- ReactComponentTreeHook = require('ReactComponentTreeHook');
42
- ReactComponentTreeTestUtils = require('ReactComponentTreeTestUtils');
43
- View = require('View');
44
- createReactNativeComponentClass = require('createReactNativeComponentClass');
45
- Image = createReactNativeComponentClass({
46
- validAttributes: {},
47
- uiViewClassName: 'Image',
48
- });
49
- var RCText = createReactNativeComponentClass({
50
- validAttributes: {},
51
- uiViewClassName: 'RCText',
52
- });
53
- Text = class extends React.Component {
54
- static childContextTypes = {
55
- isInAParentText: PropTypes.bool,
56
- };
57
-
58
- getChildContext() {
59
- return {isInAParentText: true};
60
- }
61
-
62
- render() {
63
- return <RCText {...this.props} />;
64
- }
65
- };
66
- });
67
-
68
- function assertTreeMatches(pairs, options) {
69
- if (!Array.isArray(pairs[0])) {
70
- pairs = [pairs];
71
- }
72
-
73
- var currentElement;
74
- var rootInstance;
75
-
76
- class Wrapper extends React.Component {
77
- render() {
78
- rootInstance = ReactInstanceMap.get(this);
79
- return currentElement;
80
- }
81
- }
82
-
83
- function expectWrapperTreeToEqual(expectedTree, andStayMounted) {
84
- ReactComponentTreeTestUtils.expectTree(rootInstance._debugID, {
85
- displayName: 'Wrapper',
86
- children: expectedTree ? [expectedTree] : [],
87
- });
88
- var rootDisplayNames = ReactComponentTreeTestUtils.getRootDisplayNames();
89
- var registeredDisplayNames = ReactComponentTreeTestUtils.getRegisteredDisplayNames();
90
- if (!expectedTree) {
91
- expectDev(rootDisplayNames).toEqual([]);
92
- expectDev(registeredDisplayNames).toEqual([]);
93
- } else if (andStayMounted) {
94
- expectDev(rootDisplayNames).toContain('Wrapper');
95
- expectDev(registeredDisplayNames).toContain('Wrapper');
96
- }
97
- }
98
-
99
- // Mount once, render updates, then unmount.
100
- // Ensure the tree is correct on every step.
101
- pairs.forEach(([element, expectedTree]) => {
102
- currentElement = element;
103
-
104
- // Mount a new tree or update the existing tree.
105
- ReactNative.render(<Wrapper />, 1);
106
- expectWrapperTreeToEqual(expectedTree, true);
107
-
108
- // Purging should have no effect
109
- // on the tree we expect to see.
110
- ReactComponentTreeHook.purgeUnmountedComponents();
111
- expectWrapperTreeToEqual(expectedTree, true);
112
- });
113
-
114
- // Unmounting the root node should purge
115
- // the whole subtree automatically.
116
- ReactNative.unmountComponentAtNode(1);
117
- expectWrapperTreeToEqual(null);
118
-
119
- // Mount and unmount for every pair.
120
- // Ensure the tree is correct on every step.
121
- pairs.forEach(([element, expectedTree]) => {
122
- currentElement = element;
123
-
124
- // Mount a new tree.
125
- ReactNative.render(<Wrapper />, 1);
126
- expectWrapperTreeToEqual(expectedTree);
127
-
128
- // Unmounting should clean it up.
129
- ReactNative.unmountComponentAtNode(1);
130
- expectWrapperTreeToEqual(null);
131
- });
132
- }
133
-
134
- describe('mount', () => {
135
- it('uses displayName or Unknown for classic components', () => {
136
- class Foo extends React.Component {
137
- render() {
138
- return null;
139
- }
140
- }
141
-
142
- Foo.displayName = 'Bar';
143
-
144
- class Baz extends React.Component {
145
- render() {
146
- return null;
147
- }
148
- }
149
-
150
- class Qux extends React.Component {
151
- render() {
152
- return null;
153
- }
154
- }
155
-
156
- delete Qux.displayName;
157
-
158
- var element = <View><Foo /><Baz /><Qux /></View>;
159
- var tree = {
160
- displayName: 'View',
161
- element,
162
- children: [
163
- {
164
- displayName: 'Bar',
165
- children: [],
166
- },
167
- {
168
- displayName: 'Baz',
169
- children: [],
170
- },
171
- {
172
- displayName: 'Unknown',
173
- children: [],
174
- },
175
- ],
176
- };
177
- assertTreeMatches([element, tree]);
178
- });
179
-
180
- it('uses displayName, name, or ReactComponent for modern components', () => {
181
- class Foo extends React.Component {
182
- render() {
183
- return null;
184
- }
185
- }
186
- Foo.displayName = 'Bar';
187
- class Baz extends React.Component {
188
- render() {
189
- return null;
190
- }
191
- }
192
- class Qux extends React.Component {
193
- render() {
194
- return null;
195
- }
196
- }
197
- delete Qux.name;
198
-
199
- var element = <View><Foo /><Baz /><Qux /></View>;
200
- var tree = {
201
- displayName: 'View',
202
- children: [
203
- {
204
- displayName: 'Bar',
205
- children: [],
206
- },
207
- {
208
- displayName: 'Baz',
209
- children: [],
210
- },
211
- {
212
- // Note: Ideally fallback name should be consistent (e.g. "Unknown")
213
- displayName: 'ReactComponent',
214
- children: [],
215
- },
216
- ],
217
- };
218
- assertTreeMatches([element, tree]);
219
- });
220
-
221
- it('uses displayName, name, or Object for factory components', () => {
222
- function Foo() {
223
- return {
224
- render() {
225
- return null;
226
- },
227
- };
228
- }
229
- Foo.displayName = 'Bar';
230
- function Baz() {
231
- return {
232
- render() {
233
- return null;
234
- },
235
- };
236
- }
237
- function Qux() {
238
- return {
239
- render() {
240
- return null;
241
- },
242
- };
243
- }
244
- delete Qux.name;
245
-
246
- var element = <View><Foo /><Baz /><Qux /></View>;
247
- var tree = {
248
- displayName: 'View',
249
- children: [
250
- {
251
- displayName: 'Bar',
252
- children: [],
253
- },
254
- {
255
- displayName: 'Baz',
256
- children: [],
257
- },
258
- {
259
- displayName: 'Unknown',
260
- children: [],
261
- },
262
- ],
263
- };
264
- assertTreeMatches([element, tree]);
265
- });
266
-
267
- it('uses displayName, name, or StatelessComponent for functional components', () => {
268
- function Foo() {
269
- return null;
270
- }
271
- Foo.displayName = 'Bar';
272
- function Baz() {
273
- return null;
274
- }
275
- function Qux() {
276
- return null;
277
- }
278
- delete Qux.name;
279
-
280
- var element = <View><Foo /><Baz /><Qux /></View>;
281
- var tree = {
282
- displayName: 'View',
283
- children: [
284
- {
285
- displayName: 'Bar',
286
- children: [],
287
- },
288
- {
289
- displayName: 'Baz',
290
- children: [],
291
- },
292
- {
293
- displayName: 'Unknown',
294
- children: [],
295
- },
296
- ],
297
- };
298
- assertTreeMatches([element, tree]);
299
- });
300
-
301
- it('reports a host tree correctly', () => {
302
- var element = (
303
- <View>
304
- <View>
305
- <Text>
306
- Hi!
307
- </Text>
308
- </View>
309
- <Image />
310
- </View>
311
- );
312
- var tree = {
313
- displayName: 'View',
314
- element,
315
- children: [
316
- {
317
- displayName: 'View',
318
- children: [
319
- {
320
- displayName: 'Text',
321
- children: [
322
- {
323
- displayName: 'RCText',
324
- children: [
325
- {
326
- displayName: '#text',
327
- element: 'Hi!',
328
- text: 'Hi!',
329
- },
330
- ],
331
- },
332
- ],
333
- },
334
- ],
335
- },
336
- {
337
- displayName: 'Image',
338
- element: <Image />,
339
- children: [],
340
- },
341
- ],
342
- };
343
- assertTreeMatches([element, tree]);
344
- });
345
-
346
- it('reports a simple tree with composites correctly', () => {
347
- class Foo extends React.Component {
348
- render() {
349
- return <Image />;
350
- }
351
- }
352
-
353
- var element = <Foo />;
354
- var tree = {
355
- displayName: 'Foo',
356
- element,
357
- children: [
358
- {
359
- displayName: 'Image',
360
- element: <Image />,
361
- children: [],
362
- },
363
- ],
364
- };
365
- assertTreeMatches([element, tree]);
366
- });
367
-
368
- it('reports a tree with composites correctly', () => {
369
- class Qux extends React.Component {
370
- render() {
371
- return null;
372
- }
373
- }
374
-
375
- function Foo() {
376
- return {
377
- render() {
378
- return <Qux />;
379
- },
380
- };
381
- }
382
- function Bar({children}) {
383
- return <View>{children}</View>;
384
- }
385
- class Baz extends React.Component {
386
- render() {
387
- return (
388
- <View>
389
- <Foo />
390
- <Bar>
391
- <Text>Hi,</Text>
392
- </Bar>
393
- <Image />
394
- </View>
395
- );
396
- }
397
- }
398
-
399
- var element = <Baz />;
400
- var tree = {
401
- displayName: 'Baz',
402
- element,
403
- children: [
404
- {
405
- displayName: 'View',
406
- children: [
407
- {
408
- displayName: 'Foo',
409
- element: <Foo />,
410
- children: [
411
- {
412
- displayName: 'Qux',
413
- element: <Qux />,
414
- children: [],
415
- },
416
- ],
417
- },
418
- {
419
- displayName: 'Bar',
420
- children: [
421
- {
422
- displayName: 'View',
423
- children: [
424
- {
425
- displayName: 'Text',
426
- children: [
427
- {
428
- displayName: 'RCText',
429
- children: [
430
- {
431
- displayName: '#text',
432
- element: 'Hi,',
433
- text: 'Hi,',
434
- },
435
- ],
436
- },
437
- ],
438
- },
439
- ],
440
- },
441
- ],
442
- },
443
- {
444
- displayName: 'Image',
445
- element: <Image />,
446
- children: [],
447
- },
448
- ],
449
- },
450
- ],
451
- };
452
- assertTreeMatches([element, tree]);
453
- });
454
-
455
- it('ignores null children', () => {
456
- class Foo extends React.Component {
457
- render() {
458
- return null;
459
- }
460
- }
461
- var element = <Foo />;
462
- var tree = {
463
- displayName: 'Foo',
464
- children: [],
465
- };
466
- assertTreeMatches([element, tree]);
467
- });
468
-
469
- it('ignores false children', () => {
470
- class Foo extends React.Component {
471
- render() {
472
- return false;
473
- }
474
- }
475
- var element = <Foo />;
476
- var tree = {
477
- displayName: 'Foo',
478
- children: [],
479
- };
480
- assertTreeMatches([element, tree]);
481
- });
482
-
483
- it('reports text nodes as children', () => {
484
- var element = <Text>{'1'}{2}</Text>;
485
- var tree = {
486
- displayName: 'Text',
487
- children: [
488
- {
489
- displayName: 'RCText',
490
- children: [
491
- {
492
- displayName: '#text',
493
- text: '1',
494
- },
495
- {
496
- displayName: '#text',
497
- text: '2',
498
- },
499
- ],
500
- },
501
- ],
502
- };
503
- assertTreeMatches([element, tree]);
504
- });
505
-
506
- it('reports a single text node as a child', () => {
507
- var element = <Text>{'1'}</Text>;
508
- var tree = {
509
- displayName: 'Text',
510
- children: [
511
- {
512
- displayName: 'RCText',
513
- children: [
514
- {
515
- displayName: '#text',
516
- text: '1',
517
- },
518
- ],
519
- },
520
- ],
521
- };
522
- assertTreeMatches([element, tree]);
523
- });
524
-
525
- it('reports a single number node as a child', () => {
526
- var element = <Text>{42}</Text>;
527
- var tree = {
528
- displayName: 'Text',
529
- children: [
530
- {
531
- displayName: 'RCText',
532
- children: [
533
- {
534
- displayName: '#text',
535
- text: '42',
536
- },
537
- ],
538
- },
539
- ],
540
- };
541
- assertTreeMatches([element, tree]);
542
- });
543
-
544
- it('reports a zero as a child', () => {
545
- var element = <Text>{0}</Text>;
546
- var tree = {
547
- displayName: 'Text',
548
- children: [
549
- {
550
- displayName: 'RCText',
551
- children: [
552
- {
553
- displayName: '#text',
554
- text: '0',
555
- },
556
- ],
557
- },
558
- ],
559
- };
560
- assertTreeMatches([element, tree]);
561
- });
562
-
563
- it('skips empty nodes for multiple children', () => {
564
- function Foo() {
565
- return <Image />;
566
- }
567
- var element = (
568
- <View>
569
- {false}
570
- <Foo />
571
- {null}
572
- <Foo />
573
- </View>
574
- );
575
- var tree = {
576
- displayName: 'View',
577
- element,
578
- children: [
579
- {
580
- displayName: 'Foo',
581
- element: <Foo />,
582
- children: [
583
- {
584
- displayName: 'Image',
585
- element: <Image />,
586
- children: [],
587
- },
588
- ],
589
- },
590
- {
591
- displayName: 'Foo',
592
- element: <Foo />,
593
- children: [
594
- {
595
- displayName: 'Image',
596
- element: <Image />,
597
- children: [],
598
- },
599
- ],
600
- },
601
- ],
602
- };
603
- assertTreeMatches([element, tree]);
604
- });
605
- });
606
-
607
- describe('update', () => {
608
- describe('host component', () => {
609
- it('updates text of a single text child', () => {
610
- var elementBefore = <Text>Hi.</Text>;
611
- var treeBefore = {
612
- displayName: 'Text',
613
- children: [
614
- {
615
- displayName: 'RCText',
616
- children: [
617
- {
618
- displayName: '#text',
619
- text: 'Hi.',
620
- },
621
- ],
622
- },
623
- ],
624
- };
625
-
626
- var elementAfter = <Text>Bye.</Text>;
627
- var treeAfter = {
628
- displayName: 'Text',
629
- children: [
630
- {
631
- displayName: 'RCText',
632
- children: [
633
- {
634
- displayName: '#text',
635
- text: 'Bye.',
636
- },
637
- ],
638
- },
639
- ],
640
- };
641
-
642
- assertTreeMatches([
643
- [elementBefore, treeBefore],
644
- [elementAfter, treeAfter],
645
- ]);
646
- });
647
-
648
- it('updates from no children to a single text child', () => {
649
- var elementBefore = <Text />;
650
- var treeBefore = {
651
- displayName: 'Text',
652
- children: [
653
- {
654
- displayName: 'RCText',
655
- children: [],
656
- },
657
- ],
658
- };
659
-
660
- var elementAfter = <Text>Hi.</Text>;
661
- var treeAfter = {
662
- displayName: 'Text',
663
- children: [
664
- {
665
- displayName: 'RCText',
666
- children: [
667
- {
668
- displayName: '#text',
669
- text: 'Hi.',
670
- },
671
- ],
672
- },
673
- ],
674
- };
675
-
676
- assertTreeMatches([
677
- [elementBefore, treeBefore],
678
- [elementAfter, treeAfter],
679
- ]);
680
- });
681
-
682
- it('updates from a single text child to no children', () => {
683
- var elementBefore = <Text>Hi.</Text>;
684
- var treeBefore = {
685
- displayName: 'Text',
686
- children: [
687
- {
688
- displayName: 'RCText',
689
- children: [
690
- {
691
- displayName: '#text',
692
- text: 'Hi.',
693
- },
694
- ],
695
- },
696
- ],
697
- };
698
-
699
- var elementAfter = <Text />;
700
- var treeAfter = {
701
- displayName: 'Text',
702
- children: [
703
- {
704
- displayName: 'RCText',
705
- children: [],
706
- },
707
- ],
708
- };
709
-
710
- assertTreeMatches([
711
- [elementBefore, treeBefore],
712
- [elementAfter, treeAfter],
713
- ]);
714
- });
715
-
716
- it('updates from no children to multiple text children', () => {
717
- var elementBefore = <Text />;
718
- var treeBefore = {
719
- displayName: 'Text',
720
- children: [
721
- {
722
- displayName: 'RCText',
723
- children: [],
724
- },
725
- ],
726
- };
727
-
728
- var elementAfter = <Text>{'Hi.'}{'Bye.'}</Text>;
729
- var treeAfter = {
730
- displayName: 'Text',
731
- children: [
732
- {
733
- displayName: 'RCText',
734
- children: [
735
- {
736
- displayName: '#text',
737
- text: 'Hi.',
738
- },
739
- {
740
- displayName: '#text',
741
- text: 'Bye.',
742
- },
743
- ],
744
- },
745
- ],
746
- };
747
-
748
- assertTreeMatches([
749
- [elementBefore, treeBefore],
750
- [elementAfter, treeAfter],
751
- ]);
752
- });
753
-
754
- it('updates from multiple text children to no children', () => {
755
- var elementBefore = <Text>{'Hi.'}{'Bye.'}</Text>;
756
- var treeBefore = {
757
- displayName: 'Text',
758
- children: [
759
- {
760
- displayName: 'RCText',
761
- children: [
762
- {
763
- displayName: '#text',
764
- text: 'Hi.',
765
- },
766
- {
767
- displayName: '#text',
768
- text: 'Bye.',
769
- },
770
- ],
771
- },
772
- ],
773
- };
774
-
775
- var elementAfter = <Text />;
776
- var treeAfter = {
777
- displayName: 'Text',
778
- children: [
779
- {
780
- displayName: 'RCText',
781
- children: [],
782
- },
783
- ],
784
- };
785
- assertTreeMatches([
786
- [elementBefore, treeBefore],
787
- [elementAfter, treeAfter],
788
- ]);
789
- });
790
-
791
- it('updates from one text child to multiple text children', () => {
792
- var elementBefore = <Text>Hi.</Text>;
793
- var treeBefore = {
794
- displayName: 'Text',
795
- children: [
796
- {
797
- displayName: 'RCText',
798
- children: [
799
- {
800
- displayName: '#text',
801
- text: 'Hi.',
802
- },
803
- ],
804
- },
805
- ],
806
- };
807
-
808
- var elementAfter = <Text>{'Hi.'}{'Bye.'}</Text>;
809
- var treeAfter = {
810
- displayName: 'Text',
811
- children: [
812
- {
813
- displayName: 'RCText',
814
- children: [
815
- {
816
- displayName: '#text',
817
- text: 'Hi.',
818
- },
819
- {
820
- displayName: '#text',
821
- text: 'Bye.',
822
- },
823
- ],
824
- },
825
- ],
826
- };
827
-
828
- assertTreeMatches([
829
- [elementBefore, treeBefore],
830
- [elementAfter, treeAfter],
831
- ]);
832
- });
833
-
834
- it('updates from multiple text children to one text child', () => {
835
- var elementBefore = <Text>{'Hi.'}{'Bye.'}</Text>;
836
- var treeBefore = {
837
- displayName: 'Text',
838
- children: [
839
- {
840
- displayName: 'RCText',
841
- children: [
842
- {
843
- displayName: '#text',
844
- text: 'Hi.',
845
- },
846
- {
847
- displayName: '#text',
848
- text: 'Bye.',
849
- },
850
- ],
851
- },
852
- ],
853
- };
854
-
855
- var elementAfter = <Text>Hi.</Text>;
856
- var treeAfter = {
857
- displayName: 'Text',
858
- children: [
859
- {
860
- displayName: 'RCText',
861
- children: [
862
- {
863
- displayName: '#text',
864
- text: 'Hi.',
865
- },
866
- ],
867
- },
868
- ],
869
- };
870
- assertTreeMatches([
871
- [elementBefore, treeBefore],
872
- [elementAfter, treeAfter],
873
- ]);
874
- });
875
-
876
- it('updates text nodes when reordering', () => {
877
- var elementBefore = <Text>{'Hi.'}{'Bye.'}</Text>;
878
- var treeBefore = {
879
- displayName: 'Text',
880
- children: [
881
- {
882
- displayName: 'RCText',
883
- children: [
884
- {
885
- displayName: '#text',
886
- text: 'Hi.',
887
- },
888
- {
889
- displayName: '#text',
890
- text: 'Bye.',
891
- },
892
- ],
893
- },
894
- ],
895
- };
896
-
897
- var elementAfter = <Text>{'Bye.'}{'Hi.'}</Text>;
898
- var treeAfter = {
899
- displayName: 'Text',
900
- children: [
901
- {
902
- displayName: 'RCText',
903
- children: [
904
- {
905
- displayName: '#text',
906
- text: 'Bye.',
907
- },
908
- {
909
- displayName: '#text',
910
- text: 'Hi.',
911
- },
912
- ],
913
- },
914
- ],
915
- };
916
- assertTreeMatches([
917
- [elementBefore, treeBefore],
918
- [elementAfter, treeAfter],
919
- ]);
920
- });
921
-
922
- it('updates host nodes when reordering with keys', () => {
923
- var elementBefore = (
924
- <View>
925
- <Text key="a">Hi.</Text>
926
- <Text key="b">Bye.</Text>
927
- </View>
928
- );
929
- var treeBefore = {
930
- displayName: 'View',
931
- children: [
932
- {
933
- displayName: 'Text',
934
- children: [
935
- {
936
- displayName: 'RCText',
937
- children: [
938
- {
939
- displayName: '#text',
940
- text: 'Hi.',
941
- },
942
- ],
943
- },
944
- ],
945
- },
946
- {
947
- displayName: 'Text',
948
- children: [
949
- {
950
- displayName: 'RCText',
951
- children: [
952
- {
953
- displayName: '#text',
954
- text: 'Bye.',
955
- },
956
- ],
957
- },
958
- ],
959
- },
960
- ],
961
- };
962
-
963
- var elementAfter = (
964
- <View>
965
- <Text key="b">Bye.</Text>
966
- <Text key="a">Hi.</Text>
967
- </View>
968
- );
969
- var treeAfter = {
970
- displayName: 'View',
971
- children: [
972
- {
973
- displayName: 'Text',
974
- children: [
975
- {
976
- displayName: 'RCText',
977
- children: [
978
- {
979
- displayName: '#text',
980
- text: 'Bye.',
981
- },
982
- ],
983
- },
984
- ],
985
- },
986
- {
987
- displayName: 'Text',
988
- children: [
989
- {
990
- displayName: 'RCText',
991
- children: [
992
- {
993
- displayName: '#text',
994
- text: 'Hi.',
995
- },
996
- ],
997
- },
998
- ],
999
- },
1000
- ],
1001
- };
1002
-
1003
- assertTreeMatches([
1004
- [elementBefore, treeBefore],
1005
- [elementAfter, treeAfter],
1006
- ]);
1007
- });
1008
-
1009
- it('updates host nodes when reordering with keys', () => {
1010
- var elementBefore = (
1011
- <View>
1012
- <Text>Hi.</Text>
1013
- <Text>Bye.</Text>
1014
- </View>
1015
- );
1016
- var treeBefore = {
1017
- displayName: 'View',
1018
- children: [
1019
- {
1020
- displayName: 'Text',
1021
- children: [
1022
- {
1023
- displayName: 'RCText',
1024
- children: [
1025
- {
1026
- displayName: '#text',
1027
- text: 'Hi.',
1028
- },
1029
- ],
1030
- },
1031
- ],
1032
- },
1033
- {
1034
- displayName: 'Text',
1035
- children: [
1036
- {
1037
- displayName: 'RCText',
1038
- children: [
1039
- {
1040
- displayName: '#text',
1041
- text: 'Bye.',
1042
- },
1043
- ],
1044
- },
1045
- ],
1046
- },
1047
- ],
1048
- };
1049
-
1050
- var elementAfter = (
1051
- <View>
1052
- <Text>Bye.</Text>
1053
- <Text>Hi.</Text>
1054
- </View>
1055
- );
1056
- var treeAfter = {
1057
- displayName: 'View',
1058
- children: [
1059
- {
1060
- displayName: 'Text',
1061
- children: [
1062
- {
1063
- displayName: 'RCText',
1064
- children: [
1065
- {
1066
- displayName: '#text',
1067
- text: 'Bye.',
1068
- },
1069
- ],
1070
- },
1071
- ],
1072
- },
1073
- {
1074
- displayName: 'Text',
1075
- children: [
1076
- {
1077
- displayName: 'RCText',
1078
- children: [
1079
- {
1080
- displayName: '#text',
1081
- text: 'Hi.',
1082
- },
1083
- ],
1084
- },
1085
- ],
1086
- },
1087
- ],
1088
- };
1089
-
1090
- assertTreeMatches([
1091
- [elementBefore, treeBefore],
1092
- [elementAfter, treeAfter],
1093
- ]);
1094
- });
1095
-
1096
- it('updates a single composite child of a different type', () => {
1097
- function Foo() {
1098
- return null;
1099
- }
1100
-
1101
- function Bar() {
1102
- return null;
1103
- }
1104
-
1105
- var elementBefore = <View><Foo /></View>;
1106
- var treeBefore = {
1107
- displayName: 'View',
1108
- children: [
1109
- {
1110
- displayName: 'Foo',
1111
- children: [],
1112
- },
1113
- ],
1114
- };
1115
-
1116
- var elementAfter = <View><Bar /></View>;
1117
- var treeAfter = {
1118
- displayName: 'View',
1119
- children: [
1120
- {
1121
- displayName: 'Bar',
1122
- children: [],
1123
- },
1124
- ],
1125
- };
1126
-
1127
- assertTreeMatches([
1128
- [elementBefore, treeBefore],
1129
- [elementAfter, treeAfter],
1130
- ]);
1131
- });
1132
-
1133
- it('updates a single composite child of the same type', () => {
1134
- function Foo({children}) {
1135
- return children;
1136
- }
1137
-
1138
- var elementBefore = <View><Foo><View /></Foo></View>;
1139
- var treeBefore = {
1140
- displayName: 'View',
1141
- children: [
1142
- {
1143
- displayName: 'Foo',
1144
- children: [
1145
- {
1146
- displayName: 'View',
1147
- children: [],
1148
- },
1149
- ],
1150
- },
1151
- ],
1152
- };
1153
-
1154
- var elementAfter = <View><Foo><Image /></Foo></View>;
1155
- var treeAfter = {
1156
- displayName: 'View',
1157
- children: [
1158
- {
1159
- displayName: 'Foo',
1160
- children: [
1161
- {
1162
- displayName: 'Image',
1163
- children: [],
1164
- },
1165
- ],
1166
- },
1167
- ],
1168
- };
1169
-
1170
- assertTreeMatches([
1171
- [elementBefore, treeBefore],
1172
- [elementAfter, treeAfter],
1173
- ]);
1174
- });
1175
-
1176
- it('updates from no children to a single composite child', () => {
1177
- function Foo() {
1178
- return null;
1179
- }
1180
-
1181
- var elementBefore = <View />;
1182
- var treeBefore = {
1183
- displayName: 'View',
1184
- children: [],
1185
- };
1186
-
1187
- var elementAfter = <View><Foo /></View>;
1188
- var treeAfter = {
1189
- displayName: 'View',
1190
- children: [
1191
- {
1192
- displayName: 'Foo',
1193
- children: [],
1194
- },
1195
- ],
1196
- };
1197
-
1198
- assertTreeMatches([
1199
- [elementBefore, treeBefore],
1200
- [elementAfter, treeAfter],
1201
- ]);
1202
- });
1203
-
1204
- it('updates from a single composite child to no children', () => {
1205
- function Foo() {
1206
- return null;
1207
- }
1208
-
1209
- var elementBefore = <View><Foo /></View>;
1210
- var treeBefore = {
1211
- displayName: 'View',
1212
- children: [
1213
- {
1214
- displayName: 'Foo',
1215
- children: [],
1216
- },
1217
- ],
1218
- };
1219
-
1220
- var elementAfter = <View />;
1221
- var treeAfter = {
1222
- displayName: 'View',
1223
- children: [],
1224
- };
1225
-
1226
- assertTreeMatches([
1227
- [elementBefore, treeBefore],
1228
- [elementAfter, treeAfter],
1229
- ]);
1230
- });
1231
-
1232
- it('updates mixed children', () => {
1233
- function Foo() {
1234
- return <View />;
1235
- }
1236
- var element1 = (
1237
- <View>
1238
- <Text>hi</Text>
1239
- {false}
1240
- <Text>{42}</Text>
1241
- {null}
1242
- <Foo />
1243
- </View>
1244
- );
1245
- var tree1 = {
1246
- displayName: 'View',
1247
- children: [
1248
- {
1249
- displayName: 'Text',
1250
- children: [
1251
- {
1252
- displayName: 'RCText',
1253
- children: [
1254
- {
1255
- displayName: '#text',
1256
- text: 'hi',
1257
- },
1258
- ],
1259
- },
1260
- ],
1261
- },
1262
- {
1263
- displayName: 'Text',
1264
- children: [
1265
- {
1266
- displayName: 'RCText',
1267
- children: [
1268
- {
1269
- displayName: '#text',
1270
- text: '42',
1271
- },
1272
- ],
1273
- },
1274
- ],
1275
- },
1276
- {
1277
- displayName: 'Foo',
1278
- children: [
1279
- {
1280
- displayName: 'View',
1281
- children: [],
1282
- },
1283
- ],
1284
- },
1285
- ],
1286
- };
1287
-
1288
- var element2 = (
1289
- <View>
1290
- <Foo />
1291
- {false}
1292
- <Text>hi</Text>
1293
- {null}
1294
- </View>
1295
- );
1296
- var tree2 = {
1297
- displayName: 'View',
1298
- children: [
1299
- {
1300
- displayName: 'Foo',
1301
- children: [
1302
- {
1303
- displayName: 'View',
1304
- children: [],
1305
- },
1306
- ],
1307
- },
1308
- {
1309
- displayName: 'Text',
1310
- children: [
1311
- {
1312
- displayName: 'RCText',
1313
- children: [
1314
- {
1315
- displayName: '#text',
1316
- text: 'hi',
1317
- },
1318
- ],
1319
- },
1320
- ],
1321
- },
1322
- ],
1323
- };
1324
-
1325
- var element3 = (
1326
- <View>
1327
- <Foo />
1328
- </View>
1329
- );
1330
- var tree3 = {
1331
- displayName: 'View',
1332
- children: [
1333
- {
1334
- displayName: 'Foo',
1335
- children: [
1336
- {
1337
- displayName: 'View',
1338
- children: [],
1339
- },
1340
- ],
1341
- },
1342
- ],
1343
- };
1344
-
1345
- assertTreeMatches([
1346
- [element1, tree1],
1347
- [element2, tree2],
1348
- [element3, tree3],
1349
- ]);
1350
- });
1351
- });
1352
-
1353
- describe('functional component', () => {
1354
- it('updates with a host child', () => {
1355
- function Foo({children}) {
1356
- return children;
1357
- }
1358
-
1359
- var elementBefore = <Foo><View /></Foo>;
1360
- var treeBefore = {
1361
- displayName: 'Foo',
1362
- children: [
1363
- {
1364
- displayName: 'View',
1365
- children: [],
1366
- },
1367
- ],
1368
- };
1369
-
1370
- var elementAfter = <Foo><Image /></Foo>;
1371
- var treeAfter = {
1372
- displayName: 'Foo',
1373
- children: [
1374
- {
1375
- displayName: 'Image',
1376
- children: [],
1377
- },
1378
- ],
1379
- };
1380
-
1381
- assertTreeMatches([
1382
- [elementBefore, treeBefore],
1383
- [elementAfter, treeAfter],
1384
- ]);
1385
- });
1386
-
1387
- it('updates from null to a host child', () => {
1388
- function Foo({children}) {
1389
- return children;
1390
- }
1391
-
1392
- var elementBefore = <Foo>{null}</Foo>;
1393
- var treeBefore = {
1394
- displayName: 'Foo',
1395
- children: [],
1396
- };
1397
-
1398
- var elementAfter = <Foo><View /></Foo>;
1399
- var treeAfter = {
1400
- displayName: 'Foo',
1401
- children: [
1402
- {
1403
- displayName: 'View',
1404
- children: [],
1405
- },
1406
- ],
1407
- };
1408
-
1409
- assertTreeMatches([
1410
- [elementBefore, treeBefore],
1411
- [elementAfter, treeAfter],
1412
- ]);
1413
- });
1414
-
1415
- it('updates from a host child to null', () => {
1416
- function Foo({children}) {
1417
- return children;
1418
- }
1419
-
1420
- var elementBefore = <Foo><View /></Foo>;
1421
- var treeBefore = {
1422
- displayName: 'Foo',
1423
- children: [
1424
- {
1425
- displayName: 'View',
1426
- children: [],
1427
- },
1428
- ],
1429
- };
1430
-
1431
- var elementAfter = <Foo>{null}</Foo>;
1432
- var treeAfter = {
1433
- displayName: 'Foo',
1434
- children: [],
1435
- };
1436
-
1437
- assertTreeMatches([
1438
- [elementBefore, treeBefore],
1439
- [elementAfter, treeAfter],
1440
- ]);
1441
- });
1442
-
1443
- it('updates from a host child to a composite child', () => {
1444
- function Bar() {
1445
- return null;
1446
- }
1447
-
1448
- function Foo({children}) {
1449
- return children;
1450
- }
1451
-
1452
- var elementBefore = <Foo><View /></Foo>;
1453
- var treeBefore = {
1454
- displayName: 'Foo',
1455
- children: [
1456
- {
1457
- displayName: 'View',
1458
- children: [],
1459
- },
1460
- ],
1461
- };
1462
-
1463
- var elementAfter = <Foo><Bar /></Foo>;
1464
- var treeAfter = {
1465
- displayName: 'Foo',
1466
- children: [
1467
- {
1468
- displayName: 'Bar',
1469
- children: [],
1470
- },
1471
- ],
1472
- };
1473
-
1474
- assertTreeMatches([
1475
- [elementBefore, treeBefore],
1476
- [elementAfter, treeAfter],
1477
- ]);
1478
- });
1479
-
1480
- it('updates from a composite child to a host child', () => {
1481
- function Bar() {
1482
- return null;
1483
- }
1484
-
1485
- function Foo({children}) {
1486
- return children;
1487
- }
1488
-
1489
- var elementBefore = <Foo><Bar /></Foo>;
1490
- var treeBefore = {
1491
- displayName: 'Foo',
1492
- children: [
1493
- {
1494
- displayName: 'Bar',
1495
- children: [],
1496
- },
1497
- ],
1498
- };
1499
-
1500
- var elementAfter = <Foo><View /></Foo>;
1501
- var treeAfter = {
1502
- displayName: 'Foo',
1503
- children: [
1504
- {
1505
- displayName: 'View',
1506
- children: [],
1507
- },
1508
- ],
1509
- };
1510
-
1511
- assertTreeMatches([
1512
- [elementBefore, treeBefore],
1513
- [elementAfter, treeAfter],
1514
- ]);
1515
- });
1516
-
1517
- it('updates from null to a composite child', () => {
1518
- function Bar() {
1519
- return null;
1520
- }
1521
-
1522
- function Foo({children}) {
1523
- return children;
1524
- }
1525
-
1526
- var elementBefore = <Foo>{null}</Foo>;
1527
- var treeBefore = {
1528
- displayName: 'Foo',
1529
- children: [],
1530
- };
1531
-
1532
- var elementAfter = <Foo><Bar /></Foo>;
1533
- var treeAfter = {
1534
- displayName: 'Foo',
1535
- children: [
1536
- {
1537
- displayName: 'Bar',
1538
- children: [],
1539
- },
1540
- ],
1541
- };
1542
-
1543
- assertTreeMatches([
1544
- [elementBefore, treeBefore],
1545
- [elementAfter, treeAfter],
1546
- ]);
1547
- });
1548
-
1549
- it('updates from a composite child to null', () => {
1550
- function Bar() {
1551
- return null;
1552
- }
1553
-
1554
- function Foo({children}) {
1555
- return children;
1556
- }
1557
-
1558
- var elementBefore = <Foo><Bar /></Foo>;
1559
- var treeBefore = {
1560
- displayName: 'Foo',
1561
- children: [
1562
- {
1563
- displayName: 'Bar',
1564
- children: [],
1565
- },
1566
- ],
1567
- };
1568
-
1569
- var elementAfter = <Foo>{null}</Foo>;
1570
- var treeAfter = {
1571
- displayName: 'Foo',
1572
- children: [],
1573
- };
1574
-
1575
- assertTreeMatches([
1576
- [elementBefore, treeBefore],
1577
- [elementAfter, treeAfter],
1578
- ]);
1579
- });
1580
- });
1581
-
1582
- describe('class component', () => {
1583
- it('updates with a host child', () => {
1584
- class Foo extends React.Component {
1585
- render() {
1586
- return this.props.children;
1587
- }
1588
- }
1589
-
1590
- var elementBefore = <Foo><View /></Foo>;
1591
- var treeBefore = {
1592
- displayName: 'Foo',
1593
- children: [
1594
- {
1595
- displayName: 'View',
1596
- children: [],
1597
- },
1598
- ],
1599
- };
1600
-
1601
- var elementAfter = <Foo><Image /></Foo>;
1602
- var treeAfter = {
1603
- displayName: 'Foo',
1604
- children: [
1605
- {
1606
- displayName: 'Image',
1607
- children: [],
1608
- },
1609
- ],
1610
- };
1611
-
1612
- assertTreeMatches([
1613
- [elementBefore, treeBefore],
1614
- [elementAfter, treeAfter],
1615
- ]);
1616
- });
1617
-
1618
- it('updates from null to a host child', () => {
1619
- class Foo extends React.Component {
1620
- render() {
1621
- return this.props.children;
1622
- }
1623
- }
1624
-
1625
- var elementBefore = <Foo>{null}</Foo>;
1626
- var treeBefore = {
1627
- displayName: 'Foo',
1628
- children: [],
1629
- };
1630
-
1631
- var elementAfter = <Foo><View /></Foo>;
1632
- var treeAfter = {
1633
- displayName: 'Foo',
1634
- children: [
1635
- {
1636
- displayName: 'View',
1637
- children: [],
1638
- },
1639
- ],
1640
- };
1641
-
1642
- assertTreeMatches([
1643
- [elementBefore, treeBefore],
1644
- [elementAfter, treeAfter],
1645
- ]);
1646
- });
1647
-
1648
- it('updates from a host child to null', () => {
1649
- class Foo extends React.Component {
1650
- render() {
1651
- return this.props.children;
1652
- }
1653
- }
1654
-
1655
- var elementBefore = <Foo><View /></Foo>;
1656
- var treeBefore = {
1657
- displayName: 'Foo',
1658
- children: [
1659
- {
1660
- displayName: 'View',
1661
- children: [],
1662
- },
1663
- ],
1664
- };
1665
-
1666
- var elementAfter = <Foo>{null}</Foo>;
1667
- var treeAfter = {
1668
- displayName: 'Foo',
1669
- children: [],
1670
- };
1671
-
1672
- assertTreeMatches([
1673
- [elementBefore, treeBefore],
1674
- [elementAfter, treeAfter],
1675
- ]);
1676
- });
1677
-
1678
- it('updates from a host child to a composite child', () => {
1679
- class Bar extends React.Component {
1680
- render() {
1681
- return null;
1682
- }
1683
- }
1684
-
1685
- class Foo extends React.Component {
1686
- render() {
1687
- return this.props.children;
1688
- }
1689
- }
1690
-
1691
- var elementBefore = <Foo><View /></Foo>;
1692
- var treeBefore = {
1693
- displayName: 'Foo',
1694
- children: [
1695
- {
1696
- displayName: 'View',
1697
- children: [],
1698
- },
1699
- ],
1700
- };
1701
-
1702
- var elementAfter = <Foo><Bar /></Foo>;
1703
- var treeAfter = {
1704
- displayName: 'Foo',
1705
- children: [
1706
- {
1707
- displayName: 'Bar',
1708
- children: [],
1709
- },
1710
- ],
1711
- };
1712
-
1713
- assertTreeMatches([
1714
- [elementBefore, treeBefore],
1715
- [elementAfter, treeAfter],
1716
- ]);
1717
- });
1718
-
1719
- it('updates from a composite child to a host child', () => {
1720
- class Bar extends React.Component {
1721
- render() {
1722
- return null;
1723
- }
1724
- }
1725
-
1726
- class Foo extends React.Component {
1727
- render() {
1728
- return this.props.children;
1729
- }
1730
- }
1731
-
1732
- var elementBefore = <Foo><Bar /></Foo>;
1733
- var treeBefore = {
1734
- displayName: 'Foo',
1735
- children: [
1736
- {
1737
- displayName: 'Bar',
1738
- children: [],
1739
- },
1740
- ],
1741
- };
1742
-
1743
- var elementAfter = <Foo><View /></Foo>;
1744
- var treeAfter = {
1745
- displayName: 'Foo',
1746
- children: [
1747
- {
1748
- displayName: 'View',
1749
- children: [],
1750
- },
1751
- ],
1752
- };
1753
-
1754
- assertTreeMatches([
1755
- [elementBefore, treeBefore],
1756
- [elementAfter, treeAfter],
1757
- ]);
1758
- });
1759
-
1760
- it('updates from null to a composite child', () => {
1761
- class Bar extends React.Component {
1762
- render() {
1763
- return null;
1764
- }
1765
- }
1766
-
1767
- class Foo extends React.Component {
1768
- render() {
1769
- return this.props.children;
1770
- }
1771
- }
1772
-
1773
- var elementBefore = <Foo>{null}</Foo>;
1774
- var treeBefore = {
1775
- displayName: 'Foo',
1776
- children: [],
1777
- };
1778
-
1779
- var elementAfter = <Foo><Bar /></Foo>;
1780
- var treeAfter = {
1781
- displayName: 'Foo',
1782
- children: [
1783
- {
1784
- displayName: 'Bar',
1785
- children: [],
1786
- },
1787
- ],
1788
- };
1789
-
1790
- assertTreeMatches([
1791
- [elementBefore, treeBefore],
1792
- [elementAfter, treeAfter],
1793
- ]);
1794
- });
1795
-
1796
- it('updates from a composite child to null', () => {
1797
- class Bar extends React.Component {
1798
- render() {
1799
- return null;
1800
- }
1801
- }
1802
-
1803
- class Foo extends React.Component {
1804
- render() {
1805
- return this.props.children;
1806
- }
1807
- }
1808
-
1809
- var elementBefore = <Foo><Bar /></Foo>;
1810
- var treeBefore = {
1811
- displayName: 'Foo',
1812
- children: [
1813
- {
1814
- displayName: 'Bar',
1815
- children: [],
1816
- },
1817
- ],
1818
- };
1819
-
1820
- var elementAfter = <Foo>{null}</Foo>;
1821
- var treeAfter = {
1822
- displayName: 'Foo',
1823
- children: [],
1824
- };
1825
-
1826
- assertTreeMatches([
1827
- [elementBefore, treeBefore],
1828
- [elementAfter, treeAfter],
1829
- ]);
1830
- });
1831
- });
1832
- });
1833
-
1834
- it('tracks owner correctly', () => {
1835
- class Foo extends React.Component {
1836
- render() {
1837
- return <Bar><Text>Hi.</Text></Bar>;
1838
- }
1839
- }
1840
- function Bar({children}) {
1841
- return <View>{children}<Text>Mom</Text></View>;
1842
- }
1843
-
1844
- // Note that owner is not calculated for text nodes
1845
- // because they are not created from real elements.
1846
- var element = <View><Foo /></View>;
1847
- var tree = {
1848
- displayName: 'View',
1849
- children: [
1850
- {
1851
- displayName: 'Foo',
1852
- children: [
1853
- {
1854
- displayName: 'Bar',
1855
- ownerDisplayName: 'Foo',
1856
- children: [
1857
- {
1858
- displayName: 'View',
1859
- ownerDisplayName: 'Bar',
1860
- children: [
1861
- {
1862
- displayName: 'Text',
1863
- ownerDisplayName: 'Foo',
1864
- children: [
1865
- {
1866
- displayName: 'RCText',
1867
- ownerDisplayName: 'Text',
1868
- children: [
1869
- {
1870
- displayName: '#text',
1871
- text: 'Hi.',
1872
- },
1873
- ],
1874
- },
1875
- ],
1876
- },
1877
- {
1878
- displayName: 'Text',
1879
- ownerDisplayName: 'Bar',
1880
- children: [
1881
- {
1882
- displayName: 'RCText',
1883
- ownerDisplayName: 'Text',
1884
- children: [
1885
- {
1886
- displayName: '#text',
1887
- text: 'Mom',
1888
- },
1889
- ],
1890
- },
1891
- ],
1892
- },
1893
- ],
1894
- },
1895
- ],
1896
- },
1897
- ],
1898
- },
1899
- ],
1900
- };
1901
- assertTreeMatches([element, tree], {includeOwnerDisplayName: true});
1902
- });
1903
-
1904
- it('purges unmounted components automatically', () => {
1905
- var renderBar = true;
1906
- var fooInstance;
1907
- var barInstance;
1908
-
1909
- class Foo extends React.Component {
1910
- render() {
1911
- fooInstance = ReactInstanceMap.get(this);
1912
- return renderBar ? <Bar /> : null;
1913
- }
1914
- }
1915
-
1916
- class Bar extends React.Component {
1917
- render() {
1918
- barInstance = ReactInstanceMap.get(this);
1919
- return null;
1920
- }
1921
- }
1922
-
1923
- ReactNative.render(<Foo />, 1);
1924
- ReactComponentTreeTestUtils.expectTree(
1925
- barInstance._debugID,
1926
- {
1927
- displayName: 'Bar',
1928
- parentDisplayName: 'Foo',
1929
- parentID: fooInstance._debugID,
1930
- children: [],
1931
- },
1932
- 'Foo',
1933
- );
1934
-
1935
- renderBar = false;
1936
- ReactNative.render(<Foo />, 1);
1937
- ReactComponentTreeTestUtils.expectTree(
1938
- barInstance._debugID,
1939
- {
1940
- displayName: 'Unknown',
1941
- children: [],
1942
- parentID: null,
1943
- },
1944
- 'Foo',
1945
- );
1946
-
1947
- ReactNative.unmountComponentAtNode(1);
1948
- ReactComponentTreeTestUtils.expectTree(
1949
- barInstance._debugID,
1950
- {
1951
- displayName: 'Unknown',
1952
- children: [],
1953
- parentID: null,
1954
- },
1955
- 'Foo',
1956
- );
1957
- });
1958
-
1959
- it('reports update counts', () => {
1960
- ReactNative.render(<View />, 1);
1961
- var viewID = ReactComponentTreeHook.getRootIDs()[0];
1962
- expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1963
-
1964
- ReactNative.render(<Image />, 1);
1965
- var imageID = ReactComponentTreeHook.getRootIDs()[0];
1966
- expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1967
- expectDev(ReactComponentTreeHook.getUpdateCount(imageID)).toEqual(0);
1968
-
1969
- ReactNative.render(<Image />, 1);
1970
- expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1971
- expectDev(ReactComponentTreeHook.getUpdateCount(imageID)).toEqual(1);
1972
-
1973
- ReactNative.render(<Image />, 1);
1974
- expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1975
- expectDev(ReactComponentTreeHook.getUpdateCount(imageID)).toEqual(2);
1976
-
1977
- ReactNative.unmountComponentAtNode(1);
1978
- expectDev(ReactComponentTreeHook.getUpdateCount(viewID)).toEqual(0);
1979
- expectDev(ReactComponentTreeHook.getUpdateCount(imageID)).toEqual(0);
1980
- });
1981
-
1982
- it('does not report top-level wrapper as a root', () => {
1983
- ReactNative.render(<View><Image /></View>, 1);
1984
- expectDev(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([
1985
- 'View',
1986
- ]);
1987
-
1988
- ReactNative.render(<View><Text /></View>, 1);
1989
- expectDev(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([
1990
- 'View',
1991
- ]);
1992
-
1993
- ReactNative.unmountComponentAtNode(1);
1994
- expectDev(ReactComponentTreeTestUtils.getRootDisplayNames()).toEqual([]);
1995
- expectDev(ReactComponentTreeTestUtils.getRegisteredDisplayNames()).toEqual(
1996
- [],
1997
- );
1998
- });
1999
-});