Skip to content

Commit

Permalink
[enzyme-adapter-react-*, enzyme-adapter-utils] [fix] mount: ensure …
Browse files Browse the repository at this point in the history
…the root’s `ref` prop gets attached to the actual root

Fixes #2253.
  • Loading branch information
ljharb committed Oct 10, 2019
1 parent e47f73e commit 7836e57
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class ReactFourteenAdapter extends EnzymeAdapter {
wrappingComponentProps: options.wrappingComponentProps,
props,
context,
...(ref && { ref }),
...(ref && { refProp: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class ReactFifteenFourAdapter extends EnzymeAdapter {
wrappingComponentProps: options.wrappingComponentProps,
props,
context,
...(ref && { ref }),
...(ref && { refProp: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class ReactFifteenAdapter extends EnzymeAdapter {
wrappingComponentProps: options.wrappingComponentProps,
props,
context,
...(ref && { ref }),
...(ref && { refProp: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ class ReactSixteenOneAdapter extends EnzymeAdapter {
props,
wrappingComponentProps,
context,
...(ref && { ref }),
...(ref && { refProp: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class ReactSixteenTwoAdapter extends EnzymeAdapter {
props,
wrappingComponentProps,
context,
...(ref && { ref }),
...(ref && { refProp: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ class ReactSixteenThreeAdapter extends EnzymeAdapter {
props,
wrappingComponentProps,
context,
...(ref && { ref }),
...(ref && { refProp: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ class ReactSixteenAdapter extends EnzymeAdapter {
props,
wrappingComponentProps,
context,
...(ref && { ref }),
...(ref && { refProp: ref }),
};
const ReactWrapperComponent = createMountWrapper(el, { ...options, adapter });
const wrappedEl = React.createElement(ReactWrapperComponent, wrapperProps);
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
@@ -1,5 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { ref } from 'airbnb-prop-types';
import RootFinder from './RootFinder';

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

render() {
const { Component } = this.props;
const { Component, refProp } = this.props;
const { mount, props, wrappingComponentProps } = this.state;
if (!mount) return null;
// eslint-disable-next-line react/jsx-props-no-spreading
const component = <Component {...props} />;
const component = <Component ref={refProp} {...props} />;
if (WrappingComponent) {
return (
// eslint-disable-next-line react/jsx-props-no-spreading
Expand All @@ -86,11 +87,13 @@ export default function createMountWrapper(node, options = {}) {
}
WrapperComponent.propTypes = {
Component: makeValidElementType(adapter).isRequired,
refProp: PropTypes.oneOfType([PropTypes.string, ref()]),
props: PropTypes.object.isRequired,
wrappingComponentProps: PropTypes.object,
context: PropTypes.object,
};
WrapperComponent.defaultProps = {
refProp: null,
context: null,
wrappingComponentProps: null,
};
Expand Down
42 changes: 38 additions & 4 deletions packages/enzyme-test-suite/test/ReactWrapper-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,44 @@ describeWithDOM('mount', () => {
</div>`);
});

it('calls ref', () => {
const spy = sinon.spy();
mount(<div ref={spy} />);
expect(spy).to.have.property('callCount', 1);
describeWithDOM('refs', () => {
it('calls ref', () => {
const spy = sinon.spy();
mount(<div ref={spy} />);
expect(spy).to.have.property('callCount', 1);
});

/* global HTMLElement */

itIf(is('> 0.13'), 'passes an HTML element to `ref` when root rendered', () => {
const spy = sinon.spy();
mount(<div ref={spy} />);
expect(spy).to.have.property('callCount', 1);

// sanity check
expect(document.createElement('div')).to.be.instanceOf(HTMLElement);

const [[firstArg]] = spy.args;
console.log(firstArg);
expect(firstArg).to.be.instanceOf(HTMLElement);
});

itIf(is('> 0.13'), 'passes an HTML element to `ref` when sub-rendered', () => {
const spy = sinon.spy();
class Foo extends React.Component {
render() {
return <div ref={spy} />;
}
}
mount(<Foo />);
expect(spy).to.have.property('callCount', 1);

// sanity check
expect(document.createElement('div')).to.be.instanceOf(HTMLElement);

const [[firstArg]] = spy.args;
expect(firstArg).to.be.instanceOf(HTMLElement);
});
});

describe('wrapping invalid elements', () => {
Expand Down

0 comments on commit 7836e57

Please sign in to comment.