@@ -2945,7 +2945,7 @@ describe('shallow', () => {
29452945 }
29462946 }
29472947 const result = shallow ( < Foo /> ) ;
2948- expect ( result . state ( 'count' ) ) . to . equal ( 2 ) ;
2948+ expect ( result . state ( ) ) . to . have . property ( 'count' , 2 ) ;
29492949 expect ( spy ) . to . have . property ( 'callCount' , 2 ) ;
29502950 } ) ;
29512951 } ) ;
@@ -2981,19 +2981,17 @@ describe('shallow', () => {
29812981
29822982 render ( ) {
29832983 spy ( 'render' ) ;
2984- return < div > { this . state . foo } </ div > ;
2984+ const { foo } = this . state ;
2985+ return < div > { foo } </ div > ;
29852986 }
29862987 }
29872988 Foo . contextTypes = {
29882989 foo : PropTypes . string ,
29892990 } ;
29902991
2991- const wrapper = shallow (
2992- < Foo foo = "bar" /> ,
2993- {
2994- context : { foo : 'context' } ,
2995- } ,
2996- ) ;
2992+ const wrapper = shallow ( < Foo foo = "bar" /> , {
2993+ context : { foo : 'context' } ,
2994+ } ) ;
29972995 wrapper . setProps ( { foo : 'baz' } ) ;
29982996 wrapper . setProps ( { foo : 'bax' } ) ;
29992997 expect ( spy . args ) . to . deep . equal ( [
@@ -3595,6 +3593,276 @@ describe('shallow', () => {
35953593 } ) ;
35963594 } ) ;
35973595
3596+ context ( 'unmounting phase' , ( ) => {
3597+ it ( 'should call componentWillUnmount' , ( ) => {
3598+ const spy = sinon . spy ( ) ;
3599+ class Foo extends React . Component {
3600+ componentWillUnmount ( ) {
3601+ spy ( ) ;
3602+ }
3603+ render ( ) {
3604+ return < div > foo</ div > ;
3605+ }
3606+ }
3607+ const wrapper = shallow ( < Foo /> ) ;
3608+ wrapper . unmount ( ) ;
3609+ expect ( spy ) . to . have . property ( 'callCount' , 1 ) ;
3610+ } ) ;
3611+ } ) ;
3612+
3613+ context ( 'component instance' , ( ) => {
3614+ it ( 'should call `componentDidUpdate` when component’s `setState` is called' , ( ) => {
3615+ const spy = sinon . spy ( ) ;
3616+ class Foo extends React . Component {
3617+ constructor ( props ) {
3618+ super ( props ) ;
3619+ this . state = {
3620+ foo : 'init' ,
3621+ } ;
3622+ }
3623+ componentDidUpdate ( ) {
3624+ spy ( ) ;
3625+ }
3626+ onChange ( ) {
3627+ // enzyme can't handle the update because `this` is a ReactComponent instance,
3628+ // not a ShallowWrapper instance.
3629+ this . setState ( { foo : 'onChange update' } ) ;
3630+ }
3631+ render ( ) {
3632+ return < div > { this . state . foo } </ div > ;
3633+ }
3634+ }
3635+ const wrapper = shallow ( < Foo /> ) ;
3636+
3637+ wrapper . setState ( { foo : 'wrapper setState update' } ) ;
3638+ expect ( wrapper . state ( 'foo' ) ) . to . equal ( 'wrapper setState update' ) ;
3639+ expect ( spy ) . to . have . property ( 'callCount' , 1 ) ;
3640+
3641+ wrapper . instance ( ) . onChange ( ) ;
3642+ expect ( wrapper . state ( 'foo' ) ) . to . equal ( 'onChange update' ) ;
3643+ expect ( spy ) . to . have . property ( 'callCount' , 2 ) ;
3644+ } ) ;
3645+ } ) ;
3646+
3647+ describeIf ( REACT16 , 'support getSnapshotBeforeUpdate' , ( ) => {
3648+ it ( 'should call getSnapshotBeforeUpdate and pass snapshot to componentDidUpdate' , ( ) => {
3649+ const spy = sinon . spy ( ) ;
3650+ class Foo extends React . Component {
3651+ constructor ( props ) {
3652+ super ( props ) ;
3653+ this . state = {
3654+ foo : 'bar' ,
3655+ } ;
3656+ }
3657+ componentDidUpdate ( prevProps , prevState , snapshot ) {
3658+ spy ( 'componentDidUpdate' , prevProps , this . props , prevState , this . state , snapshot ) ;
3659+ }
3660+ getSnapshotBeforeUpdate ( prevProps , prevState ) {
3661+ spy ( 'getSnapshotBeforeUpdate' , prevProps , this . props , prevState , this . state ) ;
3662+ return { snapshot : 'ok' } ;
3663+ }
3664+ render ( ) {
3665+ spy ( 'render' ) ;
3666+ return < div > foo</ div > ;
3667+ }
3668+ }
3669+ const wrapper = shallow ( < Foo name = "foo" /> ) ;
3670+ spy . reset ( ) ;
3671+ wrapper . setProps ( { name : 'bar' } ) ;
3672+ expect ( spy . args ) . to . deep . equal ( [
3673+ [ 'render' ] ,
3674+ [ 'getSnapshotBeforeUpdate' , { name : 'foo' } , { name : 'bar' } , { foo : 'bar' } , { foo : 'bar' } ] ,
3675+ [ 'componentDidUpdate' , { name : 'foo' } , { name : 'bar' } , { foo : 'bar' } , { foo : 'bar' } , { snapshot : 'ok' } ] ,
3676+ ] ) ;
3677+ spy . reset ( ) ;
3678+ wrapper . setState ( { foo : 'baz' } ) ;
3679+ expect ( spy . args ) . to . deep . equal ( [
3680+ [ 'render' ] ,
3681+ [ 'getSnapshotBeforeUpdate' , { name : 'bar' } , { name : 'bar' } , { foo : 'bar' } , { foo : 'baz' } ] ,
3682+ [ 'componentDidUpdate' , { name : 'bar' } , { name : 'bar' } , { foo : 'bar' } , { foo : 'baz' } , { snapshot : 'ok' } ] ,
3683+ ] ) ;
3684+ } ) ;
3685+ } ) ;
3686+
3687+ it ( 'should not call when disableLifecycleMethods flag is true' , ( ) => {
3688+ const spy = sinon . spy ( ) ;
3689+ class Foo extends React . Component {
3690+ componentDidMount ( ) {
3691+ spy ( ) ;
3692+ }
3693+ render ( ) {
3694+ return < div > foo</ div > ;
3695+ }
3696+ }
3697+ shallow ( < Foo /> , { disableLifecycleMethods : true } ) ;
3698+ expect ( spy ) . to . have . property ( 'callCount' , 0 ) ;
3699+ } ) ;
3700+
3701+ it ( 'should call shouldComponentUpdate when disableLifecycleMethods flag is true' , ( ) => {
3702+ const spy = sinon . spy ( ) ;
3703+ class Foo extends React . Component {
3704+ constructor ( props ) {
3705+ super ( props ) ;
3706+ this . state = {
3707+ foo : 'bar' ,
3708+ } ;
3709+ }
3710+ shouldComponentUpdate ( ) {
3711+ spy ( ) ;
3712+ return false ;
3713+ }
3714+ render ( ) {
3715+ return < div > { this . state . foo } </ div > ;
3716+ }
3717+ }
3718+ const wrapper = shallow (
3719+ < Foo foo = "foo" /> ,
3720+ {
3721+ context : { foo : 'foo' } ,
3722+ disableLifecycleMethods : true ,
3723+ } ,
3724+ ) ;
3725+ expect ( spy ) . to . have . property ( 'callCount' , 0 ) ;
3726+ wrapper . setProps ( { foo : 'bar' } ) ;
3727+ expect ( spy ) . to . have . property ( 'callCount' , 1 ) ;
3728+ wrapper . setState ( { foo : 'bar' } ) ;
3729+ expect ( spy ) . to . have . property ( 'callCount' , 2 ) ;
3730+ wrapper . setContext ( { foo : 'bar' } ) ;
3731+ expect ( spy ) . to . have . property ( 'callCount' , 3 ) ;
3732+ } ) ;
3733+ } ) ;
3734+
3735+ it ( 'works with class components that return null' , ( ) => {
3736+ class Foo extends React . Component {
3737+ render ( ) {
3738+ return null ;
3739+ }
3740+ }
3741+ const wrapper = shallow ( < Foo /> ) ;
3742+ expect ( wrapper ) . to . have . length ( 1 ) ;
3743+ expect ( wrapper . html ( ) ) . to . equal ( null ) ;
3744+ expect ( wrapper . type ( ) ) . to . equal ( null ) ;
3745+ const rendered = wrapper . render ( ) ;
3746+ expect ( rendered . length ) . to . equal ( 0 ) ;
3747+ expect ( rendered . html ( ) ) . to . equal ( null ) ;
3748+ } ) ;
3749+
3750+ itIf ( REACT16 , 'works with class components that return arrays' , ( ) => {
3751+ class Foo extends React . Component {
3752+ render ( ) {
3753+ return [ < div /> , < div /> ] ;
3754+ }
3755+ }
3756+ const wrapper = shallow ( < Foo /> ) ;
3757+ expect ( wrapper ) . to . have . lengthOf ( 2 ) ;
3758+ expect ( wrapper . find ( 'div' ) ) . to . have . lengthOf ( 2 ) ;
3759+ } ) ;
3760+
3761+ itIf ( is ( '>=15 || ^16.0.0-alpha' ) , 'works with SFCs that return null' , ( ) => {
3762+ const Foo = ( ) => null ;
3763+
3764+ const wrapper = shallow ( < Foo /> ) ;
3765+ expect ( wrapper ) . to . have . length ( 1 ) ;
3766+ expect ( wrapper . html ( ) ) . to . equal ( null ) ;
3767+ expect ( wrapper . type ( ) ) . to . equal ( null ) ;
3768+ const rendered = wrapper . render ( ) ;
3769+ expect ( rendered . length ) . to . equal ( 0 ) ;
3770+ expect ( rendered . html ( ) ) . to . equal ( null ) ;
3771+ } ) ;
3772+
3773+ describe ( '.tap()' , ( ) => {
3774+ it ( 'should call the passed function with current ShallowWrapper and returns itself' , ( ) => {
3775+ const spy = sinon . spy ( ) ;
3776+ const wrapper = shallow ( (
3777+ < ul >
3778+ < li > xxx</ li >
3779+ < li > yyy</ li >
3780+ < li > zzz</ li >
3781+ </ ul >
3782+ ) ) . find ( 'li' ) ;
3783+ const result = wrapper . tap ( spy ) ;
3784+ expect ( spy . calledWith ( wrapper ) ) . to . equal ( true ) ;
3785+ expect ( result ) . to . equal ( wrapper ) ;
3786+ } ) ;
3787+ } ) ;
3788+
3789+ describe ( '.key()' , ( ) => {
3790+ it ( 'should return the key of the node' , ( ) => {
3791+ const wrapper = shallow ( (
3792+ < ul >
3793+ { [ 'foo' , 'bar' , '' ] . map ( s => < li key = { s } > { s } </ li > ) }
3794+ </ ul >
3795+ ) ) . find ( 'li' ) ;
3796+ expect ( wrapper . at ( 0 ) . key ( ) ) . to . equal ( 'foo' ) ;
3797+ expect ( wrapper . at ( 1 ) . key ( ) ) . to . equal ( 'bar' ) ;
3798+ expect ( wrapper . at ( 2 ) . key ( ) ) . to . equal ( '' ) ;
3799+ } ) ;
3800+
3801+ it ( 'should return null when no key is specified' , ( ) => {
3802+ const wrapper = shallow ( (
3803+ < ul >
3804+ < li > foo</ li >
3805+ </ ul >
3806+ ) ) . find ( 'li' ) ;
3807+ expect ( wrapper . key ( ) ) . to . equal ( null ) ;
3808+ } ) ;
3809+ } ) ;
3810+
3811+ describe ( '.matchesElement(node)' , ( ) => {
3812+ it ( 'should match on a root node that looks like the rendered one' , ( ) => {
3813+ const spy = sinon . spy ( ) ;
3814+ const wrapper = shallow ( (
3815+ < div >
3816+ < div onClick = { spy } style = { { fontSize : 12 , color : 'red' } } > Hello World</ div >
3817+ </ div >
3818+ ) ) . first ( ) ;
3819+ expect ( wrapper . matchesElement ( < div > < div > Hello World</ div > </ div > ) ) . to . equal ( true ) ;
3820+ expect ( wrapper . matchesElement ( (
3821+ < div >
3822+ < div onClick = { spy } style = { { fontSize : 12 , color : 'red' } } > Hello World</ div >
3823+ </ div >
3824+ ) ) ) . to . equal ( true ) ;
3825+ expect ( wrapper . matchesElement ( (
3826+ < div >
3827+ < div onClick = { spy } > Hello World</ div >
3828+ </ div >
3829+ ) ) ) . to . equal ( true ) ;
3830+ expect ( wrapper . matchesElement ( (
3831+ < div >
3832+ < div style = { { fontSize : 12 , color : 'red' } } > Hello World</ div >
3833+ </ div >
3834+ ) ) ) . to . equal ( true ) ;
3835+ expect ( spy ) . to . have . property ( 'callCount' , 0 ) ;
3836+ } ) ;
3837+
3838+ it ( 'should not match on a root node that doesn\'t looks like the rendered one' , ( ) => {
3839+ const spy = sinon . spy ( ) ;
3840+ const spy2 = sinon . spy ( ) ;
3841+ const wrapper = shallow ( (
3842+ < div >
3843+ < div onClick = { spy } style = { { fontSize : 12 , color : 'red' } } > Hello World</ div >
3844+ </ div >
3845+ ) ) . first ( ) ;
3846+ expect ( wrapper . matchesElement ( < div > < div > Bonjour le monde</ div > </ div > ) ) . to . equal ( false ) ;
3847+ expect ( wrapper . matchesElement ( (
3848+ < div >
3849+ < div onClick = { spy } style = { { fontSize : 12 , color : 'blue' } } > Hello World</ div >
3850+ </ div >
3851+ ) ) ) . to . equal ( false ) ;
3852+ expect ( wrapper . matchesElement ( (
3853+ < div >
3854+ < div onClick = { spy2 } > Hello World</ div >
3855+ </ div >
3856+ ) ) ) . to . equal ( false ) ;
3857+ expect ( wrapper . matchesElement ( (
3858+ < div >
3859+ < div style = { { fontSize : 13 , color : 'red' } } > Hello World</ div >
3860+ </ div >
3861+ ) ) ) . to . equal ( false ) ;
3862+ expect ( spy ) . to . have . property ( 'callCount' , 0 ) ;
3863+ expect ( spy2 ) . to . have . property ( 'callCount' , 0 ) ;
3864+ } ) ;
3865+
35983866 context ( 'unmounting phase' , ( ) => {
35993867 it ( 'calls componentWillUnmount' , ( ) => {
36003868 const spy = sinon . spy ( ) ;
0 commit comments