@@ -708,6 +708,101 @@ describe('defineCustomElement', () => {
708
708
`<div>changedA! changedB!</div>` ,
709
709
)
710
710
} )
711
+
712
+ // #13212
713
+ test ( 'inherited from app context within nested elements' , async ( ) => {
714
+ const outerValues : ( string | undefined ) [ ] = [ ]
715
+ const innerValues : ( string | undefined ) [ ] = [ ]
716
+ const innerChildValues : ( string | undefined ) [ ] = [ ]
717
+
718
+ const Outer = defineCustomElement (
719
+ {
720
+ setup ( ) {
721
+ outerValues . push (
722
+ inject < string > ( 'shared' ) ,
723
+ inject < string > ( 'outer' ) ,
724
+ inject < string > ( 'inner' ) ,
725
+ )
726
+ } ,
727
+ render ( ) {
728
+ return h ( 'div' , [ renderSlot ( this . $slots , 'default' ) ] )
729
+ } ,
730
+ } ,
731
+ {
732
+ configureApp ( app ) {
733
+ app . provide ( 'shared' , 'shared' )
734
+ app . provide ( 'outer' , 'outer' )
735
+ } ,
736
+ } ,
737
+ )
738
+
739
+ const Inner = defineCustomElement (
740
+ {
741
+ setup ( ) {
742
+ // ensure values are not self-injected
743
+ provide ( 'inner' , 'inner-child' )
744
+
745
+ innerValues . push (
746
+ inject < string > ( 'shared' ) ,
747
+ inject < string > ( 'outer' ) ,
748
+ inject < string > ( 'inner' ) ,
749
+ )
750
+ } ,
751
+ render ( ) {
752
+ return h ( 'div' , [ renderSlot ( this . $slots , 'default' ) ] )
753
+ } ,
754
+ } ,
755
+ {
756
+ configureApp ( app ) {
757
+ app . provide ( 'outer' , 'override-outer' )
758
+ app . provide ( 'inner' , 'inner' )
759
+ } ,
760
+ } ,
761
+ )
762
+
763
+ const InnerChild = defineCustomElement ( {
764
+ setup ( ) {
765
+ innerChildValues . push (
766
+ inject < string > ( 'shared' ) ,
767
+ inject < string > ( 'outer' ) ,
768
+ inject < string > ( 'inner' ) ,
769
+ )
770
+ } ,
771
+ render ( ) {
772
+ return h ( 'div' )
773
+ } ,
774
+ } )
775
+
776
+ customElements . define ( 'provide-from-app-outer' , Outer )
777
+ customElements . define ( 'provide-from-app-inner' , Inner )
778
+ customElements . define ( 'provide-from-app-inner-child' , InnerChild )
779
+
780
+ container . innerHTML =
781
+ '<provide-from-app-outer>' +
782
+ '<provide-from-app-inner>' +
783
+ '<provide-from-app-inner-child></provide-from-app-inner-child>' +
784
+ '</provide-from-app-inner>' +
785
+ '</provide-from-app-outer>'
786
+
787
+ const outer = container . childNodes [ 0 ] as VueElement
788
+ expect ( outer . shadowRoot ! . innerHTML ) . toBe ( '<div><slot></slot></div>' )
789
+
790
+ expect ( '[Vue warn]: injection "inner" not found.' ) . toHaveBeenWarnedTimes (
791
+ 1 ,
792
+ )
793
+ expect (
794
+ '[Vue warn]: App already provides property with key "outer" inherited from its parent element. ' +
795
+ 'It will be overwritten with the new value.' ,
796
+ ) . toHaveBeenWarnedTimes ( 1 )
797
+
798
+ expect ( outerValues ) . toEqual ( [ 'shared' , 'outer' , undefined ] )
799
+ expect ( innerValues ) . toEqual ( [ 'shared' , 'override-outer' , 'inner' ] )
800
+ expect ( innerChildValues ) . toEqual ( [
801
+ 'shared' ,
802
+ 'override-outer' ,
803
+ 'inner-child' ,
804
+ ] )
805
+ } )
711
806
} )
712
807
713
808
describe ( 'styles' , ( ) => {
0 commit comments