Skip to content

Commit

Permalink
[Fix] shallow: setProps: merge instead of replace props
Browse files Browse the repository at this point in the history
Fixes #1739. Fixes #1654.
  • Loading branch information
ljharb committed Aug 8, 2018
1 parent 2bc1f85 commit 9b4d027
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 2 deletions.
140 changes: 139 additions & 1 deletion packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,7 @@ describe('shallow', () => {
render() {
return (
<div className={this.props.id}>
{this.props.id}
{this.props.foo}
</div>
);
}
Expand All @@ -1330,6 +1330,144 @@ describe('shallow', () => {
expect(wrapper.find('.bar')).to.have.lengthOf(1);
});

describe.only('merging props', () => {
it('merges, not replaces, props when rerendering', () => {
class Foo extends React.Component {
render() {
return (
<div className={this.props.id}>
{this.props.foo}
</div>
);
}
}

const wrapper = shallow(<Foo id="foo" foo="bar" />);

expect(wrapper.debug()).to.equal(`
<div className="foo">
bar
</div>
`.trim());
expect(wrapper.props()).to.eql({
className: 'foo',
children: 'bar',
});
expect(wrapper.instance().props).to.eql({
id: 'foo',
foo: 'bar',
});

wrapper.setProps({ id: 'bar' });

expect(wrapper.debug()).to.equal(`
<div className="bar">
bar
</div>
`.trim());
expect(wrapper.props()).to.eql({
className: 'bar',
children: 'bar',
});
expect(wrapper.instance().props).to.eql({
id: 'bar',
foo: 'bar',
});
});

itIf(is('> 0.13'), 'merges, not replaces, props on SFCs', () => {
function Foo({ id, foo }) {
return (
<div className={id}>
{foo}
</div>
);
}
const wrapper = shallow(<Foo id="foo" foo="bar" />);

expect(wrapper.debug()).to.equal(`
<div className="foo">
bar
</div>
`.trim());
expect(wrapper.props()).to.eql({
className: 'foo',
children: 'bar',
});
if (is('< 16')) {
expect(wrapper.instance().props).to.eql({
id: 'foo',
foo: 'bar',
});
}

wrapper.setProps({ id: 'bar' });

expect(wrapper.debug()).to.equal(`
<div className="bar">
bar
</div>
`.trim());
expect(wrapper.props()).to.eql({
className: 'bar',
children: 'bar',
});
if (is('< 16')) {
expect(wrapper.instance().props).to.eql({
id: 'bar',
foo: 'bar',
});
}
});

it('merges, not replaces, props when no rerender is needed', () => {
class Foo extends React.Component {
shouldComponentUpdate() {
return false;
}

render() {
return (
<div className={this.props.id}>
{this.props.foo}
</div>
);
}
}
const wrapper = shallow(<Foo id="foo" foo="bar" />);

expect(wrapper.debug()).to.equal(`
<div className="foo">
bar
</div>
`.trim());
expect(wrapper.props()).to.eql({
className: 'foo',
children: 'bar',
});
expect(wrapper.instance().props).to.eql({
id: 'foo',
foo: 'bar',
});

wrapper.setProps({ id: 'foo' });

expect(wrapper.debug()).to.equal(`
<div className="foo">
bar
</div>
`.trim());
expect(wrapper.props()).to.eql({
className: 'foo',
children: 'bar',
});
expect(wrapper.instance().props).to.eql({
id: 'foo',
foo: 'bar',
});
});
});

it('should call componentWillReceiveProps for new renders', () => {
const stateValue = {};

Expand Down
2 changes: 1 addition & 1 deletion packages/enzyme/src/ShallowWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ class ShallowWrapper {
}
// If it doesn't need to rerender, update only its props.
} else if (props) {
instance.props = props;
instance.props = (Object.freeze || Object)({ ...instance.props, ...props });
}
this.update();
});
Expand Down

0 comments on commit 9b4d027

Please sign in to comment.