1
- import { defineComponent , FunctionalComponent , h , SetupContext } from 'vue'
1
+ import {
2
+ defineComponent ,
3
+ FunctionalComponent ,
4
+ getCurrentInstance ,
5
+ h ,
6
+ SetupContext
7
+ } from 'vue'
2
8
import { Vue } from 'vue-class-component'
3
9
4
10
import { mount } from '../src'
@@ -78,23 +84,73 @@ describe('emitted', () => {
78
84
expect ( wrapper . emitted ( ) . hello [ 1 ] ) . toEqual ( [ 'foo' , 'bar' ] )
79
85
} )
80
86
81
- it ( 'should not propagate child events' , ( ) => {
87
+ it ( 'should propagate child native events' , async ( ) => {
82
88
const Child = defineComponent ( {
83
- name : 'Child' ,
84
- setup ( props , { emit } ) {
89
+ name : 'Button' ,
90
+ setup ( props ) {
91
+ return ( ) => h ( 'div' , [ h ( 'input' ) ] )
92
+ }
93
+ } )
94
+
95
+ const Parent = defineComponent ( {
96
+ name : 'Parent' ,
97
+ setup ( ) {
85
98
return ( ) =>
86
99
h ( 'div' , [
87
- h ( 'button' , { onClick : ( ) => emit ( 'hello' , 'foo' , 'bar' ) } )
100
+ h ( Child , {
101
+ onClick : ( event : Event ) => event . stopPropagation ( )
102
+ } )
88
103
] )
89
104
}
90
105
} )
91
106
107
+ const GrandParent : FunctionalComponent < { level : number } > = (
108
+ props ,
109
+ ctx
110
+ ) => {
111
+ return h ( `h${ props . level } ` , [ h ( Parent ) ] )
112
+ }
113
+
114
+ const wrapper = mount ( GrandParent )
115
+ const parentWrapper = wrapper . findComponent ( Parent )
116
+ const childWrapper = wrapper . findComponent ( Child )
117
+ const input = wrapper . find ( 'input' )
118
+
119
+ expect ( wrapper . emitted ( ) ) . toEqual ( { } )
120
+ expect ( parentWrapper . emitted ( ) ) . toEqual ( { } )
121
+ expect ( childWrapper . emitted ( ) ) . toEqual ( { } )
122
+
123
+ await input . trigger ( 'click' )
124
+
125
+ // Propagation should stop at Parent
126
+ expect ( childWrapper . emitted ( ) . click ) . toHaveLength ( 1 )
127
+ expect ( parentWrapper . emitted ( ) . click ) . toEqual ( undefined )
128
+ expect ( wrapper . emitted ( ) . click ) . toEqual ( undefined )
129
+
130
+ input . setValue ( 'hey' )
131
+
132
+ expect ( childWrapper . emitted ( ) . input ) . toHaveLength ( 1 )
133
+ expect ( parentWrapper . emitted ( ) . input ) . toHaveLength ( 1 )
134
+ expect ( wrapper . emitted ( ) . input ) . toHaveLength ( 1 )
135
+ } )
136
+
137
+ it ( 'should not propagate child custom events' , ( ) => {
138
+ const Child = defineComponent ( {
139
+ name : 'Child' ,
140
+ emits : [ 'hi' ] ,
141
+ setup ( props , { emit } ) {
142
+ return ( ) =>
143
+ h ( 'div' , [ h ( 'button' , { onClick : ( ) => emit ( 'hi' , 'foo' , 'bar' ) } ) ] )
144
+ }
145
+ } )
146
+
92
147
const Parent = defineComponent ( {
93
148
name : 'Parent' ,
149
+ emits : [ 'hello' ] ,
94
150
setup ( props , { emit } ) {
95
151
return ( ) =>
96
152
h ( Child , {
97
- onHello : ( ...events : unknown [ ] ) => emit ( 'parent ' , ...events )
153
+ onHi : ( ...events : unknown [ ] ) => emit ( 'hello ' , ...events )
98
154
} )
99
155
}
100
156
} )
@@ -105,14 +161,18 @@ describe('emitted', () => {
105
161
expect ( childWrapper . emitted ( ) ) . toEqual ( { } )
106
162
107
163
wrapper . find ( 'button' ) . trigger ( 'click' )
108
- expect ( wrapper . emitted ( ) . parent [ 0 ] ) . toEqual ( [ 'foo' , 'bar' ] )
109
- expect ( wrapper . emitted ( ) . hello ) . toEqual ( undefined )
110
- expect ( childWrapper . emitted ( ) . hello [ 0 ] ) . toEqual ( [ 'foo' , 'bar' ] )
111
164
165
+ // Parent should emit custom event 'hello' but not 'hi'
166
+ expect ( wrapper . emitted ( ) . hello [ 0 ] ) . toEqual ( [ 'foo' , 'bar' ] )
167
+ expect ( wrapper . emitted ( ) . hi ) . toEqual ( undefined )
168
+ // Child should emit custom event 'hi'
169
+ expect ( childWrapper . emitted ( ) . hi [ 0 ] ) . toEqual ( [ 'foo' , 'bar' ] )
170
+
171
+ // Additional events should accumulate in the same format
112
172
wrapper . find ( 'button' ) . trigger ( 'click' )
113
- expect ( wrapper . emitted ( ) . parent [ 1 ] ) . toEqual ( [ 'foo' , 'bar' ] )
114
- expect ( wrapper . emitted ( ) . hello ) . toEqual ( undefined )
115
- expect ( childWrapper . emitted ( ) . hello [ 1 ] ) . toEqual ( [ 'foo' , 'bar' ] )
173
+ expect ( wrapper . emitted ( ) . hello [ 1 ] ) . toEqual ( [ 'foo' , 'bar' ] )
174
+ expect ( wrapper . emitted ( ) . hi ) . toEqual ( undefined )
175
+ expect ( childWrapper . emitted ( ) . hi [ 1 ] ) . toEqual ( [ 'foo' , 'bar' ] )
116
176
} )
117
177
118
178
it ( 'should allow passing the name of an event' , ( ) => {
@@ -189,4 +249,29 @@ describe('emitted', () => {
189
249
const wrapper = mount ( Comp )
190
250
expect ( wrapper . emitted ( ) . foo ) . toBeTruthy ( )
191
251
} )
252
+
253
+ it ( 'captures composition event' , async ( ) => {
254
+ const useCommonBindings = ( ) => {
255
+ const onCompositionStart = ( evt : CompositionEvent ) => {
256
+ const instance = getCurrentInstance ( ) !
257
+ instance . emit ( 'compositionStart' , evt )
258
+ }
259
+ return { onCompositionStart }
260
+ }
261
+ const IxInput = defineComponent ( {
262
+ setup ( ) {
263
+ return useCommonBindings ( )
264
+ } ,
265
+ template : `<input @compositionstart="(evt) => $emit('compositionStart', evt)" />`
266
+ } )
267
+
268
+ const wrapper = mount ( {
269
+ components : { IxInput } ,
270
+ template : `<ix-input />`
271
+ } )
272
+
273
+ await wrapper . find ( 'input' ) . trigger ( 'compositionstart' )
274
+
275
+ expect ( wrapper . emitted ( ) . compositionstart ) . not . toBe ( undefined )
276
+ } )
192
277
} )
0 commit comments