mirror of
https://github.com/status-im/react-native.git
synced 2025-01-09 17:15:54 +00:00
bd91eaf664
Summary: The previous approach simply didn't work. :( As you might notice, in previous implementation of ViewShadowNode::cloneAndReplaceChild we used `ViewShadowNode` class for cloning `childNode`, and this is incorrect becasue `childNode` might be instance of any class. Reviewed By: fkgozali Differential Revision: D7595016 fbshipit-source-id: 2215414926f2f7a2e2fd05ca2d065f10d6d32b74
153 lines
5.2 KiB
C++
153 lines
5.2 KiB
C++
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#include <memory>
|
|
|
|
#include <fabric/core/ConcreteShadowNode.h>
|
|
#include <fabric/core/ShadowNode.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "TestComponent.h"
|
|
|
|
using namespace facebook::react;
|
|
|
|
TEST(ShadowNodeTest, handleProps) {
|
|
RawProps raw;
|
|
raw["nativeID"] = "abc";
|
|
|
|
auto props = std::make_shared<Props>();
|
|
props->apply(raw);
|
|
|
|
// Props are not sealed after applying raw props.
|
|
ASSERT_FALSE(props->getSealed());
|
|
|
|
ASSERT_STREQ(props->getNativeId().c_str(), "abc");
|
|
}
|
|
|
|
TEST(ShadowNodeTest, handleShadowNodeCreation) {
|
|
auto node = std::make_shared<TestShadowNode>(9, 1, (void *)NULL);
|
|
|
|
ASSERT_FALSE(node->getSealed());
|
|
ASSERT_STREQ(node->getComponentName().c_str(), "Test");
|
|
ASSERT_EQ(node->getTag(), 9);
|
|
ASSERT_EQ(node->getRootTag(), 1);
|
|
ASSERT_EQ(node->getInstanceHandle(), (void *)NULL);
|
|
TestShadowNode *nodePtr = node.get();
|
|
ASSERT_EQ(node->getComponentHandle(), typeid(*nodePtr).hash_code());
|
|
ASSERT_EQ(node->getSourceNode(), nullptr);
|
|
ASSERT_EQ(node->getChildren()->size(), 0);
|
|
|
|
ASSERT_STREQ(node->getProps()->getNativeId().c_str(), "testNativeID");
|
|
|
|
node->sealRecursive();
|
|
ASSERT_TRUE(node->getSealed());
|
|
ASSERT_TRUE(node->getProps()->getSealed());
|
|
}
|
|
|
|
TEST(ShadowNodeTest, handleShadowNodeSimpleCloning) {
|
|
auto node = std::make_shared<TestShadowNode>(9, 1, (void *)NULL);
|
|
auto node2 = std::make_shared<TestShadowNode>(node);
|
|
|
|
ASSERT_STREQ(node->getComponentName().c_str(), "Test");
|
|
ASSERT_EQ(node->getTag(), 9);
|
|
ASSERT_EQ(node->getRootTag(), 1);
|
|
ASSERT_EQ(node->getInstanceHandle(), (void *)NULL);
|
|
ASSERT_EQ(node2->getSourceNode(), node);
|
|
}
|
|
|
|
TEST(ShadowNodeTest, handleShadowNodeMutation) {
|
|
auto node1 = std::make_shared<TestShadowNode>(1, 1, (void *)NULL);
|
|
auto node2 = std::make_shared<TestShadowNode>(2, 1, (void *)NULL);
|
|
auto node3 = std::make_shared<TestShadowNode>(3, 1, (void *)NULL);
|
|
|
|
node1->appendChild(node2);
|
|
node1->appendChild(node3);
|
|
SharedShadowNodeSharedList node1Children = node1->getChildren();
|
|
ASSERT_EQ(node1Children->size(), 2);
|
|
ASSERT_EQ(node1Children->at(0), node2);
|
|
ASSERT_EQ(node1Children->at(1), node3);
|
|
|
|
auto node4 = std::make_shared<TestShadowNode>(node2);
|
|
node1->replaceChild(node2, node4);
|
|
node1Children = node1->getChildren();
|
|
ASSERT_EQ(node1Children->size(), 2);
|
|
ASSERT_EQ(node1Children->at(0), node4);
|
|
ASSERT_EQ(node1Children->at(1), node3);
|
|
|
|
// Seal the entire tree.
|
|
node1->sealRecursive();
|
|
ASSERT_TRUE(node1->getSealed());
|
|
ASSERT_TRUE(node3->getSealed());
|
|
ASSERT_TRUE(node4->getSealed());
|
|
|
|
// No more mutation after sealing.
|
|
EXPECT_THROW(node4->clearSourceNode(), std::runtime_error);
|
|
|
|
auto node5 = std::make_shared<TestShadowNode>(node4);
|
|
node5->clearSourceNode();
|
|
ASSERT_EQ(node5->getSourceNode(), nullptr);
|
|
}
|
|
|
|
TEST(ShadowNodeTest, handleSourceNode) {
|
|
auto nodeFirstGeneration = std::make_shared<TestShadowNode>(9, 1, (void *)NULL);
|
|
auto nodeSecondGeneration = std::make_shared<TestShadowNode>(nodeFirstGeneration);
|
|
auto nodeThirdGeneration = std::make_shared<TestShadowNode>(nodeSecondGeneration);
|
|
auto nodeForthGeneration = std::make_shared<TestShadowNode>(nodeThirdGeneration);
|
|
|
|
// Ensure established shource nodes structure.
|
|
ASSERT_EQ(nodeForthGeneration->getSourceNode(), nodeThirdGeneration);
|
|
ASSERT_EQ(nodeThirdGeneration->getSourceNode(), nodeSecondGeneration);
|
|
ASSERT_EQ(nodeSecondGeneration->getSourceNode(), nodeFirstGeneration);
|
|
|
|
// Shallow source node for the forth generation node.
|
|
nodeForthGeneration->shallowSourceNode();
|
|
ASSERT_EQ(nodeForthGeneration->getSourceNode(), nodeSecondGeneration);
|
|
|
|
// Shallow it one more time.
|
|
nodeForthGeneration->shallowSourceNode();
|
|
ASSERT_EQ(nodeForthGeneration->getSourceNode(), nodeFirstGeneration);
|
|
|
|
// Ensure that 3th and 2nd were not affected.
|
|
ASSERT_EQ(nodeThirdGeneration->getSourceNode(), nodeSecondGeneration);
|
|
ASSERT_EQ(nodeSecondGeneration->getSourceNode(), nodeFirstGeneration);
|
|
}
|
|
|
|
TEST(ShadowNodeTest, handleCloneFunction) {
|
|
auto firstNode = std::make_shared<TestShadowNode>(9, 1, (void *)NULL);
|
|
|
|
// The shadow node is not clonable if `cloneFunction` is not provided,
|
|
ASSERT_DEATH_IF_SUPPORTED(firstNode->clone(), "cloneFunction_");
|
|
|
|
auto secondNode = std::make_shared<TestShadowNode>(
|
|
9,
|
|
1,
|
|
(void *)NULL,
|
|
std::make_shared<const TestProps>(),
|
|
ShadowNode::emptySharedShadowNodeSharedList(),
|
|
[](const SharedShadowNode &shadowNode, const SharedProps &props, const SharedShadowNodeSharedList &children) {
|
|
return std::make_shared<const TestShadowNode>(
|
|
std::static_pointer_cast<const TestShadowNode>(shadowNode),
|
|
props,
|
|
children
|
|
);
|
|
}
|
|
);
|
|
|
|
auto secondNodeClone = secondNode->clone();
|
|
|
|
// Those two nodes are *not* same.
|
|
ASSERT_NE(secondNode, secondNodeClone);
|
|
|
|
// `secondNodeClone` is an instance of `TestShadowNode`.
|
|
ASSERT_NE(std::dynamic_pointer_cast<const TestShadowNode>(secondNodeClone), nullptr);
|
|
|
|
// Both nodes have same content.
|
|
ASSERT_EQ(secondNode->getTag(), secondNodeClone->getTag());
|
|
ASSERT_EQ(secondNode->getRootTag(), secondNodeClone->getRootTag());
|
|
ASSERT_EQ(secondNode->getProps(), secondNodeClone->getProps());
|
|
}
|