Files
react-native/ReactCommon/fabric/core/tests/LayoutableShadowNodeTest.cpp
T
Samuel Susla 510dbc5ec1 Fix measureLayout when relative node is the same as this node
Summary:
# Changes
1. Fixes a bug when calling `LayoutableShadowNode::getRelativeLayoutMetrics` with `this` being the same node as ancestor.
2. Refactors logic that increments `layoutMetric.frame.origin` by iterating through ancestors.

Changelog: [Internal]

Reviewed By: shergin

Differential Revision: D19468690

fbshipit-source-id: 5b9e187adc26a206da035e4387bb5f528aabdbb2
2020-01-22 05:12:10 -08:00

104 lines
3.6 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <gtest/gtest.h>
#include "TestComponent.h"
using namespace facebook::react;
class LayoutableShadowNodeTest : public ::testing::Test {
protected:
LayoutableShadowNodeTest()
: eventDispatcher_(std::shared_ptr<EventDispatcher const>()),
componentDescriptor_(TestComponentDescriptor({eventDispatcher_})) {
auto familyA = std::make_shared<ShadowNodeFamily>(
ShadowNodeFamilyFragment{
/* .tag = */ 9,
/* .surfaceId = */ 1,
/* .eventEmitter = */ nullptr,
},
componentDescriptor_);
nodeA_ = std::make_shared<TestShadowNode>(
ShadowNodeFragment{
/* .props = */ std::make_shared<const TestProps>(),
/* .children = */ ShadowNode::emptySharedShadowNodeSharedList(),
},
familyA,
ShadowNodeTraits{});
auto familyB = std::make_shared<ShadowNodeFamily>(
ShadowNodeFamilyFragment{
/* .tag = */ 10,
/* .surfaceId = */ 1,
/* .eventEmitter = */ nullptr,
},
componentDescriptor_);
nodeB_ = std::make_shared<TestShadowNode>(
ShadowNodeFragment{
/* .props = */ std::make_shared<const TestProps>(),
/* .children = */ ShadowNode::emptySharedShadowNodeSharedList(),
},
familyB,
ShadowNodeTraits{});
nodeA_->appendChild(nodeB_);
}
std::shared_ptr<EventDispatcher const> eventDispatcher_;
std::shared_ptr<TestShadowNode> nodeA_;
std::shared_ptr<TestShadowNode> nodeB_;
TestComponentDescriptor componentDescriptor_;
};
TEST_F(LayoutableShadowNodeTest, relativeLayoutMetrics) {
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.origin = {10, 20};
layoutMetrics.frame.size = {100, 200};
nodeA_->setLayoutMetrics(layoutMetrics);
nodeB_->setLayoutMetrics(layoutMetrics);
auto relativeLayoutMetrics = nodeB_->getRelativeLayoutMetrics(*nodeA_, {});
// A is a parent to B, A has origin {10, 10}, B has origin {10, 10}.
// B's relative origin to A should be {10, 10}.
// D19447900 has more about the issue.
EXPECT_EQ(relativeLayoutMetrics.frame.origin.x, 10);
EXPECT_EQ(relativeLayoutMetrics.frame.origin.y, 20);
}
TEST_F(LayoutableShadowNodeTest, relativeLayoutMetricsOnSameNode) {
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.origin = {10, 20};
layoutMetrics.frame.size = {100, 200};
nodeA_->setLayoutMetrics(layoutMetrics);
auto relativeLayoutMetrics = nodeA_->getRelativeLayoutMetrics(*nodeA_, {});
EXPECT_EQ(relativeLayoutMetrics.frame.origin.x, 0);
EXPECT_EQ(relativeLayoutMetrics.frame.origin.y, 0);
EXPECT_EQ(relativeLayoutMetrics.frame.size.width, 100);
EXPECT_EQ(relativeLayoutMetrics.frame.size.height, 200);
}
TEST_F(LayoutableShadowNodeTest, relativeLayourMetricsOnClonedNode) {
// B is cloned and mutated.
auto nodeBRevision2 = std::static_pointer_cast<TestShadowNode>(
componentDescriptor_.cloneShadowNode(*nodeB_, ShadowNodeFragment{}));
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.size = {500, 600};
nodeBRevision2->setLayoutMetrics(layoutMetrics);
nodeA_->replaceChild(*nodeB_, nodeBRevision2);
// Even if we ask old ShadowNode for its relative layoutMetrics, it needs to
// return correct, new layoutMetrics. D19433873 has more about the issue.
auto newRelativeLayoutMetrics = nodeB_->getRelativeLayoutMetrics(*nodeA_, {});
EXPECT_EQ(newRelativeLayoutMetrics.frame.size.width, 500);
EXPECT_EQ(newRelativeLayoutMetrics.frame.size.height, 600);
}