@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
44import { expect } from 'chai' ;
55import sinon from 'sinon' ;
66import wrap from 'mocha-wrap' ;
7+ import isEqual from 'lodash.isequal' ;
78import {
89 mount ,
910 render ,
@@ -27,6 +28,7 @@ import {
2728 createRef ,
2829 Fragment ,
2930 forwardRef ,
31+ PureComponent ,
3032} from './_helpers/react-compat' ;
3133import {
3234 describeWithDOM ,
@@ -5128,6 +5130,78 @@ describeWithDOM('mount', () => {
51285130 } ) ;
51295131 } ) ;
51305132
5133+ describeIf ( is ( '>= 15.3' ) , 'PureComponent' , ( ) => {
5134+ it ( 'does not update when state and props did not change' , ( ) => {
5135+ class Foo extends PureComponent {
5136+ constructor ( props ) {
5137+ super ( props ) ;
5138+ this . state = {
5139+ foo : 'init' ,
5140+ } ;
5141+ }
5142+
5143+ componentDidUpdate ( ) { }
5144+
5145+ render ( ) {
5146+ return (
5147+ < div >
5148+ { this . state . foo }
5149+ </ div >
5150+ ) ;
5151+ }
5152+ }
5153+ const spy = sinon . spy ( Foo . prototype , 'componentDidUpdate' ) ;
5154+ const wrapper = mount ( < Foo id = { 1 } /> ) ;
5155+ wrapper . setState ( { foo : 'update' } ) ;
5156+ expect ( spy ) . to . have . property ( 'callCount' , 1 ) ;
5157+ wrapper . setState ( { foo : 'update' } ) ;
5158+ expect ( spy ) . to . have . property ( 'callCount' , 1 ) ;
5159+
5160+ wrapper . setProps ( { id : 2 } ) ;
5161+ expect ( spy ) . to . have . property ( 'callCount' , 2 ) ;
5162+ wrapper . setProps ( { id : 2 } ) ;
5163+ expect ( spy ) . to . have . property ( 'callCount' , 2 ) ;
5164+ } ) ;
5165+ } ) ;
5166+
5167+ describe ( 'Own PureComponent implementation' , ( ) => {
5168+ it ( 'does not update when state and props did not change' , ( ) => {
5169+ class Foo extends React . Component {
5170+ constructor ( props ) {
5171+ super ( props ) ;
5172+ this . state = {
5173+ foo : 'init' ,
5174+ } ;
5175+ }
5176+
5177+ shouldComponentUpdate ( nextProps , nextState ) {
5178+ return ! isEqual ( this . props , nextProps ) || ! isEqual ( this . state , nextState ) ;
5179+ }
5180+
5181+ componentDidUpdate ( ) { }
5182+
5183+ render ( ) {
5184+ return (
5185+ < div >
5186+ { this . state . foo }
5187+ </ div >
5188+ ) ;
5189+ }
5190+ }
5191+ const spy = sinon . spy ( Foo . prototype , 'componentDidUpdate' ) ;
5192+ const wrapper = mount ( < Foo id = { 1 } /> ) ;
5193+ wrapper . setState ( { foo : 'update' } ) ;
5194+ expect ( spy ) . to . have . property ( 'callCount' , 1 ) ;
5195+ wrapper . setState ( { foo : 'update' } ) ;
5196+ expect ( spy ) . to . have . property ( 'callCount' , 1 ) ;
5197+
5198+ wrapper . setProps ( { id : 2 } ) ;
5199+ expect ( spy ) . to . have . property ( 'callCount' , 2 ) ;
5200+ wrapper . setProps ( { id : 2 } ) ;
5201+ expect ( spy ) . to . have . property ( 'callCount' , 2 ) ;
5202+ } ) ;
5203+ } ) ;
5204+
51315205 describeIf ( is ( '>= 16.3' ) , 'support getSnapshotBeforeUpdate' , ( ) => {
51325206 it ( 'calls getSnapshotBeforeUpdate and pass snapshot to componentDidUpdate' , ( ) => {
51335207 const spy = sinon . spy ( ) ;
0 commit comments