Skip to content

Commit 7836e57

Browse files
committed
[enzyme-adapter-react-*, enzyme-adapter-utils] [fix] mount: ensure the root’s ref prop gets attached to the actual root
Fixes #2253.
1 parent e47f73e commit 7836e57

File tree

9 files changed

+50
-13
lines changed

9 files changed

+50
-13
lines changed

packages/enzyme-adapter-react-14/src/ReactFourteenAdapter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class ReactFourteenAdapter extends EnzymeAdapter {
110110
wrappingComponentProps: options.wrappingComponentProps,
111111
props,
112112
context,
113-
...(ref && { ref }),
113+
...(ref && { refProp: ref }),
114114
};
115115
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
116116
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);

packages/enzyme-adapter-react-15.4/src/ReactFifteenFourAdapter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class ReactFifteenFourAdapter extends EnzymeAdapter {
145145
wrappingComponentProps: options.wrappingComponentProps,
146146
props,
147147
context,
148-
...(ref && { ref }),
148+
...(ref && { refProp: ref }),
149149
};
150150
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
151151
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);

packages/enzyme-adapter-react-15/src/ReactFifteenAdapter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class ReactFifteenAdapter extends EnzymeAdapter {
145145
wrappingComponentProps: options.wrappingComponentProps,
146146
props,
147147
context,
148-
...(ref && { ref }),
148+
...(ref && { refProp: ref }),
149149
};
150150
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
151151
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);

packages/enzyme-adapter-react-16.1/src/ReactSixteenOneAdapter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class ReactSixteenOneAdapter extends EnzymeAdapter {
278278
props,
279279
wrappingComponentProps,
280280
context,
281-
...(ref && { ref }),
281+
...(ref && { refProp: ref }),
282282
};
283283
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
284284
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);

packages/enzyme-adapter-react-16.2/src/ReactSixteenTwoAdapter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter {
280280
props,
281281
wrappingComponentProps,
282282
context,
283-
...(ref && { ref }),
283+
...(ref && { refProp: ref }),
284284
};
285285
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
286286
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);

packages/enzyme-adapter-react-16.3/src/ReactSixteenThreeAdapter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter {
299299
props,
300300
wrappingComponentProps,
301301
context,
302-
...(ref && { ref }),
302+
...(ref && { refProp: ref }),
303303
};
304304
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
305305
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);

packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ class ReactSixteenAdapter extends EnzymeAdapter {
421421
props,
422422
wrappingComponentProps,
423423
context,
424-
...(ref && { ref }),
424+
...(ref && { refProp: ref }),
425425
};
426426
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
427427
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);

packages/enzyme-adapter-utils/src/createMountWrapper.jsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
import { ref } from 'airbnb-prop-types';
34
import RootFinder from './RootFinder';
45

56
/* eslint react/forbid-prop-types: 0 */
@@ -68,11 +69,11 @@ export default function createMountWrapper(node, options = {}) {
6869
}
6970

7071
render() {
71-
const { Component } = this.props;
72+
const { Component, refProp } = this.props;
7273
const { mount, props, wrappingComponentProps } = this.state;
7374
if (!mount) return null;
7475
// eslint-disable-next-line react/jsx-props-no-spreading
75-
const component = <Component {...props} />;
76+
const component = <Component ref={refProp} {...props} />;
7677
if (WrappingComponent) {
7778
return (
7879
// eslint-disable-next-line react/jsx-props-no-spreading
@@ -86,11 +87,13 @@ export default function createMountWrapper(node, options = {}) {
8687
}
8788
WrapperComponent.propTypes = {
8889
Component: makeValidElementType(adapter).isRequired,
90+
refProp: PropTypes.oneOfType([PropTypes.string, ref()]),
8991
props: PropTypes.object.isRequired,
9092
wrappingComponentProps: PropTypes.object,
9193
context: PropTypes.object,
9294
};
9395
WrapperComponent.defaultProps = {
96+
refProp: null,
9497
context: null,
9598
wrappingComponentProps: null,
9699
};

packages/enzyme-test-suite/test/ReactWrapper-spec.jsx

+38-4
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,44 @@ describeWithDOM('mount', () => {
104104
</div>`);
105105
});
106106

107-
it('calls ref', () => {
108-
const spy = sinon.spy();
109-
mount(<div ref={spy} />);
110-
expect(spy).to.have.property('callCount', 1);
107+
describeWithDOM('refs', () => {
108+
it('calls ref', () => {
109+
const spy = sinon.spy();
110+
mount(<div ref={spy} />);
111+
expect(spy).to.have.property('callCount', 1);
112+
});
113+
114+
/* global HTMLElement */
115+
116+
itIf(is('> 0.13'), 'passes an HTML element to `ref` when root rendered', () => {
117+
const spy = sinon.spy();
118+
mount(<div ref={spy} />);
119+
expect(spy).to.have.property('callCount', 1);
120+
121+
// sanity check
122+
expect(document.createElement('div')).to.be.instanceOf(HTMLElement);
123+
124+
const [[firstArg]] = spy.args;
125+
console.log(firstArg);
126+
expect(firstArg).to.be.instanceOf(HTMLElement);
127+
});
128+
129+
itIf(is('> 0.13'), 'passes an HTML element to `ref` when sub-rendered', () => {
130+
const spy = sinon.spy();
131+
class Foo extends React.Component {
132+
render() {
133+
return <div ref={spy} />;
134+
}
135+
}
136+
mount(<Foo />);
137+
expect(spy).to.have.property('callCount', 1);
138+
139+
// sanity check
140+
expect(document.createElement('div')).to.be.instanceOf(HTMLElement);
141+
142+
const [[firstArg]] = spy.args;
143+
expect(firstArg).to.be.instanceOf(HTMLElement);
144+
});
111145
});
112146

113147
describe('wrapping invalid elements', () => {

0 commit comments

Comments
 (0)