diff --git a/packages/react-native/Libraries/Components/ScrollView/__tests__/ScrollView-viewCulling-itest.js b/packages/react-native/Libraries/Components/ScrollView/__tests__/ScrollView-viewCulling-itest.js index cafe96b9615..1883c7dc62d 100644 --- a/packages/react-native/Libraries/Components/ScrollView/__tests__/ScrollView-viewCulling-itest.js +++ b/packages/react-native/Libraries/Components/ScrollView/__tests__/ScrollView-viewCulling-itest.js @@ -789,111 +789,6 @@ test('culling when ScrollView parent has transform', () => { ]); }); -test('view flattening with culling', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - let maybeNode; - - Fantom.runTask(() => { - root.render( - { - maybeNode = node; - }}> - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); - - const element = ensureInstance(maybeNode, ReactNativeElement); - - Fantom.scrollTo(element, { - x: 0, - y: 60, - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - ]); - - // force view to be unflattened. - Fantom.runTask(() => { - root.render( - { - maybeNode = node; - }}> - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "View", nativeID: "child"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Create {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - ]); - - // force view to be flattened. - Fantom.runTask(() => { - root.render( - { - maybeNode = node; - }}> - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "View", nativeID: "child"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Delete {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - ]); -}); - test('culling inside of Modal', () => { const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); let maybeNode; @@ -960,603 +855,710 @@ test('culling inside of Modal', () => { ]); }); -test('scroll view parent is unflattened and culled view becomes visible', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); +describe('reparenting', () => { + test('view flattening with culling', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); + let maybeNode; - Fantom.runTask(() => { - root.render( - - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); - - Fantom.runTask(() => { - root.render( - - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Remove {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - 'Create {type: "View", nativeID: "unflattened"}', - 'Update {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', - 'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', - ]); -}); - -test('scroll view parent is flattened and culled view becomes visible', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - - Fantom.runTask(() => { - root.render( - - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "View", nativeID: "unflattened"}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', - ]); - - Fantom.runTask(() => { - root.render( - - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Remove {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', - 'Remove {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', - 'Delete {type: "View", nativeID: "unflattened"}', - 'Update {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); -}); - -test('scroll view parent is flattened and view becomes culled', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - - Fantom.runTask(() => { - root.render( - - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "View", nativeID: "unflattened"}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', - ]); - - Fantom.runTask(() => { - root.render( - - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Remove {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', - 'Remove {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', - 'Delete {type: "View", nativeID: "unflattened"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Delete {type: "View", nativeID: "child"}', - 'Update {type: "View", nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); -}); - -test('scroll view parent is unflattened and view becomes culled', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - - Fantom.runTask(() => { - root.render( - - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); - - Fantom.runTask(() => { - root.render( - - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Remove {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - 'Create {type: "View", nativeID: "unflattened"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Delete {type: "View", nativeID: "child"}', - 'Update {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', - 'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', - ]); -}); - -test('parent-child flattening with culling', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - - Fantom.runTask(() => { - root.render( - - { + root.render( + { + maybeNode = node; }}> + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); + + const element = ensureInstance(maybeNode, ReactNativeElement); + + Fantom.scrollTo(element, { + x: 0, + y: 60, + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + ]); + + // force view to be unflattened. + Fantom.runTask(() => { + root.render( + { + maybeNode = node; + }}> + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "View", nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + ]); + + // force view to be flattened. + Fantom.runTask(() => { + root.render( + { + maybeNode = node; + }}> + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "View", nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Delete {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + ]); + }); + + test('scroll view parent is unflattened and culled view becomes visible', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Remove {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + 'Create {type: "View", nativeID: "unflattened"}', + 'Update {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', + 'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', + ]); + }); + + test('scroll view parent is flattened and culled view becomes visible', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "View", nativeID: "unflattened"}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', + ]); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Remove {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', + 'Remove {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', + 'Delete {type: "View", nativeID: "unflattened"}', + 'Update {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); + }); + + test('scroll view parent is flattened and view becomes culled', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "View", nativeID: "unflattened"}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', + ]); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Remove {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', + 'Remove {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', + 'Delete {type: "View", nativeID: "unflattened"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Delete {type: "View", nativeID: "child"}', + 'Update {type: "View", nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); + }); + + test('scroll view parent is unflattened and view becomes culled', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); + + Fantom.runTask(() => { + root.render( + + + + + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Remove {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + 'Create {type: "View", nativeID: "unflattened"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Delete {type: "View", nativeID: "child"}', + 'Update {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (root), index: 0, nativeID: "unflattened"}', + 'Insert {type: "ScrollView", parentNativeID: "unflattened", index: 0, nativeID: (N/A)}', + ]); + }); + + test('parent-child flattening with culling', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); + + Fantom.runTask(() => { + root.render( + + + style={{ + marginTop: 50, + opacity: 0, + }}> + + - - , - ); - }); + , + ); + }); - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); - // force parent-child to be flattened. - Fantom.runTask(() => { - root.render( - - + // force parent-child to be flattened. + Fantom.runTask(() => { + root.render( + + style={{ + marginTop: 50, + }}> + + - - , - ); + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "View", nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Delete {type: "View", nativeID: (N/A)}', + 'Delete {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + ]); }); - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "View", nativeID: "child"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Delete {type: "View", nativeID: (N/A)}', - 'Delete {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - ]); -}); + test('parent-child switching from unflattened-flattened to flattened-unflattened', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); -test('parent-child switching from unflattened-flattened to flattened-unflattened', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - - Fantom.runTask(() => { - root.render( - - + Fantom.runTask(() => { + root.render( + - - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); - - // force view to be flattened. - Fantom.runTask(() => { - root.render( - - - + style={{ + marginTop: 50, + }}> + + - - , - ); - }); + , + ); + }); - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "View", nativeID: "child"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Delete {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - ]); -}); + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); -test('unflattening and creating a subtree that is partially culled', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - - // First render with a flattened view container that is visible. - Fantom.runTask(() => { - root.render( - - - , - ); - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); - - let maybeNode = null; - - // Now update opacity to unflattned the container and add a child that has a culled descendant. - Fantom.runTask(() => { - root.render( - { - maybeNode = node; - }} - contentOffset={{x: 0, y: 111}}> - + // force view to be flattened. + Fantom.runTask(() => { + root.render( + + marginTop: 50, + opacity: 0, + }}> + + - - , - ); + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "View", nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Delete {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + ]); }); - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Update {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - ]); + test('unflattening and creating a subtree that is partially culled', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - const element = ensureInstance(maybeNode, ReactNativeElement); + // First render with a flattened view container that is visible. + Fantom.runTask(() => { + root.render( + + + , + ); + }); - // Scroll down to see the grandchild. - Fantom.scrollTo(element, { - x: 0, - y: 115, - }); + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "grandchild"}', - 'Insert {type: "View", parentNativeID: "child", index: 0, nativeID: "grandchild"}', - ]); -}); + let maybeNode = null; -test('flattening and deleting a subtree that is partially culled', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - - // First render with a unflattened view container that is visible and a subtree that is partially culled. - Fantom.runTask(() => { - root.render( - - - - - - - , - ); - }); - - // All views are mounted, except for the grandchild. - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); - - // Now change opacity to the default to flatten the container and delete container's subtree. - Fantom.runTask(() => { - root.render( - - { + root.render( + { + maybeNode = node; }} - /> - , - ); - }); - - // Note that the grandchild is not deleted because it was not previously mounted. - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Update {type: "View", nativeID: (N/A)}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Delete {type: "View", nativeID: (N/A)}', - 'Delete {type: "View", nativeID: "child"}', - ]); -}); - -test('parent-child switching from unflattened-flattened to flattened-unflattened and grandchild is culled', () => { - const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - - // First render unflattened view container with flattened child that has a culled grandchild. - Fantom.runTask(() => { - root.render( - - + contentOffset={{x: 0, y: 111}}> + nativeID="child" + style={{ + marginTop: 10, + height: 10, + width: 10, + }}> + + - - , - ); + , + ); + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Update {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + ]); + + const element = ensureInstance(maybeNode, ReactNativeElement); + + // Scroll down to see the grandchild. + Fantom.scrollTo(element, { + x: 0, + y: 115, + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "grandchild"}', + 'Insert {type: "View", parentNativeID: "child", index: 0, nativeID: "grandchild"}', + ]); }); - // Note that `grandchild` is not mounted. - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "RootView", nativeID: (root)}', - 'Create {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', - ]); + test('flattening and deleting a subtree that is partially culled', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); - let maybeNode = null; + // First render with a unflattened view container that is visible and a subtree that is partially culled. + Fantom.runTask(() => { + root.render( + + + + + + + , + ); + }); - // Now change unflattened view container to flattened and change its child to be unflattened. - Fantom.runTask(() => { - root.render( - { - maybeNode = node; - }} - contentOffset={{x: 0, y: 60}}> - + // All views are mounted, except for the grandchild. + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); + + // Now change opacity to the default to flatten the container and delete container's subtree. + Fantom.runTask(() => { + root.render( + + , + ); + }); + + // Note that the grandchild is not deleted because it was not previously mounted. + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Update {type: "View", nativeID: (N/A)}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "child"}', + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Delete {type: "View", nativeID: (N/A)}', + 'Delete {type: "View", nativeID: "child"}', + ]); + }); + + test('parent-child switching from unflattened-flattened to flattened-unflattened and grandchild is culled', () => { + const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100}); + + // First render unflattened view container with flattened child that has a culled grandchild. + Fantom.runTask(() => { + root.render( + + + style={{ + marginTop: 50, + }}> + + - - , - ); + , + ); + }); + + // Note that `grandchild` is not mounted. + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "RootView", nativeID: (root)}', + 'Create {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}', + ]); + + let maybeNode = null; + + // Now change unflattened view container to flattened and change its child to be unflattened. + Fantom.runTask(() => { + root.render( + { + maybeNode = node; + }} + contentOffset={{x: 0, y: 60}}> + + + + + + , + ); + }); + + // Note that `grandchild` is not mounted. + expect(root.takeMountingManagerLogs()).toEqual([ + 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + 'Delete {type: "View", nativeID: (N/A)}', + 'Create {type: "View", nativeID: (N/A)}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', + ]); + + const element = ensureInstance(maybeNode, ReactNativeElement); + + // Scroll to reveal grandchild. + Fantom.scrollTo(element, { + x: 0, + y: 70, + }); + + expect(root.takeMountingManagerLogs()).toEqual([ + 'Update {type: "ScrollView", nativeID: (N/A)}', + 'Create {type: "View", nativeID: "grandchild"}', + 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "grandchild"}', + ]); }); - - // Note that `grandchild` is not mounted. - expect(root.takeMountingManagerLogs()).toEqual([ - 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - 'Delete {type: "View", nativeID: (N/A)}', - 'Create {type: "View", nativeID: (N/A)}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}', - ]); - - const element = ensureInstance(maybeNode, ReactNativeElement); - - // Scroll to reveal grandchild. - Fantom.scrollTo(element, { - x: 0, - y: 70, - }); - - expect(root.takeMountingManagerLogs()).toEqual([ - 'Update {type: "ScrollView", nativeID: (N/A)}', - 'Create {type: "View", nativeID: "grandchild"}', - 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "grandchild"}', - ]); });