[react-interactions] Add getInstanceFromNode support to TestHostRenderer (#17065)
Fix bad WeakMap key case Fix bad WeakMap key case
Dominic Gannaway committed
Oct 11, 2019 at 16:58 UTC
0ac8e563d0bdbbbfe12d718710b3959e78d507dd
2 files changed
+66
-3
packages/react-reconciler/src/__tests__/ReactScope-test.internal.js
+53
@@ -402,6 +402,59 @@ describe('ReactScope', () => {
402
expect(node).toEqual(aRef.current);
403
});
404
405
+ it('containsNode() works as intended', () => {
406
+ const TestScope = React.unstable_createScope((type, props) => true);
407
+ const scopeRef = React.createRef();
408
+ const divRef = React.createRef();
409
+ const spanRef = React.createRef();
410
+ const aRef = React.createRef();
411
+ const outerSpan = React.createRef();
412
+ const emRef = React.createRef();
413
+
414
+ function Test({toggle}) {
415
+ return toggle ? (
416
+ <div>
417
+ <span ref={outerSpan}>SPAN</span>
418
+ <TestScope ref={scopeRef}>
419
+ <div ref={divRef}>DIV</div>
420
+ <span ref={spanRef}>SPAN</span>
421
+ <a ref={aRef}>A</a>
422
+ </TestScope>
423
+ <em ref={emRef}>EM</em>
424
+ </div>
425
+ ) : (
426
+ <div>
427
+ <TestScope ref={scopeRef}>
428
+ <a ref={aRef}>A</a>
429
+ <div ref={divRef}>DIV</div>
430
+ <span ref={spanRef}>SPAN</span>
431
+ <em ref={emRef}>EM</em>
432
+ </TestScope>
433
+ <span ref={outerSpan}>SPAN</span>
434
+ </div>
435
+ );
436
+ }
437
+
438
+ const renderer = ReactTestRenderer.create(<Test toggle={true} />, {
439
+ createNodeMock: element => {
440
+ return element;
441
+ },
442
+ });
443
+ expect(scopeRef.current.containsNode(divRef.current)).toBe(true);
444
+ expect(scopeRef.current.containsNode(spanRef.current)).toBe(true);
445
+ expect(scopeRef.current.containsNode(aRef.current)).toBe(true);
446
+ expect(scopeRef.current.containsNode(outerSpan.current)).toBe(false);
447
+ expect(scopeRef.current.containsNode(emRef.current)).toBe(false);
448
+ renderer.update(<Test toggle={false} />);
449
+ expect(scopeRef.current.containsNode(divRef.current)).toBe(true);
450
+ expect(scopeRef.current.containsNode(spanRef.current)).toBe(true);
451
+ expect(scopeRef.current.containsNode(aRef.current)).toBe(true);
452
+ expect(scopeRef.current.containsNode(outerSpan.current)).toBe(false);
453
+ expect(scopeRef.current.containsNode(emRef.current)).toBe(true);
454
+ renderer.update(<Test toggle={true} />);
455
+ expect(scopeRef.current.containsNode(emRef.current)).toBe(false);
456
+ });
457
+
458
it('mixed getParent() and getAllNodes() works as intended', () => {
459
const TestScope = React.unstable_createScope((type, props) => true);
460
const TestScope2 = React.unstable_createScope((type, props) => true);
packages/react-test-renderer/src/ReactTestHostConfig.js
+13
-3
@@ -53,6 +53,8 @@ export * from 'shared/HostConfigWithNoHydration';
53
const EVENT_COMPONENT_CONTEXT = {};
54
const NO_CONTEXT = {};
55
const UPDATE_SIGNAL = {};
56
+const nodeToInstanceMap = new WeakMap();
57
+
58
if (__DEV__) {
59
Object.freeze(NO_CONTEXT);
60
Object.freeze(UPDATE_SIGNAL);
@@ -62,10 +64,14 @@ export function getPublicInstance(inst: Instance | TextInstance): * {
64
switch (inst.tag) {
65
case 'INSTANCE':
66
const createNodeMock = inst.rootContainerInstance.createNodeMock;
65
- return createNodeMock({
67
+ const mockNode = createNodeMock({
68
type: inst.type,
69
props: inst.props,
70
});
71
+ if (typeof mockNode === 'object' && mockNode !== null) {
72
+ nodeToInstanceMap.set(mockNode, inst);
73
+ }
74
+ return mockNode;
75
default:
76
return inst;
77
}
@@ -354,6 +360,10 @@ export function unmountFundamentalComponent(
360
}
361
}
362
357
-export function getInstanceFromNode(node: Object) {
358
- throw new Error('Not yet implemented.');
363
+export function getInstanceFromNode(mockNode: Object) {
364
+ const instance = nodeToInstanceMap.get(mockNode);
365
+ if (instance !== undefined) {
366
+ return instance.internalInstanceHandle;
367
+ }
368
+ return null;
369
}