diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
index 0a5e20d08..10a0a3c11 100644
--- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
+++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx
@@ -958,6 +958,50 @@ describe('shallow', () => {
expect(wrapper.first('div').text()).to.equal('yolo');
});
+ it('should call componentWillReceiveProps, shouldComponentUpdate and componentWillUpdate with merged newProps', () => {
+ const spy = sinon.spy();
+
+ class Foo extends React.Component {
+ componentWillReceiveProps(nextProps) {
+ spy('componentWillReceiveProps', this.props, nextProps);
+ }
+ shouldComponentUpdate(nextProps) {
+ spy('shouldComponentUpdate', this.props, nextProps);
+ return true;
+ }
+ componentWillUpdate(nextProps) {
+ spy('componentWillUpdate', this.props, nextProps);
+ }
+ render() {
+ return (
+
+ );
+ }
+ }
+
+ const wrapper = shallow();
+
+ wrapper.setProps({ b: 'c', d: 'e' });
+
+ expect(spy.args).to.deep.equal([
+ [
+ 'componentWillReceiveProps',
+ { a: 'a', b: 'b' },
+ { a: 'a', b: 'c', d: 'e' },
+ ],
+ [
+ 'shouldComponentUpdate',
+ { a: 'a', b: 'b' },
+ { a: 'a', b: 'c', d: 'e' },
+ ],
+ [
+ 'componentWillUpdate',
+ { a: 'a', b: 'b' },
+ { a: 'a', b: 'c', d: 'e' },
+ ],
+ ]);
+ });
+
describeIf(!REACT013, 'stateless function components', () => {
it('should set props for a component multiple times', () => {
const Foo = props => (
@@ -3094,6 +3138,58 @@ describe('shallow', () => {
);
});
+ it('should componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate and componentDidUpdate with merged props', () => {
+ const spy = sinon.spy();
+
+ class Foo extends React.Component {
+ componentWillReceiveProps(nextProps) {
+ spy('componentWillReceiveProps', this.props, nextProps);
+ }
+ shouldComponentUpdate(nextProps) {
+ spy('shouldComponentUpdate', this.props, nextProps);
+ return true;
+ }
+ componentWillUpdate(nextProps) {
+ spy('componentWillUpdate', this.props, nextProps);
+ }
+ componentDidUpdate(prevProps) {
+ spy('componentDidUpdate', prevProps, this.props);
+ }
+ render() {
+ return (
+
+ );
+ }
+ }
+
+ const wrapper = shallow(, { lifecycleExperimental: true });
+
+ wrapper.setProps({ b: 'c', d: 'e' });
+
+ expect(spy.args).to.deep.equal([
+ [
+ 'componentWillReceiveProps',
+ { a: 'a', b: 'b' },
+ { a: 'a', b: 'c', d: 'e' },
+ ],
+ [
+ 'shouldComponentUpdate',
+ { a: 'a', b: 'b' },
+ { a: 'a', b: 'c', d: 'e' },
+ ],
+ [
+ 'componentWillUpdate',
+ { a: 'a', b: 'b' },
+ { a: 'a', b: 'c', d: 'e' },
+ ],
+ [
+ 'componentDidUpdate',
+ { a: 'a', b: 'b' },
+ { a: 'a', b: 'c', d: 'e' },
+ ],
+ ]);
+ });
+
it('should cancel rendering when Component returns false in shouldComponentUpdate', () => {
const spy = sinon.spy();
diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js
index c4defa1bc..5bab2813e 100644
--- a/packages/enzyme/src/ShallowWrapper.js
+++ b/packages/enzyme/src/ShallowWrapper.js
@@ -262,7 +262,7 @@ class ShallowWrapper {
const state = instance.state;
const prevProps = instance.props || this[UNRENDERED].props;
const prevContext = instance.context || this[OPTIONS].context;
- const nextProps = props || prevProps;
+ const nextProps = { ...prevProps, ...props };
const nextContext = context || prevContext;
if (context) {
this[OPTIONS] = { ...this[OPTIONS], context: nextContext };