3
3
// Note: emits and listener fallthrough is tested in
4
4
// ./rendererAttrsFallthrough.spec.ts.
5
5
6
- import { nextTick , onBeforeUnmount } from '../src'
6
+ import { toHandlers } from '@vue/runtime-core'
7
+ import {
8
+ createComponent ,
9
+ defineComponent ,
10
+ nextTick ,
11
+ onBeforeUnmount ,
12
+ } from '../src'
7
13
import { isEmitListener } from '../src/componentEmits'
8
14
import { makeRender } from './_utils'
9
15
10
- const define = makeRender < any > ( )
16
+ const define = makeRender ( )
11
17
12
- describe . todo ( 'component: emit' , ( ) => {
18
+ describe ( 'component: emit' , ( ) => {
13
19
test ( 'trigger handlers' , ( ) => {
14
20
const { render } = define ( {
15
- render ( ) { } ,
16
- setup ( _ : any , { emit } : any ) {
21
+ setup ( _ , { emit } ) {
17
22
emit ( 'foo' )
18
23
emit ( 'bar' )
19
24
emit ( '!baz' )
20
25
} ,
21
26
} )
22
- const onfoo = vi . fn ( )
27
+ const onFoo = vi . fn ( )
23
28
const onBar = vi . fn ( )
24
29
const onBaz = vi . fn ( )
25
30
render ( {
26
- get onfoo ( ) {
27
- return onfoo
28
- } ,
29
- get onBar ( ) {
30
- return onBar
31
- } ,
32
- get [ 'on!baz' ] ( ) {
33
- return onBaz
31
+ onfoo : ( ) => onFoo ,
32
+ onBar : ( ) => onBar ,
33
+ [ 'on!baz' ] : ( ) => onBaz ,
34
+ } )
35
+
36
+ expect ( onFoo ) . not . toHaveBeenCalled ( )
37
+ expect ( onBar ) . toHaveBeenCalled ( )
38
+ expect ( onBaz ) . toHaveBeenCalled ( )
39
+ } )
40
+
41
+ test ( 'trigger dynamic emits' , ( ) => {
42
+ const { render } = define ( {
43
+ setup ( _ , { emit } ) {
44
+ emit ( 'foo' )
45
+ emit ( 'bar' )
46
+ emit ( '!baz' )
34
47
} ,
35
48
} )
49
+ const onFoo = vi . fn ( )
50
+ const onBar = vi . fn ( )
51
+ const onBaz = vi . fn ( )
52
+ render ( ( ) => ( {
53
+ onfoo : onFoo ,
54
+ onBar,
55
+ [ 'on!baz' ] : onBaz ,
56
+ } ) )
36
57
37
- expect ( onfoo ) . not . toHaveBeenCalled ( )
58
+ expect ( onFoo ) . not . toHaveBeenCalled ( )
38
59
expect ( onBar ) . toHaveBeenCalled ( )
39
60
expect ( onBaz ) . toHaveBeenCalled ( )
40
61
} )
41
62
42
63
test ( 'trigger camelCase handler' , ( ) => {
43
64
const { render } = define ( {
44
- render ( ) { } ,
45
- setup ( _ : any , { emit } : any ) {
65
+ setup ( _ , { emit } ) {
46
66
emit ( 'test-event' )
47
67
} ,
48
68
} )
49
69
50
70
const fooSpy = vi . fn ( )
51
- render ( {
52
- get onTestEvent ( ) {
53
- return fooSpy
54
- } ,
55
- } )
71
+ render ( { onTestEvent : ( ) => fooSpy } )
56
72
expect ( fooSpy ) . toHaveBeenCalled ( )
57
73
} )
58
74
59
75
test ( 'trigger kebab-case handler' , ( ) => {
60
76
const { render } = define ( {
61
- render ( ) { } ,
62
- setup ( _ : any , { emit } : any ) {
77
+ setup ( _ , { emit } ) {
63
78
emit ( 'test-event' )
64
79
} ,
65
80
} )
66
81
67
82
const fooSpy = vi . fn ( )
68
- render ( {
69
- get [ 'onTest-event' ] ( ) {
70
- return fooSpy
71
- } ,
72
- } )
83
+ render ( { [ 'onTest-event' ] : ( ) => fooSpy } )
73
84
expect ( fooSpy ) . toHaveBeenCalledTimes ( 1 )
74
85
} )
75
86
76
87
// #3527
77
- test . todo ( 'trigger mixed case handlers' , ( ) => {
88
+ test ( 'trigger mixed case handlers' , ( ) => {
78
89
const { render } = define ( {
79
- render ( ) { } ,
80
- setup ( _ : any , { emit } : any ) {
90
+ setup ( _ , { emit } ) {
81
91
emit ( 'test-event' )
82
92
emit ( 'testEvent' )
83
93
} ,
@@ -86,15 +96,10 @@ describe.todo('component: emit', () => {
86
96
const fooSpy = vi . fn ( )
87
97
const barSpy = vi . fn ( )
88
98
render (
89
- // TODO: impl `toHandlers`
90
- {
91
- get [ 'onTest-Event' ] ( ) {
92
- return fooSpy
93
- } ,
94
- get onTestEvent ( ) {
95
- return barSpy
96
- } ,
97
- } ,
99
+ toHandlers ( {
100
+ 'test-event' : ( ) => fooSpy ,
101
+ testEvent : ( ) => barSpy ,
102
+ } ) ,
98
103
)
99
104
expect ( fooSpy ) . toHaveBeenCalledTimes ( 1 )
100
105
expect ( barSpy ) . toHaveBeenCalledTimes ( 1 )
@@ -103,8 +108,7 @@ describe.todo('component: emit', () => {
103
108
// for v-model:foo-bar usage in DOM templates
104
109
test ( 'trigger hyphenated events for update:xxx events' , ( ) => {
105
110
const { render } = define ( {
106
- render ( ) { } ,
107
- setup ( _ : any , { emit } : any ) {
111
+ setup ( _ , { emit } ) {
108
112
emit ( 'update:fooProp' )
109
113
emit ( 'update:barProp' )
110
114
} ,
@@ -113,12 +117,8 @@ describe.todo('component: emit', () => {
113
117
const fooSpy = vi . fn ( )
114
118
const barSpy = vi . fn ( )
115
119
render ( {
116
- get [ 'onUpdate:fooProp' ] ( ) {
117
- return fooSpy
118
- } ,
119
- get [ 'onUpdate:bar-prop' ] ( ) {
120
- return barSpy
121
- } ,
120
+ [ 'onUpdate:fooProp' ] : ( ) => fooSpy ,
121
+ [ 'onUpdate:bar-prop' ] : ( ) => barSpy ,
122
122
} )
123
123
124
124
expect ( fooSpy ) . toHaveBeenCalled ( )
@@ -127,38 +127,57 @@ describe.todo('component: emit', () => {
127
127
128
128
test ( 'should trigger array of listeners' , async ( ) => {
129
129
const { render } = define ( {
130
- render ( ) { } ,
131
- setup ( _ : any , { emit } : any ) {
130
+ setup ( _ , { emit } ) {
132
131
emit ( 'foo' , 1 )
133
132
} ,
134
133
} )
135
134
136
135
const fn1 = vi . fn ( )
137
136
const fn2 = vi . fn ( )
138
137
139
- render ( {
140
- onFoo : ( ) => [ fn1 , fn2 ] ,
141
- } )
138
+ render ( { onFoo : ( ) => [ fn1 , fn2 ] } )
142
139
expect ( fn1 ) . toHaveBeenCalledTimes ( 1 )
143
140
expect ( fn1 ) . toHaveBeenCalledWith ( 1 )
144
141
expect ( fn2 ) . toHaveBeenCalledTimes ( 1 )
145
142
expect ( fn2 ) . toHaveBeenCalledWith ( 1 )
146
143
} )
147
144
148
- test . todo ( 'warning for undeclared event (array)' , ( ) => {
149
- // TODO: warning
145
+ test ( 'warning for undeclared event (array)' , ( ) => {
146
+ const { render } = define ( {
147
+ emits : [ 'foo' ] ,
148
+
149
+ setup ( _ , { emit } ) {
150
+ emit ( 'bar' )
151
+ } ,
152
+ } )
153
+ render ( )
154
+ expect (
155
+ `Component emitted event "bar" but it is neither declared` ,
156
+ ) . toHaveBeenWarned ( )
150
157
} )
151
158
152
- test . todo ( 'warning for undeclared event (object)' , ( ) => {
153
- // TODO: warning
159
+ test ( 'warning for undeclared event (object)' , ( ) => {
160
+ const { render } = define ( {
161
+ emits : {
162
+ foo : null ,
163
+ } ,
164
+
165
+ setup ( _ , { emit } ) {
166
+ emit ( 'bar' )
167
+ } ,
168
+ } )
169
+ render ( )
170
+ expect (
171
+ `Component emitted event "bar" but it is neither declared` ,
172
+ ) . toHaveBeenWarned ( )
154
173
} )
155
174
156
175
test ( 'should not warn if has equivalent onXXX prop' , ( ) => {
157
176
define ( {
158
177
props : [ 'onFoo' ] ,
159
178
emits : [ ] ,
160
- render ( ) { } ,
161
- setup ( _ : any , { emit } : any ) {
179
+
180
+ setup ( _ , { emit } ) {
162
181
emit ( 'foo' )
163
182
} ,
164
183
} ) . render ( )
@@ -182,12 +201,11 @@ describe.todo('component: emit', () => {
182
201
183
202
test ( '.once' , ( ) => {
184
203
const { render } = define ( {
185
- render ( ) { } ,
186
204
emits : {
187
205
foo : null ,
188
206
bar : null ,
189
207
} ,
190
- setup ( _ : any , { emit } : any ) {
208
+ setup ( _ , { emit } ) {
191
209
emit ( 'foo' )
192
210
emit ( 'foo' )
193
211
emit ( 'bar' )
@@ -197,71 +215,49 @@ describe.todo('component: emit', () => {
197
215
const fn = vi . fn ( )
198
216
const barFn = vi . fn ( )
199
217
render ( {
200
- get onFooOnce ( ) {
201
- return fn
202
- } ,
203
- get onBarOnce ( ) {
204
- return barFn
205
- } ,
218
+ onFooOnce : ( ) => fn ,
219
+ onBarOnce : ( ) => barFn ,
206
220
} )
207
221
expect ( fn ) . toHaveBeenCalledTimes ( 1 )
208
222
expect ( barFn ) . toHaveBeenCalledTimes ( 1 )
209
223
} )
210
224
211
225
test ( '.once with normal listener of the same name' , ( ) => {
212
226
const { render } = define ( {
213
- render ( ) { } ,
214
227
emits : {
215
228
foo : null ,
216
229
} ,
217
- setup ( _ : any , { emit } : any ) {
230
+ setup ( _ , { emit } ) {
218
231
emit ( 'foo' )
219
232
emit ( 'foo' )
220
233
} ,
221
234
} )
222
235
const onFoo = vi . fn ( )
223
236
const onFooOnce = vi . fn ( )
224
237
render ( {
225
- get onFoo ( ) {
226
- return onFoo
227
- } ,
228
- get onFooOnce ( ) {
229
- return onFooOnce
230
- } ,
238
+ onFoo : ( ) => onFoo ,
239
+ onFooOnce : ( ) => onFooOnce ,
231
240
} )
232
241
expect ( onFoo ) . toHaveBeenCalledTimes ( 2 )
233
242
expect ( onFooOnce ) . toHaveBeenCalledTimes ( 1 )
234
243
} )
235
244
236
245
test ( '.number modifier should work with v-model on component' , ( ) => {
237
246
const { render } = define ( {
238
- render ( ) { } ,
239
- setup ( _ : any , { emit } : any ) {
247
+ setup ( _ , { emit } ) {
240
248
emit ( 'update:modelValue' , '1' )
241
249
emit ( 'update:foo' , '2' )
242
250
} ,
243
251
} )
244
252
const fn1 = vi . fn ( )
245
253
const fn2 = vi . fn ( )
246
254
render ( {
247
- modelValue ( ) {
248
- return null
249
- } ,
250
- modelModifiers ( ) {
251
- return { number : true }
252
- } ,
253
- [ 'onUpdate:modelValue' ] ( ) {
254
- return fn1
255
- } ,
256
- foo ( ) {
257
- return null
258
- } ,
259
- fooModifiers ( ) {
260
- return { number : true }
261
- } ,
262
- [ 'onUpdate:foo' ] ( ) {
263
- return fn2
264
- } ,
255
+ modelValue : ( ) => null ,
256
+ modelModifiers : ( ) => ( { number : true } ) ,
257
+ [ 'onUpdate:modelValue' ] : ( ) => fn1 ,
258
+ foo : ( ) => null ,
259
+ fooModifiers : ( ) => ( { number : true } ) ,
260
+ [ 'onUpdate:foo' ] : ( ) => fn2 ,
265
261
} )
266
262
expect ( fn1 ) . toHaveBeenCalledTimes ( 1 )
267
263
expect ( fn1 ) . toHaveBeenCalledWith ( 1 )
@@ -271,8 +267,7 @@ describe.todo('component: emit', () => {
271
267
272
268
test ( '.trim modifier should work with v-model on component' , ( ) => {
273
269
const { render } = define ( {
274
- render ( ) { } ,
275
- setup ( _ : any , { emit } : any ) {
270
+ setup ( _ , { emit } ) {
276
271
emit ( 'update:modelValue' , ' one ' )
277
272
emit ( 'update:foo' , ' two ' )
278
273
} ,
@@ -307,8 +302,7 @@ describe.todo('component: emit', () => {
307
302
308
303
test ( '.trim and .number modifiers should work with v-model on component' , ( ) => {
309
304
const { render } = define ( {
310
- render ( ) { } ,
311
- setup ( _ : any , { emit } : any ) {
305
+ setup ( _ , { emit } ) {
312
306
emit ( 'update:modelValue' , ' +01.2 ' )
313
307
emit ( 'update:foo' , ' 1 ' )
314
308
} ,
@@ -343,8 +337,7 @@ describe.todo('component: emit', () => {
343
337
344
338
test ( 'only trim string parameter when work with v-model on component' , ( ) => {
345
339
const { render } = define ( {
346
- render ( ) { } ,
347
- setup ( _ : any , { emit } : any ) {
340
+ setup ( _ , { emit } ) {
348
341
emit ( 'update:modelValue' , ' foo ' , { bar : ' bar ' } )
349
342
} ,
350
343
} )
@@ -395,20 +388,21 @@ describe.todo('component: emit', () => {
395
388
396
389
test ( 'does not emit after unmount' , async ( ) => {
397
390
const fn = vi . fn ( )
398
- const { app } = define ( {
391
+
392
+ const Foo = defineComponent ( {
399
393
emits : [ 'closing' ] ,
400
- setup ( _ : any , { emit } : any ) {
394
+ setup ( _ , { emit } ) {
401
395
onBeforeUnmount ( async ( ) => {
402
396
await nextTick ( )
403
397
emit ( 'closing' , true )
404
398
} )
405
399
} ,
406
- render ( ) { } ,
407
- } ) . render ( {
408
- get onClosing ( ) {
409
- return fn
410
- } ,
411
400
} )
401
+
402
+ const { app } = define ( ( ) =>
403
+ createComponent ( Foo , { onClosing : ( ) => fn } ) ,
404
+ ) . render ( )
405
+
412
406
await nextTick ( )
413
407
app . unmount ( )
414
408
await nextTick ( )
0 commit comments