Skip to content

Commit 9b4d027

Browse files
committed
[Fix] shallow: setProps: merge instead of replace props
Fixes #1739. Fixes #1654.
1 parent 2bc1f85 commit 9b4d027

File tree

2 files changed

+140
-2
lines changed

2 files changed

+140
-2
lines changed

packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,7 @@ describe('shallow', () => {
13191319
render() {
13201320
return (
13211321
<div className={this.props.id}>
1322-
{this.props.id}
1322+
{this.props.foo}
13231323
</div>
13241324
);
13251325
}
@@ -1330,6 +1330,144 @@ describe('shallow', () => {
13301330
expect(wrapper.find('.bar')).to.have.lengthOf(1);
13311331
});
13321332

1333+
describe.only('merging props', () => {
1334+
it('merges, not replaces, props when rerendering', () => {
1335+
class Foo extends React.Component {
1336+
render() {
1337+
return (
1338+
<div className={this.props.id}>
1339+
{this.props.foo}
1340+
</div>
1341+
);
1342+
}
1343+
}
1344+
1345+
const wrapper = shallow(<Foo id="foo" foo="bar" />);
1346+
1347+
expect(wrapper.debug()).to.equal(`
1348+
<div className="foo">
1349+
bar
1350+
</div>
1351+
`.trim());
1352+
expect(wrapper.props()).to.eql({
1353+
className: 'foo',
1354+
children: 'bar',
1355+
});
1356+
expect(wrapper.instance().props).to.eql({
1357+
id: 'foo',
1358+
foo: 'bar',
1359+
});
1360+
1361+
wrapper.setProps({ id: 'bar' });
1362+
1363+
expect(wrapper.debug()).to.equal(`
1364+
<div className="bar">
1365+
bar
1366+
</div>
1367+
`.trim());
1368+
expect(wrapper.props()).to.eql({
1369+
className: 'bar',
1370+
children: 'bar',
1371+
});
1372+
expect(wrapper.instance().props).to.eql({
1373+
id: 'bar',
1374+
foo: 'bar',
1375+
});
1376+
});
1377+
1378+
itIf(is('> 0.13'), 'merges, not replaces, props on SFCs', () => {
1379+
function Foo({ id, foo }) {
1380+
return (
1381+
<div className={id}>
1382+
{foo}
1383+
</div>
1384+
);
1385+
}
1386+
const wrapper = shallow(<Foo id="foo" foo="bar" />);
1387+
1388+
expect(wrapper.debug()).to.equal(`
1389+
<div className="foo">
1390+
bar
1391+
</div>
1392+
`.trim());
1393+
expect(wrapper.props()).to.eql({
1394+
className: 'foo',
1395+
children: 'bar',
1396+
});
1397+
if (is('< 16')) {
1398+
expect(wrapper.instance().props).to.eql({
1399+
id: 'foo',
1400+
foo: 'bar',
1401+
});
1402+
}
1403+
1404+
wrapper.setProps({ id: 'bar' });
1405+
1406+
expect(wrapper.debug()).to.equal(`
1407+
<div className="bar">
1408+
bar
1409+
</div>
1410+
`.trim());
1411+
expect(wrapper.props()).to.eql({
1412+
className: 'bar',
1413+
children: 'bar',
1414+
});
1415+
if (is('< 16')) {
1416+
expect(wrapper.instance().props).to.eql({
1417+
id: 'bar',
1418+
foo: 'bar',
1419+
});
1420+
}
1421+
});
1422+
1423+
it('merges, not replaces, props when no rerender is needed', () => {
1424+
class Foo extends React.Component {
1425+
shouldComponentUpdate() {
1426+
return false;
1427+
}
1428+
1429+
render() {
1430+
return (
1431+
<div className={this.props.id}>
1432+
{this.props.foo}
1433+
</div>
1434+
);
1435+
}
1436+
}
1437+
const wrapper = shallow(<Foo id="foo" foo="bar" />);
1438+
1439+
expect(wrapper.debug()).to.equal(`
1440+
<div className="foo">
1441+
bar
1442+
</div>
1443+
`.trim());
1444+
expect(wrapper.props()).to.eql({
1445+
className: 'foo',
1446+
children: 'bar',
1447+
});
1448+
expect(wrapper.instance().props).to.eql({
1449+
id: 'foo',
1450+
foo: 'bar',
1451+
});
1452+
1453+
wrapper.setProps({ id: 'foo' });
1454+
1455+
expect(wrapper.debug()).to.equal(`
1456+
<div className="foo">
1457+
bar
1458+
</div>
1459+
`.trim());
1460+
expect(wrapper.props()).to.eql({
1461+
className: 'foo',
1462+
children: 'bar',
1463+
});
1464+
expect(wrapper.instance().props).to.eql({
1465+
id: 'foo',
1466+
foo: 'bar',
1467+
});
1468+
});
1469+
});
1470+
13331471
it('should call componentWillReceiveProps for new renders', () => {
13341472
const stateValue = {};
13351473

packages/enzyme/src/ShallowWrapper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ class ShallowWrapper {
358358
}
359359
// If it doesn't need to rerender, update only its props.
360360
} else if (props) {
361-
instance.props = props;
361+
instance.props = (Object.freeze || Object)({ ...instance.props, ...props });
362362
}
363363
this.update();
364364
});

0 commit comments

Comments
 (0)