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; }