diff --git a/packages/react-reconciler/src/__tests__/ReactScope-test.internal.js b/packages/react-reconciler/src/__tests__/ReactScope-test.internal.js
index 67c1a088b7818..edf2fbc09621e 100644
--- a/packages/react-reconciler/src/__tests__/ReactScope-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactScope-test.internal.js
@@ -402,6 +402,59 @@ describe('ReactScope', () => {
expect(node).toEqual(aRef.current);
});
+ it('containsNode() works as intended', () => {
+ const TestScope = React.unstable_createScope((type, props) => true);
+ const scopeRef = React.createRef();
+ const divRef = React.createRef();
+ const spanRef = React.createRef();
+ const aRef = React.createRef();
+ const outerSpan = React.createRef();
+ const emRef = React.createRef();
+
+ function Test({toggle}) {
+ return toggle ? (
+
+
SPAN
+
+ DIV
+ SPAN
+ A
+
+
EM
+
+ ) : (
+
+
+ A
+ DIV
+ SPAN
+ EM
+
+
SPAN
+
+ );
+ }
+
+ const renderer = ReactTestRenderer.create(, {
+ createNodeMock: element => {
+ return element;
+ },
+ });
+ expect(scopeRef.current.containsNode(divRef.current)).toBe(true);
+ expect(scopeRef.current.containsNode(spanRef.current)).toBe(true);
+ expect(scopeRef.current.containsNode(aRef.current)).toBe(true);
+ expect(scopeRef.current.containsNode(outerSpan.current)).toBe(false);
+ expect(scopeRef.current.containsNode(emRef.current)).toBe(false);
+ renderer.update();
+ expect(scopeRef.current.containsNode(divRef.current)).toBe(true);
+ expect(scopeRef.current.containsNode(spanRef.current)).toBe(true);
+ expect(scopeRef.current.containsNode(aRef.current)).toBe(true);
+ expect(scopeRef.current.containsNode(outerSpan.current)).toBe(false);
+ expect(scopeRef.current.containsNode(emRef.current)).toBe(true);
+ renderer.update();
+ expect(scopeRef.current.containsNode(emRef.current)).toBe(false);
+ });
+
it('mixed getParent() and getAllNodes() works as intended', () => {
const TestScope = React.unstable_createScope((type, props) => true);
const TestScope2 = React.unstable_createScope((type, props) => true);
diff --git a/packages/react-test-renderer/src/ReactTestHostConfig.js b/packages/react-test-renderer/src/ReactTestHostConfig.js
index 8cbf8bc64918f..ea56e7616aa1b 100644
--- a/packages/react-test-renderer/src/ReactTestHostConfig.js
+++ b/packages/react-test-renderer/src/ReactTestHostConfig.js
@@ -53,6 +53,8 @@ export * from 'shared/HostConfigWithNoHydration';
const EVENT_COMPONENT_CONTEXT = {};
const NO_CONTEXT = {};
const UPDATE_SIGNAL = {};
+const nodeToInstanceMap = new WeakMap();
+
if (__DEV__) {
Object.freeze(NO_CONTEXT);
Object.freeze(UPDATE_SIGNAL);
@@ -62,10 +64,14 @@ export function getPublicInstance(inst: Instance | TextInstance): * {
switch (inst.tag) {
case 'INSTANCE':
const createNodeMock = inst.rootContainerInstance.createNodeMock;
- return createNodeMock({
+ const mockNode = createNodeMock({
type: inst.type,
props: inst.props,
});
+ if (typeof mockNode === 'object' && mockNode !== null) {
+ nodeToInstanceMap.set(mockNode, inst);
+ }
+ return mockNode;
default:
return inst;
}
@@ -354,6 +360,10 @@ export function unmountFundamentalComponent(
}
}
-export function getInstanceFromNode(node: Object) {
- throw new Error('Not yet implemented.');
+export function getInstanceFromNode(mockNode: Object) {
+ const instance = nodeToInstanceMap.get(mockNode);
+ if (instance !== undefined) {
+ return instance.internalInstanceHandle;
+ }
+ return null;
}