@@ -19,7 +19,12 @@ Examples:
1919import { makeTestGroup } from '../../common/framework/test_group.js' ;
2020import { keysOf } from '../../common/util/data_tables.js' ;
2121import { getGPU } from '../../common/util/navigator_gpu.js' ;
22- import { assert , objectEquals , unreachable } from '../../common/util/util.js' ;
22+ import {
23+ assert ,
24+ objectEquals ,
25+ raceWithRejectOnTimeout ,
26+ unreachable ,
27+ } from '../../common/util/util.js' ;
2328import { getDefaultLimitsForDevice , kLimits } from '../capability_info.js' ;
2429import { AllFeaturesMaxLimitsGPUTest , GPUTest } from '../gpu_test.js' ;
2530
@@ -562,3 +567,112 @@ and expect instances of these classes to respond correctly.
562567 const fn = kClassInheritanceTests [ t . params . type ] ;
563568 t . expect ( fn ( ) , fn . toString ( ) ) ;
564569 } ) ;
570+
571+ const kDispatchTests = {
572+ async canPassEventThroughDevice ( t : GPUTest ) {
573+ const result = await raceWithRejectOnTimeout (
574+ new Promise ( resolve => {
575+ t . device . addEventListener ( 'foo' , resolve , { once : true } ) ;
576+ t . device . dispatchEvent ( new Event ( 'foo' ) ) ;
577+ } ) ,
578+ 500 ,
579+ 'timeout'
580+ ) ;
581+ const event = result as Event ;
582+ t . expect ( ( ) => event instanceof Event , 'event' ) ;
583+ t . expect ( ( ) => event . type === 'foo' ) ;
584+ } ,
585+ async canPassCustomEventThroughDevice ( t : GPUTest ) {
586+ const result = await raceWithRejectOnTimeout (
587+ new Promise ( resolve => {
588+ t . device . addEventListener ( 'bar' , resolve , { once : true } ) ;
589+ t . device . dispatchEvent ( new CustomEvent ( 'bar' ) ) ;
590+ } ) ,
591+ 500 ,
592+ 'timeout'
593+ ) ;
594+ const event = result as CustomEvent ;
595+ t . expect ( ( ) => event instanceof CustomEvent ) ;
596+ t . expect ( ( ) => event instanceof Event ) ;
597+ t . expect ( ( ) => event . type === 'bar' ) ;
598+ } ,
599+ async patchingEventTargetAffectsDevice ( t : GPUTest ) {
600+ let addEventListenerWasCalled = false ;
601+ let dispatchEventWasCalled = false ;
602+ let removeEventListenerWasCalled = false ;
603+
604+ // eslint-disable-next-line @typescript-eslint/unbound-method
605+ const origFnAddEventListener = EventTarget . prototype . addEventListener ;
606+ EventTarget . prototype . addEventListener = function (
607+ ...args : Parameters < typeof EventTarget . prototype . addEventListener >
608+ ) {
609+ addEventListenerWasCalled = true ;
610+ return origFnAddEventListener . call ( this , ...args ) ;
611+ } ;
612+
613+ // eslint-disable-next-line @typescript-eslint/unbound-method
614+ const origFnDispatchEvent = EventTarget . prototype . dispatchEvent ;
615+ EventTarget . prototype . dispatchEvent = function ( event : Event ) {
616+ dispatchEventWasCalled = true ;
617+ return origFnDispatchEvent . call ( this , event ) ;
618+ } ;
619+
620+ // eslint-disable-next-line @typescript-eslint/unbound-method
621+ const origFnRemoveEventListener = EventTarget . prototype . removeEventListener ;
622+ EventTarget . prototype . removeEventListener = function (
623+ ...args : Parameters < typeof EventTarget . prototype . removeEventListener >
624+ ) {
625+ removeEventListenerWasCalled = true ;
626+ return origFnRemoveEventListener . call ( this , ...args ) ;
627+ } ;
628+
629+ try {
630+ await raceWithRejectOnTimeout (
631+ new Promise ( resolve => {
632+ t . device . addEventListener ( 'foo' , resolve ) ;
633+ t . device . dispatchEvent ( new Event ( 'foo' ) ) ;
634+ t . device . removeEventListener ( 'foo' , resolve ) ;
635+ } ) ,
636+ 500 ,
637+ 'timeout'
638+ ) ;
639+ } finally {
640+ EventTarget . prototype . addEventListener = origFnAddEventListener ;
641+ EventTarget . prototype . dispatchEvent = origFnDispatchEvent ;
642+ EventTarget . prototype . removeEventListener = origFnRemoveEventListener ;
643+ }
644+ t . expect ( addEventListenerWasCalled , 'overriding EventTarget addEventListener worked' ) ;
645+ t . expect ( dispatchEventWasCalled , 'overriding EventTarget dispatchEvent worked' ) ;
646+ t . expect ( removeEventListenerWasCalled , 'overriding EventTarget removeEventListener worked' ) ;
647+ } ,
648+ async passingGPUUncapturedErrorEventWorksThoughEventTarget ( t : GPUTest ) {
649+ const target = new EventTarget ( ) ;
650+ const result = await raceWithRejectOnTimeout (
651+ new Promise ( resolve => {
652+ target . addEventListener ( 'uncapturederror' , resolve , { once : true } ) ;
653+ target . dispatchEvent (
654+ new GPUUncapturedErrorEvent ( 'uncapturederror' , {
655+ error : new GPUValidationError ( 'test error' ) ,
656+ } )
657+ ) ;
658+ } ) ,
659+ 500 ,
660+ 'timeout'
661+ ) ;
662+ const event = result as GPUUncapturedErrorEvent ;
663+ t . expect ( ( ) => event instanceof GPUUncapturedErrorEvent ) ;
664+ t . expect ( ( ) => event . error instanceof GPUValidationError ) ;
665+ t . expect ( ( ) => event . error . message === 'test error' ) ;
666+ } ,
667+ } as const ;
668+
669+ g . test ( 'device,EventTarget' )
670+ . desc (
671+ `
672+ Test some repercussions of the fact that GPUDevice extends EventTarget
673+ `
674+ )
675+ . params ( u => u . combine ( 'test' , keysOf ( kDispatchTests ) ) )
676+ . fn ( async t => {
677+ await kDispatchTests [ t . params . test ] ( t ) ;
678+ } ) ;
0 commit comments