Skip to content

Commit

Permalink
[Fix] mount/shallow: renderProp: improve error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Mar 26, 2019
1 parent a9a69f1 commit e17eb34
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
32 changes: 31 additions & 1 deletion packages/enzyme-test-suite/test/shared/methods/renderProp.jsx
Expand Up @@ -13,6 +13,7 @@ import { is } from '../../_helpers/version';
export default function describeRenderProp({
Wrap,
WrapRendered,
WrapperName,
}) {
wrap()
.withConsoleThrows()
Expand All @@ -25,7 +26,12 @@ export default function describeRenderProp({
class Bar extends React.Component {
render() {
const { render: r } = this.props;
return <div className="in-bar">{r()}</div>;
return <div className="in-bar">{typeof r === 'function' && r()}</div>;
}
}
class RendersBar extends React.Component {
render() {
return <Bar {...this.props} />;
}
}

Expand All @@ -45,6 +51,30 @@ export default function describeRenderProp({
expect(stub.args).to.deep.equal([['one', 'two']]);
});

it('throws on a non-string prop name', () => {
const wrapper = Wrap(<RendersBar render={() => {}} />);
expect(() => wrapper.renderProp()).to.throw(
TypeError,
`${WrapperName}::renderProp(): \`propName\` must be a string`,
);
});

it('throws on a missing prop', () => {
const wrapper = Wrap(<RendersBar render={() => {}} />);
expect(() => wrapper.renderProp('nope')).to.throw(
Error,
`${WrapperName}::renderProp(): no prop called “nope“ found`,
);
});

it('throws on a non-function render prop value', () => {
const wrapper = Wrap(<RendersBar render={{}} />);
expect(() => wrapper.renderProp('render')).to.throw(
TypeError,
`${WrapperName}::renderProp(): expected prop “render“ to contain a function, but it holds “object“`,
);
});

it('throws on host elements', () => {
class Div extends React.Component {
render() {
Expand Down
6 changes: 3 additions & 3 deletions packages/enzyme/src/ReactWrapper.js
Expand Up @@ -794,15 +794,15 @@ class ReactWrapper {
throw new TypeError('ReactWrapper::renderProp() can only be called on custom components');
}
if (typeof propName !== 'string') {
throw new TypeError('`propName` must be a string');
throw new TypeError('ReactWrapper::renderProp(): `propName` must be a string');
}
const props = this.props();
if (!has(props, propName)) {
throw new Error(`no prop called “${propName}“ found`);
throw new Error(`ReactWrapper::renderProp(): no prop called “${propName}“ found`);
}
const propValue = props[propName];
if (typeof propValue !== 'function') {
throw new TypeError(`expected prop “${propName}“ to contain a function, but it holds “${typeof prop}“`);
throw new TypeError(`ReactWrapper::renderProp(): expected prop “${propName}“ to contain a function, but it holds “${typeof propValue}“`);
}

return (...args) => {
Expand Down
6 changes: 3 additions & 3 deletions packages/enzyme/src/ShallowWrapper.js
Expand Up @@ -1191,15 +1191,15 @@ class ShallowWrapper {
throw new TypeError('ShallowWrapper::renderProp() can only be called on custom components');
}
if (typeof propName !== 'string') {
throw new TypeError('`propName` must be a string');
throw new TypeError('ShallowWrapper::renderProp(): `propName` must be a string');
}
const props = this.props();
if (!has(props, propName)) {
throw new Error(`no prop called “${propName}“ found`);
throw new Error(`ShallowWrapper::renderProp(): no prop called “${propName}“ found`);
}
const propValue = props[propName];
if (typeof propValue !== 'function') {
throw new TypeError(`expected prop “${propName}“ to contain a function, but it holds “${typeof prop}“`);
throw new TypeError(`ShallowWrapper::renderProp(): expected prop “${propName}“ to contain a function, but it holds “${typeof propValue}“`);
}

return (...args) => {
Expand Down

0 comments on commit e17eb34

Please sign in to comment.