From 23fbd312aa80233d4062de28cb950c91786fb3f1 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Wed, 30 May 2018 21:49:15 -0700 Subject: [PATCH] Include instanceHandle in cloning mechanism Reviewed By: shergin, achen1 Differential Revision: D8072075 fbshipit-source-id: 2fcfdfa5116850ce0bac6c2c86d87e5bf00fd7f0 --- .../react/fabric/FabricReconciler.java | 15 +++--- .../react/fabric/FabricUIManager.java | 25 +++++----- .../uimanager/NativeViewHierarchyManager.java | 8 ++-- .../react/uimanager/ReactShadowNode.java | 12 +++-- .../react/uimanager/ReactShadowNodeImpl.java | 29 ++++++++--- .../progressbar/ProgressBarShadowNode.java | 8 ++-- .../views/slider/ReactSliderManager.java | 8 ++-- .../views/switchview/ReactSwitchManager.java | 8 ++-- .../react/views/text/ReactTextShadowNode.java | 8 ++-- .../textinput/ReactTextInputShadowNode.java | 8 ++-- .../react/bridge/InstanceHandleHelper.java | 20 ++++++++ .../react/fabric/FabricUIManagerTest.java | 48 ++++++++++++------- .../react/fabric/ReactShadowNodeTest.java | 2 +- 13 files changed, 126 insertions(+), 73 deletions(-) create mode 100644 ReactAndroid/src/test/java/com/facebook/react/bridge/InstanceHandleHelper.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java index 5f61d943f..c42de9efe 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java @@ -120,17 +120,20 @@ public class FabricReconciler { int reactTag = node.getReactTag(); if (DEBUG) { Log.d( - TAG, - "manageChildren.enqueueUpdateProperties " + - "\n\ttag: " + reactTag + - "\n\tviewClass: " + node.getViewClass() + - "\n\tnewProps: " + node.getNewProps()); + TAG, + "manageChildren.enqueueUpdateProperties " + + "\n\ttag: " + reactTag + + "\n\tviewClass: " + node.getViewClass() + + "\n\tinstanceHandle: " + node.getInstanceHandle() + + "\n\tnewProps: " + node.getNewProps()); } if (node.getNewProps() != null) { uiViewOperationQueue.enqueueUpdateProperties( reactTag, node.getViewClass(), node.getNewProps()); } - } + uiViewOperationQueue.enqueueUpdateInstanceHandle( + reactTag, node.getInstanceHandle()); + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 7021c7831..6b7bfff47 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -98,6 +98,7 @@ public class FabricUIManager implements UIManager, JSHandler { ReactShadowNode rootNode = getRootNode(rootTag); node.setRootTag(rootNode.getReactTag()); node.setViewClassName(viewName); + node.setInstanceHandle(instanceHandle); node.setReactTag(reactTag); node.setThemedContext(rootNode.getThemedContext()); @@ -139,8 +140,7 @@ public class FabricUIManager implements UIManager, JSHandler { Log.d(TAG, "cloneNode \n\tnode: " + node); } try { - // TODO: Pass new instanceHandle - ReactShadowNode clone = node.mutableCopy(); + ReactShadowNode clone = node.mutableCopy(instanceHandle); assertReactShadowNodeCopy(node, clone); return clone; } catch (Throwable t) { @@ -160,8 +160,7 @@ public class FabricUIManager implements UIManager, JSHandler { Log.d(TAG, "cloneNodeWithNewChildren \n\tnode: " + node); } try { - // TODO: Pass new instanceHandle - ReactShadowNode clone = node.mutableCopyWithNewChildren(); + ReactShadowNode clone = node.mutableCopyWithNewChildren(instanceHandle); assertReactShadowNodeCopy(node, clone); return clone; } catch (Throwable t) { @@ -182,9 +181,8 @@ public class FabricUIManager implements UIManager, JSHandler { Log.d(TAG, "cloneNodeWithNewProps \n\tnode: " + node + "\n\tprops: " + newProps); } try { - // TODO: Pass new instanceHandle - ReactShadowNode clone = - node.mutableCopyWithNewProps(newProps == null ? null : new ReactStylesDiffMap(newProps)); + ReactShadowNode clone = node.mutableCopyWithNewProps(instanceHandle, + newProps == null ? null : new ReactStylesDiffMap(newProps)); assertReactShadowNodeCopy(node, clone); return clone; } catch (Throwable t) { @@ -206,9 +204,8 @@ public class FabricUIManager implements UIManager, JSHandler { Log.d(TAG, "cloneNodeWithNewChildrenAndProps \n\tnode: " + node + "\n\tnewProps: " + newProps); } try { - // TODO: Pass new instanceHandle ReactShadowNode clone = - node.mutableCopyWithNewChildrenAndProps( + node.mutableCopyWithNewChildrenAndProps(instanceHandle, newProps == null ? null : new ReactStylesDiffMap(newProps)); assertReactShadowNodeCopy(node, clone); return clone; @@ -244,7 +241,7 @@ public class FabricUIManager implements UIManager, JSHandler { // then we add a mutation of it. In the future this will be performed by FabricJS / Fiber. //TODO: T27926878 avoid cloning shared child if (child.getParent() != null) { - child = child.mutableCopy(); + child = child.mutableCopy(child.getInstanceHandle()); } parent.addChildAt(child, parent.getChildCount()); } catch (Throwable t) { @@ -315,7 +312,7 @@ public class FabricUIManager implements UIManager, JSHandler { private ReactShadowNode calculateDiffingAndCreateNewRootNode( ReactShadowNode currentRootShadowNode, List newChildList) { - ReactShadowNode newRootShadowNode = currentRootShadowNode.mutableCopyWithNewChildren(); + ReactShadowNode newRootShadowNode = currentRootShadowNode.mutableCopyWithNewChildren(currentRootShadowNode.getInstanceHandle()); for (ReactShadowNode child : newChildList) { appendChild(newRootShadowNode, child); } @@ -489,10 +486,10 @@ public class FabricUIManager implements UIManager, JSHandler { // -> call to C++ } - public long createEventTarget(int targetTag) throws IllegalStateException { - long instanceHandle = mNativeViewHierarchyManager.getInstanceHandle(targetTag); + public long createEventTarget(int reactTag) throws IllegalStateException { + long instanceHandle = mNativeViewHierarchyManager.getInstanceHandle(reactTag); if (instanceHandle == 0) { - throw new IllegalStateException("View with targetTag " + targetTag + " does not exist."); + throw new IllegalStateException("View with reactTag " + reactTag + " does not exist."); } // TODO: uncomment after diff including Binding is landed diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index 7a59df26f..d5a204719 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -221,16 +221,16 @@ public class NativeViewHierarchyManager { @Nullable @TargetApi(Build.VERSION_CODES.DONUT) - public long getInstanceHandle(int targetTag) { + public long getInstanceHandle(int reactTag) { UiThreadUtil.assertOnUiThread(); - View view = mTagsToViews.get(targetTag); + View view = mTagsToViews.get(reactTag); if (view == null) { - throw new IllegalArgumentException("Unable to find view for tag: " + targetTag); + throw new IllegalArgumentException("Unable to find view for tag: " + reactTag); } Long tag = (Long) view.getTag(R.id.view_tag_instance_handle); if (tag == null) { - throw new IllegalArgumentException("Unable to find instanceHandle for tag: " + targetTag); + throw new IllegalArgumentException("Unable to find instanceHandle for tag: " + reactTag); } return tag; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java index 7790a49dd..ed134e216 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java @@ -71,13 +71,13 @@ public interface ReactShadowNode { /** * @return a mutable copy of the {@link ReactShadowNode} */ - T mutableCopy(); + T mutableCopy(long instanceHandle); - T mutableCopyWithNewProps(@Nullable ReactStylesDiffMap newProps); + T mutableCopyWithNewProps(long instanceHandle, @Nullable ReactStylesDiffMap newProps); - T mutableCopyWithNewChildren(); + T mutableCopyWithNewChildren(long instanceHandle); - T mutableCopyWithNewChildrenAndProps(@Nullable ReactStylesDiffMap newProps); + T mutableCopyWithNewChildrenAndProps(long instanceHandle, @Nullable ReactStylesDiffMap newProps); String getViewClass(); @@ -373,4 +373,8 @@ public interface ReactShadowNode { @Nullable ReactShadowNode getOriginalReactShadowNode(); void setOriginalReactShadowNode(@Nullable ReactShadowNode node); + + long getInstanceHandle(); + + void setInstanceHandle(long instanceHandle); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java index 27a70d167..3b3929646 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java @@ -81,7 +81,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode + parentReactShadowNode + " index: " + childIndex); } - ReactShadowNodeImpl newNode = oldReactShadowNode.mutableCopy(); + ReactShadowNodeImpl newNode = oldReactShadowNode.mutableCopy(oldReactShadowNode.getInstanceHandle()); parentReactShadowNode.replaceChild(newNode, childIndex); return newNode.mYogaNode; } @@ -114,6 +114,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode private ReactShadowNode mOriginalReactShadowNode = null; private @Nullable ReactStylesDiffMap mNewProps; + private long mInstanceHandle; public ReactShadowNodeImpl() { mDefaultPadding = new Spacing(0); @@ -166,11 +167,12 @@ public class ReactShadowNodeImpl implements ReactShadowNode } @Override - public ReactShadowNodeImpl mutableCopy() { + public ReactShadowNodeImpl mutableCopy(long instanceHandle) { ReactShadowNodeImpl copy = copy(); Assertions.assertCondition( getClass() == copy.getClass(), "Copied shadow node must use the same class"); + copy.mInstanceHandle = instanceHandle; if (mYogaNode != null) { copy.mYogaNode = mYogaNode.clone(); copy.mYogaNode.setData(copy); @@ -185,8 +187,9 @@ public class ReactShadowNodeImpl implements ReactShadowNode } @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren() { + public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { ReactShadowNodeImpl copy = copy(); + copy.mInstanceHandle = instanceHandle; Assertions.assertCondition( getClass() == copy.getClass(), "Copied shadow node must use the same class"); @@ -204,8 +207,9 @@ public class ReactShadowNodeImpl implements ReactShadowNode } @Override - public ReactShadowNodeImpl mutableCopyWithNewProps(@Nullable ReactStylesDiffMap newProps) { - ReactShadowNodeImpl copy = mutableCopy(); + public ReactShadowNodeImpl mutableCopyWithNewProps(long instanceHandle, + @Nullable ReactStylesDiffMap newProps) { + ReactShadowNodeImpl copy = mutableCopy(instanceHandle); if (newProps != null) { copy.updateProperties(newProps); copy.mNewProps = newProps; @@ -214,8 +218,9 @@ public class ReactShadowNodeImpl implements ReactShadowNode } @Override - public ReactShadowNodeImpl mutableCopyWithNewChildrenAndProps(@Nullable ReactStylesDiffMap newProps) { - ReactShadowNodeImpl copy = mutableCopyWithNewChildren(); + public ReactShadowNodeImpl mutableCopyWithNewChildrenAndProps(long instanceHandle, + @Nullable ReactStylesDiffMap newProps) { + ReactShadowNodeImpl copy = mutableCopyWithNewChildren(instanceHandle); if (newProps != null) { copy.updateProperties(newProps); copy.mNewProps = newProps; @@ -1107,4 +1112,14 @@ public class ReactShadowNodeImpl implements ReactShadowNode public void setOriginalReactShadowNode(ReactShadowNode node) { mOriginalReactShadowNode = node; } + + @Override + public long getInstanceHandle() { + return mInstanceHandle; + } + + @Override + public void setInstanceHandle(long instanceHandle) { + mInstanceHandle = instanceHandle; + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java index 779d647f6..d18466e58 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java @@ -53,8 +53,8 @@ public class ProgressBarShadowNode extends LayoutShadowNode implements YogaMeasu } @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren() { - ProgressBarShadowNode node = (ProgressBarShadowNode) super.mutableCopyWithNewChildren(); + public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { + ProgressBarShadowNode node = (ProgressBarShadowNode) super.mutableCopyWithNewChildren(instanceHandle); node.initMeasureFunction(); return node; } @@ -64,8 +64,8 @@ public class ProgressBarShadowNode extends LayoutShadowNode implements YogaMeasu } @Override - public ReactShadowNodeImpl mutableCopy() { - ProgressBarShadowNode node = (ProgressBarShadowNode) super.mutableCopy(); + public ReactShadowNodeImpl mutableCopy(long instanceHandle) { + ProgressBarShadowNode node = (ProgressBarShadowNode) super.mutableCopy(instanceHandle); node.initMeasureFunction(); return node; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java index dd8008d5b..43aca591b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java @@ -62,15 +62,15 @@ public class ReactSliderManager extends SimpleViewManager { } @Override - public ReactShadowNodeImpl mutableCopy() { - ReactSliderShadowNode reactShadowNode = (ReactSliderShadowNode) super.mutableCopy(); + public ReactShadowNodeImpl mutableCopy(long instanceHandle) { + ReactSliderShadowNode reactShadowNode = (ReactSliderShadowNode) super.mutableCopy(instanceHandle); reactShadowNode.initMeasureFunction(); return reactShadowNode; } @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren() { - ReactSliderShadowNode reactShadowNode = (ReactSliderShadowNode) super.mutableCopyWithNewChildren(); + public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { + ReactSliderShadowNode reactShadowNode = (ReactSliderShadowNode) super.mutableCopyWithNewChildren(instanceHandle); reactShadowNode.initMeasureFunction(); return reactShadowNode; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java index a1a576b37..f6a7f2d8e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java @@ -55,15 +55,15 @@ public class ReactSwitchManager extends SimpleViewManager { } @Override - public ReactShadowNodeImpl mutableCopy() { - ReactSwitchShadowNode reactShadowNode = (ReactSwitchShadowNode) super.mutableCopy(); + public ReactShadowNodeImpl mutableCopy(long instanceHandle) { + ReactSwitchShadowNode reactShadowNode = (ReactSwitchShadowNode) super.mutableCopy(instanceHandle); reactShadowNode.initMeasureFunction(); return reactShadowNode; } @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren() { - ReactSwitchShadowNode reactShadowNode = (ReactSwitchShadowNode) super.mutableCopyWithNewChildren(); + public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { + ReactSwitchShadowNode reactShadowNode = (ReactSwitchShadowNode) super.mutableCopyWithNewChildren(instanceHandle); reactShadowNode.initMeasureFunction(); return reactShadowNode; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java index 1cec7c690..1f4f52fd7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java @@ -159,15 +159,15 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode { } @Override - public ReactShadowNodeImpl mutableCopy() { - ReactTextShadowNode copy = (ReactTextShadowNode) super.mutableCopy(); + public ReactShadowNodeImpl mutableCopy(long instanceHandle) { + ReactTextShadowNode copy = (ReactTextShadowNode) super.mutableCopy(instanceHandle); copy.initMeasureFunction(); return copy; } @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren() { - ReactTextShadowNode copy = (ReactTextShadowNode) super.mutableCopyWithNewChildren(); + public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { + ReactTextShadowNode copy = (ReactTextShadowNode) super.mutableCopyWithNewChildren(instanceHandle); copy.initMeasureFunction(); return copy; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java index e121f2b5f..28c559afb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java @@ -65,8 +65,8 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode } @Override - public ReactTextInputShadowNode mutableCopy() { - ReactTextInputShadowNode node = (ReactTextInputShadowNode) super.mutableCopy(); + public ReactTextInputShadowNode mutableCopy(long instanceHandle) { + ReactTextInputShadowNode node = (ReactTextInputShadowNode) super.mutableCopy(instanceHandle); node.initMeasureFunction(); ThemedReactContext themedContext = getThemedContext(); if (themedContext != null) { @@ -80,8 +80,8 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode } @Override - public ReactTextInputShadowNode mutableCopyWithNewChildren() { - ReactTextInputShadowNode node = (ReactTextInputShadowNode) super.mutableCopyWithNewChildren(); + public ReactTextInputShadowNode mutableCopyWithNewChildren(long instanceHandle) { + ReactTextInputShadowNode node = (ReactTextInputShadowNode) super.mutableCopyWithNewChildren(instanceHandle); node.initMeasureFunction(); ThemedReactContext themedContext = getThemedContext(); if (themedContext != null) { diff --git a/ReactAndroid/src/test/java/com/facebook/react/bridge/InstanceHandleHelper.java b/ReactAndroid/src/test/java/com/facebook/react/bridge/InstanceHandleHelper.java new file mode 100644 index 000000000..bb47fd0da --- /dev/null +++ b/ReactAndroid/src/test/java/com/facebook/react/bridge/InstanceHandleHelper.java @@ -0,0 +1,20 @@ +/** + * 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. + */ + +package com.facebook.react.bridge; + + +import java.util.Random; + +public class InstanceHandleHelper { + + private static final Random random = new Random(); + + public static long randomInstanceHandle() { + return random.nextLong(); + } +} diff --git a/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricUIManagerTest.java b/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricUIManagerTest.java index 69f029361..1b651817e 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricUIManagerTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricUIManagerTest.java @@ -2,6 +2,7 @@ package com.facebook.react.fabric; import static org.fest.assertions.api.Assertions.assertThat; +import static com.facebook.react.bridge.InstanceHandleHelper.randomInstanceHandle; import com.facebook.react.ReactRootView; import com.facebook.react.bridge.ReactApplicationContext; @@ -28,6 +29,7 @@ import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; + /** Tests {@link FabricUIManager} */ @RunWith(RobolectricTestRunner.class) public class FabricUIManagerTest { @@ -35,7 +37,6 @@ public class FabricUIManagerTest { private FabricUIManager mFabricUIManager; private ThemedReactContext mThemedReactContext; private int mNextReactTag; - private int mNextInstanceHandle; @Before public void setUp() throws Exception { @@ -58,10 +59,9 @@ public class FabricUIManagerTest { new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); int rootTag = mFabricUIManager.addRootView(rootView); int reactTag = mNextReactTag++; - int instanceHandle = mNextInstanceHandle++; String viewClass = ReactViewManager.REACT_CLASS; ReactShadowNode node = - mFabricUIManager.createNode(reactTag, viewClass, rootTag, null, instanceHandle); + mFabricUIManager.createNode(reactTag, viewClass, rootTag, null, randomInstanceHandle()); assertThat(reactTag).isEqualTo(node.getReactTag()); assertThat(viewClass).isEqualTo(node.getViewClass()); @@ -79,10 +79,9 @@ public class FabricUIManagerTest { new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); int rootTag = mFabricUIManager.addRootView(rootView); int reactTag = mNextReactTag++; - int instanceHandle = mNextInstanceHandle++; String viewClass = ReactViewManager.REACT_CLASS; ReactShadowNode node = - mFabricUIManager.createNode(reactTag, viewClass, rootTag, null, instanceHandle); + mFabricUIManager.createNode(reactTag, viewClass, rootTag, null, randomInstanceHandle()); List childSet = mFabricUIManager.createChildSet(rootTag); mFabricUIManager.appendChildToSet(childSet, node); @@ -106,6 +105,21 @@ public class FabricUIManagerTest { assertThat(clonedNode.getChildAt(0)).isEqualTo(child); } + + @Test + public void testCloneWithInstanceHandle() { + ReactShadowNode node = createViewNode(); + + long oldInstanceHandle = node.getInstanceHandle(); + long newInstanceHandle = oldInstanceHandle + 1; + ReactShadowNode clonedNode = mFabricUIManager.cloneNode(node, newInstanceHandle); + + assertThat(clonedNode).isNotSameAs(node); + assertThat(clonedNode.getInstanceHandle()).isSameAs(newInstanceHandle); + assertThat(node.getInstanceHandle()).isSameAs(oldInstanceHandle); + } + + @Test public void testDefaultSpacingCloning() { ReactShadowNode node = createViewNode(); @@ -124,7 +138,7 @@ public class FabricUIManagerTest { node.setText("test"); assertThat(node.isVirtual()).isTrue(); - ReactRawTextShadowNode clonedNode = (ReactRawTextShadowNode) node.mutableCopy(); + ReactRawTextShadowNode clonedNode = (ReactRawTextShadowNode) node.mutableCopy(randomInstanceHandle()); assertThat(clonedNode.getText()).isEqualTo("test"); assertThat(clonedNode).isNotEqualTo(node); @@ -134,7 +148,7 @@ public class FabricUIManagerTest { public void testLayoutProgressBarAfterClonning() { ProgressBarShadowNode node = new ProgressBarShadowNode(); node.setThemedContext(mThemedReactContext); - ProgressBarShadowNode clone = (ProgressBarShadowNode) node.mutableCopy(); + ProgressBarShadowNode clone = (ProgressBarShadowNode) node.mutableCopy(randomInstanceHandle()); clone.calculateLayout(); } @@ -144,7 +158,7 @@ public class FabricUIManagerTest { ReactShadowNode child = createViewNode(); node.addChildAt(child, 0); - ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewChildren(node, 0); + ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewChildren(node, randomInstanceHandle()); assertThat(clonedNode.getChildCount()).isZero(); assertSameFields(clonedNode, node); @@ -155,7 +169,7 @@ public class FabricUIManagerTest { ReactShadowNode node = createViewNode(); ReadableNativeMap props = null; // TODO(ayc): Figure out how to create a Native map from tests. - ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewProps(node, props, 0); + ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewProps(node, props, randomInstanceHandle()); } @Test @@ -163,7 +177,7 @@ public class FabricUIManagerTest { ReactShadowNode node = createViewNode(); ReadableNativeMap props = null; - ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewChildrenAndProps(node, props, 0); + ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewChildrenAndProps(node, props, randomInstanceHandle()); assertThat(clonedNode.getChildCount()).isZero(); } @@ -221,10 +235,10 @@ public class FabricUIManagerTest { new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); int rootTag = mFabricUIManager.addRootView(rootView); ReactShadowNode text = - mFabricUIManager.createNode(0, ReactTextViewManager.REACT_CLASS, rootTag, null, mNextInstanceHandle++); + mFabricUIManager.createNode(0, ReactTextViewManager.REACT_CLASS, rootTag, null, randomInstanceHandle()); assertThat(text.isMeasureDefined()).isTrue(); - ReactShadowNode textCopy = text.mutableCopy(); + ReactShadowNode textCopy = text.mutableCopy(randomInstanceHandle()); assertThat(textCopy.isMeasureDefined()).isTrue(); textCopy.setStyleWidth(200); @@ -247,13 +261,13 @@ public class FabricUIManagerTest { int rootTag = mFabricUIManager.addRootView(rootView); String viewClass = ReactViewManager.REACT_CLASS; - ReactShadowNode aa = mFabricUIManager.createNode(2, viewClass, rootTag, null, mNextInstanceHandle++); - ReactShadowNode a = mFabricUIManager.createNode(3, viewClass, rootTag, null, mNextInstanceHandle++); + ReactShadowNode aa = mFabricUIManager.createNode(2, viewClass, rootTag, null, randomInstanceHandle()); + ReactShadowNode a = mFabricUIManager.createNode(3, viewClass, rootTag, null, randomInstanceHandle()); mFabricUIManager.appendChild(a, aa); - ReactShadowNode bb = mFabricUIManager.createNode(4, viewClass, rootTag, null, mNextInstanceHandle++); - ReactShadowNode b = mFabricUIManager.createNode(5, viewClass, rootTag, null, mNextInstanceHandle++); + ReactShadowNode bb = mFabricUIManager.createNode(4, viewClass, rootTag, null, randomInstanceHandle()); + ReactShadowNode b = mFabricUIManager.createNode(5, viewClass, rootTag, null, randomInstanceHandle()); mFabricUIManager.appendChild(b, bb); - ReactShadowNode container = mFabricUIManager.createNode(6, viewClass, rootTag, null, mNextInstanceHandle++); + ReactShadowNode container = mFabricUIManager.createNode(6, viewClass, rootTag, null, randomInstanceHandle()); mFabricUIManager.appendChild(container, a); mFabricUIManager.appendChild(container, b); List childSet = mFabricUIManager.createChildSet(rootTag); diff --git a/ReactAndroid/src/test/java/com/facebook/react/fabric/ReactShadowNodeTest.java b/ReactAndroid/src/test/java/com/facebook/react/fabric/ReactShadowNodeTest.java index 12f4ddb58..7148da735 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/fabric/ReactShadowNodeTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/fabric/ReactShadowNodeTest.java @@ -13,7 +13,7 @@ public class ReactShadowNodeTest { @Test(expected = AssertionError.class) public void testClonedInstance() { TestReactShadowNode node = new TestReactShadowNode(); - node.mutableCopy(); + node.mutableCopy(node.getInstanceHandle()); } private static class TestReactShadowNode extends ReactShadowNodeImpl {}