@@ -474,6 +474,190 @@ describe('defineCustomElement', () => {
474474        '<div><span>1 is number</span><span>true is boolean</span></div>' , 
475475      ) 
476476    } ) 
477+ 
478+     test ( 'should patch all props together' ,  async  ( )  =>  { 
479+       let  prop1Calls  =  0 
480+       let  prop2Calls  =  0 
481+       const  E  =  defineCustomElement ( { 
482+         props : { 
483+           prop1 : { 
484+             type : String , 
485+             default : 'default1' , 
486+           } , 
487+           prop2 : { 
488+             type : String , 
489+             default : 'default2' , 
490+           } , 
491+         } , 
492+         data ( )  { 
493+           return  { 
494+             data1 : 'defaultData1' , 
495+             data2 : 'defaultData2' , 
496+           } 
497+         } , 
498+         watch : { 
499+           prop1 ( _ )  { 
500+             prop1Calls ++ 
501+             this . data2  =  this . prop2 
502+           } , 
503+           prop2 ( _ )  { 
504+             prop2Calls ++ 
505+             this . data1  =  this . prop1 
506+           } , 
507+         } , 
508+         render ( )  { 
509+           return  h ( 'div' ,  [ 
510+             h ( 'h1' ,  this . prop1 ) , 
511+             h ( 'h1' ,  this . prop2 ) , 
512+             h ( 'h2' ,  this . data1 ) , 
513+             h ( 'h2' ,  this . data2 ) , 
514+           ] ) 
515+         } , 
516+       } ) 
517+       customElements . define ( 'my-watch-element' ,  E ) 
518+ 
519+       render ( h ( 'my-watch-element' ) ,  container ) 
520+       const  e  =  container . childNodes [ 0 ]  as  VueElement 
521+       expect ( e ) . toBeInstanceOf ( E ) 
522+       expect ( e . _instance ) . toBeTruthy ( ) 
523+       expect ( e . shadowRoot ! . innerHTML ) . toBe ( 
524+         `<div><h1>default1</h1><h1>default2</h1><h2>defaultData1</h2><h2>defaultData2</h2></div>` , 
525+       ) 
526+       expect ( prop1Calls ) . toBe ( 0 ) 
527+       expect ( prop2Calls ) . toBe ( 0 ) 
528+ 
529+       // patch props 
530+       render ( 
531+         h ( 'my-watch-element' ,  {  prop1 : 'newValue1' ,  prop2 : 'newValue2'  } ) , 
532+         container , 
533+       ) 
534+       await  nextTick ( ) 
535+       expect ( e . shadowRoot ! . innerHTML ) . toBe ( 
536+         `<div><h1>newValue1</h1><h1>newValue2</h1><h2>newValue1</h2><h2>newValue2</h2></div>` , 
537+       ) 
538+       expect ( prop1Calls ) . toBe ( 1 ) 
539+       expect ( prop2Calls ) . toBe ( 1 ) 
540+ 
541+       // same prop values 
542+       render ( 
543+         h ( 'my-watch-element' ,  {  prop1 : 'newValue1' ,  prop2 : 'newValue2'  } ) , 
544+         container , 
545+       ) 
546+       await  nextTick ( ) 
547+       expect ( e . shadowRoot ! . innerHTML ) . toBe ( 
548+         `<div><h1>newValue1</h1><h1>newValue2</h1><h2>newValue1</h2><h2>newValue2</h2></div>` , 
549+       ) 
550+       expect ( prop1Calls ) . toBe ( 1 ) 
551+       expect ( prop2Calls ) . toBe ( 1 ) 
552+ 
553+       // update only prop1 
554+       render ( 
555+         h ( 'my-watch-element' ,  {  prop1 : 'newValue3' ,  prop2 : 'newValue2'  } ) , 
556+         container , 
557+       ) 
558+       await  nextTick ( ) 
559+       expect ( e . shadowRoot ! . innerHTML ) . toBe ( 
560+         `<div><h1>newValue3</h1><h1>newValue2</h1><h2>newValue1</h2><h2>newValue2</h2></div>` , 
561+       ) 
562+       expect ( prop1Calls ) . toBe ( 2 ) 
563+       expect ( prop2Calls ) . toBe ( 1 ) 
564+     } ) 
565+ 
566+     test ( 'should patch all props together (async)' ,  async  ( )  =>  { 
567+       let  prop1Calls  =  0 
568+       let  prop2Calls  =  0 
569+       const  E  =  defineCustomElement ( 
570+         defineAsyncComponent ( ( )  => 
571+           Promise . resolve ( 
572+             defineComponent ( { 
573+               props : { 
574+                 prop1 : { 
575+                   type : String , 
576+                   default : 'default1' , 
577+                 } , 
578+                 prop2 : { 
579+                   type : String , 
580+                   default : 'default2' , 
581+                 } , 
582+               } , 
583+               data ( )  { 
584+                 return  { 
585+                   data1 : 'defaultData1' , 
586+                   data2 : 'defaultData2' , 
587+                 } 
588+               } , 
589+               watch : { 
590+                 prop1 ( _ )  { 
591+                   prop1Calls ++ 
592+                   this . data2  =  this . prop2 
593+                 } , 
594+                 prop2 ( _ )  { 
595+                   prop2Calls ++ 
596+                   this . data1  =  this . prop1 
597+                 } , 
598+               } , 
599+               render ( )  { 
600+                 return  h ( 'div' ,  [ 
601+                   h ( 'h1' ,  this . prop1 ) , 
602+                   h ( 'h1' ,  this . prop2 ) , 
603+                   h ( 'h2' ,  this . data1 ) , 
604+                   h ( 'h2' ,  this . data2 ) , 
605+                 ] ) 
606+               } , 
607+             } ) , 
608+           ) , 
609+         ) , 
610+       ) 
611+       customElements . define ( 'my-async-watch-element' ,  E ) 
612+ 
613+       render ( h ( 'my-async-watch-element' ) ,  container ) 
614+ 
615+       await  new  Promise ( r  =>  setTimeout ( r ) ) 
616+       const  e  =  container . childNodes [ 0 ]  as  VueElement 
617+       expect ( e ) . toBeInstanceOf ( E ) 
618+       expect ( e . _instance ) . toBeTruthy ( ) 
619+       expect ( e . shadowRoot ! . innerHTML ) . toBe ( 
620+         `<div><h1>default1</h1><h1>default2</h1><h2>defaultData1</h2><h2>defaultData2</h2></div>` , 
621+       ) 
622+       expect ( prop1Calls ) . toBe ( 0 ) 
623+       expect ( prop2Calls ) . toBe ( 0 ) 
624+ 
625+       // patch props 
626+       render ( 
627+         h ( 'my-async-watch-element' ,  {  prop1 : 'newValue1' ,  prop2 : 'newValue2'  } ) , 
628+         container , 
629+       ) 
630+       await  nextTick ( ) 
631+       expect ( e . shadowRoot ! . innerHTML ) . toBe ( 
632+         `<div><h1>newValue1</h1><h1>newValue2</h1><h2>newValue1</h2><h2>newValue2</h2></div>` , 
633+       ) 
634+       expect ( prop1Calls ) . toBe ( 1 ) 
635+       expect ( prop2Calls ) . toBe ( 1 ) 
636+ 
637+       // same prop values 
638+       render ( 
639+         h ( 'my-async-watch-element' ,  {  prop1 : 'newValue1' ,  prop2 : 'newValue2'  } ) , 
640+         container , 
641+       ) 
642+       await  nextTick ( ) 
643+       expect ( e . shadowRoot ! . innerHTML ) . toBe ( 
644+         `<div><h1>newValue1</h1><h1>newValue2</h1><h2>newValue1</h2><h2>newValue2</h2></div>` , 
645+       ) 
646+       expect ( prop1Calls ) . toBe ( 1 ) 
647+       expect ( prop2Calls ) . toBe ( 1 ) 
648+ 
649+       // update only prop1 
650+       render ( 
651+         h ( 'my-async-watch-element' ,  {  prop1 : 'newValue3' ,  prop2 : 'newValue2'  } ) , 
652+         container , 
653+       ) 
654+       await  nextTick ( ) 
655+       expect ( e . shadowRoot ! . innerHTML ) . toBe ( 
656+         `<div><h1>newValue3</h1><h1>newValue2</h1><h2>newValue1</h2><h2>newValue2</h2></div>` , 
657+       ) 
658+       expect ( prop1Calls ) . toBe ( 2 ) 
659+       expect ( prop2Calls ) . toBe ( 1 ) 
660+     } ) 
477661  } ) 
478662
479663  describe ( 'attrs' ,  ( )  =>  { 
0 commit comments