Skip to content

Commit

Permalink
Add failing test case for refs on the root in mount
Browse files Browse the repository at this point in the history
Fix ref on root component pointing to wrapper

Backport root ref fix to older adapters

Adjust ref call to work with 0.13 host instances

Use ref prop type

Check if WrapperComponent supports forwardedRef prop
  • Loading branch information
eps1lon authored and ljharb committed Apr 16, 2019
1 parent 696a272 commit bca17b7
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 18 deletions.
7 changes: 5 additions & 2 deletions packages/enzyme-adapter-react-13/src/ReactThirteenAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,16 @@ class ReactThirteenAdapter extends EnzymeAdapter {
render(el, context, callback) {
if (instance === null) {
const { ref, type, props } = el;
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const refProp = ReactWrapperComponent.supportsForwardedRef === true
? 'forwardedRef'
: 'ref';
const wrapperProps = {
Component: type,
props,
context,
...(ref && { ref }),
...(ref && { [refProp]: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = React.render(wrappedEl, domNode);
if (typeof callback === 'function') {
Expand Down
7 changes: 5 additions & 2 deletions packages/enzyme-adapter-react-14/src/ReactFourteenAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,17 @@ class ReactFourteenAdapter extends EnzymeAdapter {
render(el, context, callback) {
if (instance === null) {
const { type, props, ref } = el;
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const refProp = ReactWrapperComponent.supportsForwardedRef === true
? 'forwardedRef'
: 'ref';
const wrapperProps = {
Component: type,
wrappingComponentProps: options.wrappingComponentProps,
props,
context,
...(ref && { refProp: ref }),
...(ref && { [refProp]: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = ReactDOM.render(wrappedEl, domNode);
if (typeof callback === 'function') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,17 @@ class ReactFifteenFourAdapter extends EnzymeAdapter {
render(el, context, callback) {
if (instance === null) {
const { type, props, ref } = el;
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const refProp = ReactWrapperComponent.supportsForwardedRef === true
? 'forwardedRef'
: 'ref';
const wrapperProps = {
Component: type,
wrappingComponentProps: options.wrappingComponentProps,
props,
context,
...(ref && { refProp: ref }),
...(ref && { [refProp]: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = ReactDOM.render(wrappedEl, domNode);
if (typeof callback === 'function') {
Expand Down
7 changes: 5 additions & 2 deletions packages/enzyme-adapter-react-15/src/ReactFifteenAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,17 @@ class ReactFifteenAdapter extends EnzymeAdapter {
render(el, context, callback) {
if (instance === null) {
const { type, props, ref } = el;
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const refProp = ReactWrapperComponent.supportsForwardedRef === true
? 'forwardedRef'
: 'ref';
const wrapperProps = {
Component: type,
wrappingComponentProps: options.wrappingComponentProps,
props,
context,
...(ref && { refProp: ref }),
...(ref && { [refProp]: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = ReactDOM.render(wrappedEl, domNode);
if (typeof callback === 'function') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,17 @@ class ReactSixteenOneAdapter extends EnzymeAdapter {
render(el, context, callback) {
if (instance === null) {
const { type, props, ref } = el;
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const refProp = ReactWrapperComponent.supportsForwardedRef === true
? 'forwardedRef'
: 'ref';
const wrapperProps = {
Component: type,
props,
wrappingComponentProps,
context,
...(ref && { refProp: ref }),
...(ref && { [refProp]: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = hydrateIn
? ReactDOM.hydrate(wrappedEl, domNode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,17 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter {
render(el, context, callback) {
if (instance === null) {
const { type, props, ref } = el;
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const refProp = ReactWrapperComponent.supportsForwardedRef === true
? 'forwardedRef'
: 'ref';
const wrapperProps = {
Component: type,
props,
wrappingComponentProps,
context,
...(ref && { refProp: ref }),
...(ref && { [refProp]: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = hydrateIn
? ReactDOM.hydrate(wrappedEl, domNode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,17 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter {
render(el, context, callback) {
if (instance === null) {
const { type, props, ref } = el;
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const refProp = ReactWrapperComponent.supportsForwardedRef === true
? 'forwardedRef'
: 'ref';
const wrapperProps = {
Component: type,
props,
wrappingComponentProps,
context,
...(ref && { refProp: ref }),
...(ref && { [refProp]: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = hydrateIn
? ReactDOM.hydrate(wrappedEl, domNode)
Expand Down
7 changes: 5 additions & 2 deletions packages/enzyme-adapter-react-16/src/ReactSixteenAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -423,14 +423,17 @@ class ReactSixteenAdapter extends EnzymeAdapter {
return wrapAct(() => {
if (instance === null) {
const { type, props, ref } = el;
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const refProp = ReactWrapperComponent.supportsForwardedRef === true
? 'forwardedRef'
: 'ref';
const wrapperProps = {
Component: type,
props,
wrappingComponentProps,
context,
...(ref && { refProp: ref }),
...(ref && { [refProp]: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
instance = hydrateIn
? ReactDOM.hydrate(wrappedEl, domNode)
Expand Down
7 changes: 5 additions & 2 deletions packages/enzyme-adapter-utils/src/createMountWrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ export default function createMountWrapper(node, options = {}) {
}

render() {
const { Component, refProp } = this.props;
const { Component, forwardedRef } = this.props;
const { mount, props, wrappingComponentProps } = this.state;
if (!mount) return null;
// eslint-disable-next-line react/jsx-props-no-spreading
const component = <Component ref={refProp} {...props} />;
const component = <Component ref={forwardedRef} {...props} />;
if (WrappingComponent) {
return (
// eslint-disable-next-line react/jsx-props-no-spreading
Expand All @@ -85,17 +85,20 @@ export default function createMountWrapper(node, options = {}) {
return component;
}
}
WrapperComponent.supportsForwardedRef = true;
WrapperComponent.propTypes = {
Component: makeValidElementType(adapter).isRequired,
refProp: PropTypes.oneOfType([PropTypes.string, ref()]),
props: PropTypes.object.isRequired,
wrappingComponentProps: PropTypes.object,
context: PropTypes.object,
forwardedRef: ref(),
};
WrapperComponent.defaultProps = {
refProp: null,
context: null,
wrappingComponentProps: null,
forwardedRef: undefined,
};

if (options.context && (node.type.contextTypes || options.childContextTypes)) {
Expand Down
6 changes: 6 additions & 0 deletions packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,14 @@ describeWithDOM('mount', () => {
describeWithDOM('refs', () => {
it('calls ref', () => {
const spy = sinon.spy();

mount(<div ref={spy} />);

expect(spy).to.have.property('callCount', 1);

const [instance] = spy.firstCall.args;
const element = is('<= 0.13') ? instance.getDOMNode() : instance;
expect(element).to.be.instanceOf(global.HTMLElement);
});

/* global HTMLElement */
Expand Down

0 comments on commit bca17b7

Please sign in to comment.