diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index 5167a51b4..60ef105d6 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -1319,7 +1319,7 @@ describe('shallow', () => { render() { return (
- {this.props.id} + {this.props.foo}
); } @@ -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 ( +
+ {this.props.foo} +
+ ); + } + } + + const wrapper = shallow(); + + expect(wrapper.debug()).to.equal(` +
+ bar +
+ `.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(` +
+ bar +
+ `.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 ( +
+ {foo} +
+ ); + } + const wrapper = shallow(); + + expect(wrapper.debug()).to.equal(` +
+ bar +
+ `.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(` +
+ bar +
+ `.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 ( +
+ {this.props.foo} +
+ ); + } + } + const wrapper = shallow(); + + expect(wrapper.debug()).to.equal(` +
+ bar +
+ `.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(` +
+ bar +
+ `.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 = {}; diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js index 3aa18e78c..b355e7a9b 100644 --- a/packages/enzyme/src/ShallowWrapper.js +++ b/packages/enzyme/src/ShallowWrapper.js @@ -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(); });