Fabric/Text: ShadowNode::clone() - dynamic self-cloning mechanism

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
This commit is contained in:
Valentin Shergin
2018-04-26 17:51:27 -07:00
committed by Facebook Github Bot
parent 2e7dbc82b3
commit bd91eaf664
7 changed files with 106 additions and 15 deletions

View File

@@ -115,3 +115,38 @@ TEST(ShadowNodeTest, handleSourceNode) {
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());
}