From 367992983096215833fd1828c432bb02da0008f0 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 23 Mar 2020 13:28:46 -0700 Subject: [PATCH] Fabric: Modernizing Yoga Dirty flag test. Summary: Now we using TEST_F thing that allows consilidating initialization. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D20578788 fbshipit-source-id: 103bcb8fdeb3dbf297385cfe56415bd646e16791 --- .../fabric/components/view/tests/ViewTest.cpp | 323 +++++++++--------- 1 file changed, 163 insertions(+), 160 deletions(-) diff --git a/ReactCommon/fabric/components/view/tests/ViewTest.cpp b/ReactCommon/fabric/components/view/tests/ViewTest.cpp index 7faa2ace76e..15bfea1fafc 100644 --- a/ReactCommon/fabric/components/view/tests/ViewTest.cpp +++ b/ReactCommon/fabric/components/view/tests/ViewTest.cpp @@ -20,171 +20,174 @@ using namespace facebook::react; -TEST(ElementTest, testYogaDirtyFlag) { - auto builder = simpleComponentBuilder(); +class YogaDirtyFlagTest : public ::testing::Test { + protected: + ComponentBuilder builder_; + std::shared_ptr rootShadowNode_; + std::shared_ptr innerShadowNode_; + std::shared_ptr scrollViewShadowNode_; - auto rootShadowNode = std::shared_ptr{}; - auto innerShadowNode = std::shared_ptr{}; + YogaDirtyFlagTest() : builder_(simpleComponentBuilder()) { + // clang-format off + auto element = + Element() + .reference(rootShadowNode_) + .tag(1) + .children({ + Element() + .tag(2), + Element() + .tag(3) + .reference(innerShadowNode_) + .children({ + Element() + .tag(4) + .props([] { + /* + * Some non-default props. + */ + auto mutableViewProps = std::make_shared(); + auto &props = *mutableViewProps; + props.nativeId = "native Id"; + props.opacity = 0.5; + props.yogaStyle.alignContent() = YGAlignBaseline; + props.yogaStyle.flexDirection() = YGFlexDirectionRowReverse; + return mutableViewProps; + }), + Element() + .tag(5), + Element() + .tag(6), + Element() + .reference(scrollViewShadowNode_) + .tag(7) + }) + }); + // clang-format on - // clang-format off - auto element = - Element() - .reference(rootShadowNode) - .tag(1) - .children({ - Element() - .tag(2), - Element() - .tag(3) - .reference(innerShadowNode) - .children({ - Element() - .tag(4) - .props([] { - /* - * Some non-default props. - */ - auto mutableViewProps = std::make_shared(); - auto &props = *mutableViewProps; - props.nativeId = "native Id"; - props.opacity = 0.5; - props.yogaStyle.alignContent() = YGAlignBaseline; - props.yogaStyle.flexDirection() = YGFlexDirectionRowReverse; - return mutableViewProps; - }), - Element() - .tag(5), - Element() - .tag(6) - }), - Element() - .tag(9) - }); - // clang-format on + builder_.build(element); - builder.build(element); + /* + * Yoga nodes are dirty right after creation. + */ + EXPECT_TRUE(rootShadowNode_->layoutIfNeeded()); + /* + * Yoga nodes are clean (not dirty) right after layout pass. + */ + EXPECT_FALSE(rootShadowNode_->layoutIfNeeded()); + } +}; + +TEST_F(YogaDirtyFlagTest, cloningPropsWithoutChangingThem) { /* - * Yoga nodes are dirty right after creation. + * Cloning props without changing them must *not* dirty a Yoga node. */ - EXPECT_TRUE(rootShadowNode->layoutIfNeeded()); + auto newRootShadowNode = rootShadowNode_->cloneTree( + innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) { + auto &componentDescriptor = oldShadowNode.getComponentDescriptor(); + auto props = componentDescriptor.cloneProps( + oldShadowNode.getProps(), RawProps()); + return oldShadowNode.clone(ShadowNodeFragment{props}); + }); - /* - * Yoga nodes are clean (not dirty) right after layout pass. - */ - EXPECT_FALSE(rootShadowNode->layoutIfNeeded()); - - { - /* - * Cloning props without changing them must *not* dirty Yoga nodes. - */ - auto newRootShadowNode = - std::static_pointer_cast(rootShadowNode->cloneTree( - innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) { - auto &componentDescriptor = - oldShadowNode.getComponentDescriptor(); - auto props = componentDescriptor.cloneProps( - oldShadowNode.getProps(), RawProps()); - return oldShadowNode.clone(ShadowNodeFragment{props}); - })); - - EXPECT_FALSE(newRootShadowNode->layoutIfNeeded()); - } - - { - /* - * Changing *non-layout* sub-props must *not* dirty Yoga nodes. - */ - auto newRootShadowNode = - std::static_pointer_cast(rootShadowNode->cloneTree( - innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) { - auto viewProps = std::make_shared(); - auto &props = *viewProps; - - props.nativeId = "some new native Id"; - props.foregroundColor = whiteColor(); - props.backgroundColor = blackColor(); - props.opacity = props.opacity + 0.042; - props.zIndex = props.zIndex + 42; - props.shouldRasterize = !props.shouldRasterize; - props.collapsable = !props.collapsable; - - return oldShadowNode.clone(ShadowNodeFragment{viewProps}); - })); - - EXPECT_FALSE(newRootShadowNode->layoutIfNeeded()); - } - - { - /* - * Changing *layout* sub-props *must* dirty Yoga nodes. - */ - auto newRootShadowNode = - std::static_pointer_cast(rootShadowNode->cloneTree( - innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) { - auto viewProps = std::make_shared(); - auto &props = *viewProps; - - props.yogaStyle.alignContent() = YGAlignBaseline; - props.yogaStyle.display() = YGDisplayNone; - - return oldShadowNode.clone(ShadowNodeFragment{viewProps}); - })); - - EXPECT_TRUE(newRootShadowNode->layoutIfNeeded()); - } - - { - /* - * Removing all children *must* dirty Yoga nodes. - */ - auto newRootShadowNode = - std::static_pointer_cast(rootShadowNode->cloneTree( - innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) { - return oldShadowNode.clone( - {ShadowNodeFragment::propsPlaceholder(), - ShadowNode::emptySharedShadowNodeSharedList()}); - })); - - EXPECT_TRUE(newRootShadowNode->layoutIfNeeded()); - } - - { - /* - * Removing the last child *must* dirty Yoga nodes. - */ - auto newRootShadowNode = - std::static_pointer_cast(rootShadowNode->cloneTree( - innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) { - auto children = oldShadowNode.getChildren(); - children.pop_back(); - - std::reverse(children.begin(), children.end()); - - return oldShadowNode.clone( - {ShadowNodeFragment::propsPlaceholder(), - std::make_shared(children)}); - })); - - EXPECT_TRUE(newRootShadowNode->layoutIfNeeded()); - } - - { - /* - * Reversing a list of children *must* dirty Yoga nodes. - */ - auto newRootShadowNode = - std::static_pointer_cast(rootShadowNode->cloneTree( - innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) { - auto children = oldShadowNode.getChildren(); - - std::reverse(children.begin(), children.end()); - - return oldShadowNode.clone( - {ShadowNodeFragment::propsPlaceholder(), - std::make_shared(children)}); - })); - - EXPECT_TRUE(newRootShadowNode->layoutIfNeeded()); - } + EXPECT_FALSE( + static_cast(*newRootShadowNode).layoutIfNeeded()); +} + +TEST_F(YogaDirtyFlagTest, changingNonLayoutSubPropsMustNotDirtyYogaNode) { + /* + * Changing *non-layout* sub-props must *not* dirty a Yoga node. + */ + auto newRootShadowNode = rootShadowNode_->cloneTree( + innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) { + auto viewProps = std::make_shared(); + auto &props = *viewProps; + + props.nativeId = "some new native Id"; + props.foregroundColor = whiteColor(); + props.backgroundColor = blackColor(); + props.opacity = props.opacity + 0.042; + props.zIndex = props.zIndex + 42; + props.shouldRasterize = !props.shouldRasterize; + props.collapsable = !props.collapsable; + + return oldShadowNode.clone(ShadowNodeFragment{viewProps}); + }); + + EXPECT_FALSE( + static_cast(*newRootShadowNode).layoutIfNeeded()); +} + +TEST_F(YogaDirtyFlagTest, changingLayoutSubPropsMustDirtyYogaNode) { + /* + * Changing *layout* sub-props *must* dirty a Yoga node. + */ + auto newRootShadowNode = rootShadowNode_->cloneTree( + innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) { + auto viewProps = std::make_shared(); + auto &props = *viewProps; + + props.yogaStyle.alignContent() = YGAlignBaseline; + props.yogaStyle.display() = YGDisplayNone; + + return oldShadowNode.clone(ShadowNodeFragment{viewProps}); + }); + + EXPECT_TRUE( + static_cast(*newRootShadowNode).layoutIfNeeded()); +} + +TEST_F(YogaDirtyFlagTest, removingAllChildrenMustDirtyYogaNode) { + /* + * Removing all children *must* dirty a Yoga node. + */ + auto newRootShadowNode = rootShadowNode_->cloneTree( + innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) { + return oldShadowNode.clone( + {ShadowNodeFragment::propsPlaceholder(), + ShadowNode::emptySharedShadowNodeSharedList()}); + }); + + EXPECT_TRUE( + static_cast(*newRootShadowNode).layoutIfNeeded()); +} + +TEST_F(YogaDirtyFlagTest, removingLastChildMustDirtyYogaNode) { + /* + * Removing the last child *must* dirty the Yoga node. + */ + auto newRootShadowNode = rootShadowNode_->cloneTree( + innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) { + auto children = oldShadowNode.getChildren(); + children.pop_back(); + + std::reverse(children.begin(), children.end()); + + return oldShadowNode.clone( + {ShadowNodeFragment::propsPlaceholder(), + std::make_shared(children)}); + }); + + EXPECT_TRUE( + static_cast(*newRootShadowNode).layoutIfNeeded()); +} + +TEST_F(YogaDirtyFlagTest, reversingListOfChildrenMustDirtyYogaNode) { + /* + * Reversing a list of children *must* dirty a Yoga node. + */ + auto newRootShadowNode = rootShadowNode_->cloneTree( + innerShadowNode_->getFamily(), [](ShadowNode const &oldShadowNode) { + auto children = oldShadowNode.getChildren(); + + std::reverse(children.begin(), children.end()); + + return oldShadowNode.clone( + {ShadowNodeFragment::propsPlaceholder(), + std::make_shared(children)}); + }); + + EXPECT_TRUE( + static_cast(*newRootShadowNode).layoutIfNeeded()); }