@@ -19,6 +19,7 @@ import {
1919 FunctionalComponent ,
2020 ClassComponent ,
2121 HostComponent ,
22+ HostPortal ,
2223 HostText ,
2324 HostRoot ,
2425} from 'shared/ReactTypeOfWork' ;
@@ -286,60 +287,86 @@ function toJSON(inst: Instance | TextInstance): ReactTestRendererNode {
286287 }
287288}
288289
289- function nodeAndSiblingsTrees ( nodeWithSibling : ?Fiber ) {
290+ function childrenToTree ( node ) {
291+ if ( ! node ) {
292+ return null ;
293+ }
294+ const children = nodeAndSiblingsArray ( node ) ;
295+ if ( children . length === 0 ) {
296+ return null ;
297+ } else if ( children . length === 1 ) {
298+ return toTree ( children [ 0 ] ) ;
299+ }
300+ return flatten ( children . map ( toTree ) ) ;
301+ }
302+
303+ function nodeAndSiblingsArray ( nodeWithSibling ) {
290304 const array = [ ] ;
291305 let node = nodeWithSibling ;
292306 while ( node != null ) {
293307 array . push ( node ) ;
294308 node = node . sibling ;
295309 }
296- const trees = array . map ( toTree ) ;
297- return trees . length ? trees : null ;
310+ return array ;
298311}
299312
300- function hasSiblings ( node : ?Fiber ) {
301- return node && node . sibling ;
313+ function flatten ( arr ) {
314+ const result = [ ] ;
315+ const stack = [ { i : 0 , array : arr } ] ;
316+ while ( stack . length ) {
317+ const n = stack . pop ( ) ;
318+ while ( n . i < n . array . length ) {
319+ const el = n . array [ n . i ] ;
320+ n . i += 1 ;
321+ if ( Array . isArray ( el ) ) {
322+ stack . push ( n ) ;
323+ stack . push ( { i : 0 , array : el } ) ;
324+ break ;
325+ }
326+ result . push ( el ) ;
327+ }
328+ }
329+ return result ;
302330}
303331
304332function toTree ( node : ?Fiber ) {
305333 if ( node == null ) {
306334 return null ;
307335 }
308336 switch ( node . tag ) {
309- case HostRoot : // 3
310- return toTree ( node . child ) ;
337+ case HostRoot :
338+ return childrenToTree ( node . child ) ;
339+ case HostPortal :
340+ return childrenToTree ( node . child ) ;
311341 case ClassComponent :
312342 return {
313343 nodeType : 'component' ,
314344 type : node . type ,
315345 props : { ...node . memoizedProps } ,
316346 instance : node . stateNode ,
317- rendered : hasSiblings ( node . child )
318- ? nodeAndSiblingsTrees ( node . child )
319- : toTree ( node . child ) ,
347+ rendered : childrenToTree ( node . child ) ,
320348 } ;
321- case FunctionalComponent : // 1
349+ case FunctionalComponent :
322350 return {
323351 nodeType : 'component' ,
324352 type : node . type ,
325353 props : { ...node . memoizedProps } ,
326354 instance : null ,
327- rendered : hasSiblings ( node . child )
328- ? nodeAndSiblingsTrees ( node . child )
329- : toTree ( node . child ) ,
355+ rendered : childrenToTree ( node . child ) ,
330356 } ;
331- case HostComponent : // 5
357+ case HostComponent : {
332358 return {
333359 nodeType : 'host' ,
334360 type : node . type ,
335361 props : { ...node . memoizedProps } ,
336362 instance : null , // TODO: use createNodeMock here somehow?
337- rendered : nodeAndSiblingsTrees ( node . child ) ,
363+ rendered : flatten ( nodeAndSiblingsArray ( node . child ) . map ( toTree ) ) ,
338364 } ;
339- case HostText : // 6
365+ }
366+ case HostText :
340367 return node . stateNode . text ;
341- case Fragment : // 10
342- return toTree ( node . child ) ;
368+ case Fragment :
369+ return childrenToTree ( node . child ) ;
343370 default :
344371 invariant (
345372 false ,
0 commit comments