@@ -253,9 +253,6 @@ export default (Component, options: any = {}) => {
253
253
// onKeyDown => keyDown
254
254
const eventName = _ . camelCase ( listenerName . replace ( 'on' , '' ) )
255
255
256
- // onKeyDown => handleKeyDown
257
- const handlerName = _ . camelCase ( listenerName . replace ( 'on' , 'handle' ) )
258
-
259
256
const handlerSpy = jest . fn ( )
260
257
const props = {
261
258
...requiredProps ,
@@ -286,6 +283,11 @@ export default (Component, options: any = {}) => {
286
283
if ( customHandler ) {
287
284
customHandler ( eventShape )
288
285
} else {
286
+ if ( Component . propTypes [ listenerName ] ) {
287
+ throw new Error (
288
+ `Handler for '${ listenerName } ' is not passed to child event emitter element <${ eventTarget . type ( ) } />` ,
289
+ )
290
+ }
289
291
return
290
292
}
291
293
@@ -298,6 +300,9 @@ export default (Component, options: any = {}) => {
298
300
// ^ was not called once on "blur"
299
301
const leftPad = ' ' . repeat ( info . displayName . length + listenerName . length + 3 )
300
302
303
+ // onKeyDown => handleKeyDown
304
+ const handlerName = _ . camelCase ( listenerName . replace ( 'on' , 'handle' ) )
305
+
301
306
try {
302
307
expect ( handlerSpy ) . toHaveBeenCalled ( )
303
308
} catch ( err ) {
@@ -313,7 +318,10 @@ export default (Component, options: any = {}) => {
313
318
314
319
if ( _ . has ( Component . propTypes , listenerName ) ) {
315
320
expectedArgs = [ eventShape , component . props ( ) ]
316
- errorMessage = 'was not called with (event, data)'
321
+ errorMessage =
322
+ 'was not called with (event, data).\n' +
323
+ `Ensure that 'props' object is passed to '${ listenerName } '\n` +
324
+ `event handler of <${ Component . displayName } />.`
317
325
}
318
326
319
327
// Components should return the event first, then any data
@@ -438,4 +446,37 @@ export default (Component, options: any = {}) => {
438
446
expect ( Component . displayName ) . toEqual ( info . constructorName )
439
447
} )
440
448
} )
449
+
450
+ const validListenerNames = _ . reduce (
451
+ syntheticEvent . types ,
452
+ ( result , { listeners } ) => [ ...result , ...listeners ] ,
453
+ [ ] ,
454
+ )
455
+
456
+ // ---------------------------------------
457
+ // Opt-in tests
458
+ // ---------------------------------------
459
+ return {
460
+ // -------------------------------------
461
+ // Ensure that props are passed as a
462
+ // second argument to event handler
463
+ // -------------------------------------
464
+ hasExtendedHandlerFor ( onEventName ) {
465
+ describe ( `has extended handler for '${ onEventName } ' event` , ( ) => {
466
+ test ( `'${ onEventName } ' is a valid event listener name` , ( ) => {
467
+ expect ( validListenerNames ) . toContain ( onEventName )
468
+ } )
469
+
470
+ test ( `is declared in props` , ( ) => {
471
+ expect ( Component . propTypes [ onEventName ] ) . toBeTruthy ( )
472
+ } )
473
+ } )
474
+
475
+ // -----------------------------------
476
+ // Allows chained calls for optional
477
+ // test suites
478
+ // -----------------------------------
479
+ return this
480
+ } ,
481
+ }
441
482
}
0 commit comments