/
githubmr
/
facebook-react-native
Обзор
Документация
Войти
/
githubmr
/
facebook-react-native
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-native/ReactCommon/react/renderer/components/view/tests/ViewTest.cpp
232 строки
8 KB
generatedunixname89002005287564
Fix CQS signal modernize-use-designated-initializers in xplat/js/react-native-github/packages (#53962)
26 сен 2025, 20:50
26 сен 2025, 20:50
8bc133c
Код
Авторство
О чём код?
/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include <algorithm> #include <memory> #include <gtest/gtest.h> #include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h> #include <react/renderer/components/root/RootComponentDescriptor.h> #include <react/renderer/components/scrollview/ScrollViewComponentDescriptor.h> #include <react/renderer/components/view/ViewComponentDescriptor.h> #include <react/renderer/core/PropsParserContext.h> #include <react/renderer/element/ComponentBuilder.h> #include <react/renderer/element/Element.h> #include <react/renderer/element/testUtils.h> namespace facebook::react { class YogaDirtyFlagTest : public ::testing::Test { protected: ComponentBuilder builder_; std::shared_ptr<RootShadowNode> rootShadowNode_; std::shared_ptr<ViewShadowNode> innerShadowNode_; std::shared_ptr<ScrollViewShadowNode> scrollViewShadowNode_; YogaDirtyFlagTest() : builder_(simpleComponentBuilder()) { // clang-format off auto element = Element<RootShadowNode>() .reference(rootShadowNode_) .tag(1) .children({ Element<ViewShadowNode>() .tag(2), Element<ViewShadowNode>() .tag(3) .reference(innerShadowNode_) .children({ Element<ViewShadowNode>() .tag(4) .props([] { /* * Some non-default props. */ auto mutableViewProps = std::make_shared<ViewShadowNodeProps>(); auto &props = *mutableViewProps; props.nativeId = "native Id"; props.opacity = 0.5; props.yogaStyle.setAlignContent(yoga::Align::Baseline); props.yogaStyle.setFlexDirection(yoga::FlexDirection::RowReverse); return mutableViewProps; }), Element<ViewShadowNode>() .tag(5), Element<ViewShadowNode>() .tag(6), Element<ScrollViewShadowNode>() .reference(scrollViewShadowNode_) .tag(7) .children({ Element<ViewShadowNode>() .tag(8) }) }) }); // clang-format on 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) { ContextContainer contextContainer{}; PropsParserContext parserContext{-1, contextContainer}; /* * Cloning props without changing them must *not* dirty a Yoga node. */ auto newRootShadowNode = rootShadowNode_->cloneTree( innerShadowNode_->getFamily(), [&](const ShadowNode& oldShadowNode) { auto& componentDescriptor = oldShadowNode.getComponentDescriptor(); auto props = componentDescriptor.cloneProps( parserContext, oldShadowNode.getProps(), RawProps()); return oldShadowNode.clone(ShadowNodeFragment{.props = props}); }); EXPECT_FALSE( static_cast<RootShadowNode&>(*newRootShadowNode).layoutIfNeeded()); } TEST_F(YogaDirtyFlagTest, changingNonLayoutSubPropsMustNotDirtyYogaNode) { /* * Changing *non-layout* sub-props must *not* dirty a Yoga node. */ auto newRootShadowNode = rootShadowNode_->cloneTree( innerShadowNode_->getFamily(), [](const ShadowNode& oldShadowNode) { auto viewProps = std::make_shared<ViewShadowNodeProps>(); auto& props = *viewProps; props.nativeId = "some new native Id"; props.backgroundColor = blackColor(); props.opacity = props.opacity + 0.042; props.zIndex = props.zIndex.value_or(0) + 42; props.shouldRasterize = !props.shouldRasterize; props.collapsable = !props.collapsable; return oldShadowNode.clone(ShadowNodeFragment{.props = viewProps}); }); EXPECT_FALSE( static_cast<RootShadowNode&>(*newRootShadowNode).layoutIfNeeded()); } TEST_F(YogaDirtyFlagTest, changingLayoutSubPropsMustDirtyYogaNode) { /* * Changing *layout* sub-props *must* dirty a Yoga node. */ auto newRootShadowNode = rootShadowNode_->cloneTree( innerShadowNode_->getFamily(), [](const ShadowNode& oldShadowNode) { auto viewProps = std::make_shared<ViewShadowNodeProps>(); auto& props = *viewProps; props.yogaStyle.setAlignContent(yoga::Align::Baseline); props.yogaStyle.setDisplay(yoga::Display::None); return oldShadowNode.clone(ShadowNodeFragment{.props = viewProps}); }); EXPECT_TRUE( static_cast<RootShadowNode&>(*newRootShadowNode).layoutIfNeeded()); } TEST_F(YogaDirtyFlagTest, removingAllChildrenMustDirtyYogaNode) { /* * Removing all children *must* dirty a Yoga node. */ auto newRootShadowNode = rootShadowNode_->cloneTree( innerShadowNode_->getFamily(), [](const ShadowNode& oldShadowNode) { return oldShadowNode.clone( {.props = ShadowNodeFragment::propsPlaceholder(), .children = ShadowNode::emptySharedShadowNodeSharedList()}); }); EXPECT_TRUE( static_cast<RootShadowNode&>(*newRootShadowNode).layoutIfNeeded()); } TEST_F(YogaDirtyFlagTest, removingLastChildMustDirtyYogaNode) { /* * Removing the last child *must* dirty the Yoga node. */ auto newRootShadowNode = rootShadowNode_->cloneTree( innerShadowNode_->getFamily(), [](const ShadowNode& oldShadowNode) { auto children = oldShadowNode.getChildren(); children.pop_back(); std::reverse(children.begin(), children.end()); return oldShadowNode.clone( {.props = ShadowNodeFragment::propsPlaceholder(), .children = std::make_shared< const std::vector<std::shared_ptr<const ShadowNode>>>( children)}); }); EXPECT_TRUE( static_cast<RootShadowNode&>(*newRootShadowNode).layoutIfNeeded()); } TEST_F(YogaDirtyFlagTest, reversingListOfChildrenMustDirtyYogaNode) { /* * Reversing a list of children *must* dirty a Yoga node. */ auto newRootShadowNode = rootShadowNode_->cloneTree( innerShadowNode_->getFamily(), [](const ShadowNode& oldShadowNode) { auto children = oldShadowNode.getChildren(); std::reverse(children.begin(), children.end()); return oldShadowNode.clone( {.props = ShadowNodeFragment::propsPlaceholder(), .children = std::make_shared< const std::vector<std::shared_ptr<const ShadowNode>>>( children)}); }); EXPECT_TRUE( static_cast<RootShadowNode&>(*newRootShadowNode).layoutIfNeeded()); } TEST_F(YogaDirtyFlagTest, updatingStateForScrollViewMistNotDirtyYogaNode) { /* * Updating a state for *some* (not all!) components must *not* dirty Yoga * nodes. */ auto newRootShadowNode = rootShadowNode_->cloneTree( scrollViewShadowNode_->getFamily(), [](const ShadowNode& oldShadowNode) { auto state = ScrollViewState{}; state.contentOffset = Point{.x = 42, .y = 9000}; auto& componentDescriptor = oldShadowNode.getComponentDescriptor(); auto newState = componentDescriptor.createState( oldShadowNode.getFamily(), std::make_shared<ScrollViewState>(state)); return oldShadowNode.clone( {.props = ShadowNodeFragment::propsPlaceholder(), .children = ShadowNodeFragment::childrenPlaceholder(), .state = newState}); }); EXPECT_FALSE( static_cast<RootShadowNode&>(*newRootShadowNode).layoutIfNeeded()); } } // namespace facebook::react