@@ -155,4 +155,62 @@ test.describe("_hyperscript bootstrapping", () => {
155155 await find ( 'div' ) . dispatchEvent ( 'click' ) ;
156156 await expect ( find ( 'div' ) ) . toHaveClass ( / b a r / ) ;
157157 } ) ;
158+
159+ test ( "cleanup removes event listeners on the element" , async ( { html, find, evaluate} ) => {
160+ await html ( "<div _='on click add .foo'></div>" ) ;
161+ await find ( 'div' ) . dispatchEvent ( 'click' ) ;
162+ await expect ( find ( 'div' ) ) . toHaveClass ( / f o o / ) ;
163+
164+ // Cleanup and verify listener is gone
165+ await evaluate ( ( ) => {
166+ var div = document . querySelector ( '#work-area div' ) ;
167+ _hyperscript . cleanup ( div ) ;
168+ div . classList . remove ( 'foo' ) ;
169+ div . click ( ) ;
170+ } ) ;
171+ await expect ( find ( 'div' ) ) . not . toHaveClass ( / f o o / ) ;
172+ } ) ;
173+
174+ test ( "cleanup removes cross-element event listeners" , async ( { html, find, evaluate} ) => {
175+ await html ( "<div id='source'></div><div id='target' _='on click from #source add .foo'></div>" ) ;
176+
177+ // Verify the cross-element listener works
178+ await find ( '#source' ) . dispatchEvent ( 'click' ) ;
179+ await expect ( find ( '#target' ) ) . toHaveClass ( / f o o / ) ;
180+
181+ // Cleanup target and verify listener on source is removed
182+ var listenerRemoved = await evaluate ( ( ) => {
183+ var source = document . getElementById ( 'source' ) ;
184+ var target = document . getElementById ( 'target' ) ;
185+ _hyperscript . cleanup ( target ) ;
186+ target . classList . remove ( 'foo' ) ;
187+ source . click ( ) ;
188+ // If cleanup worked, target should NOT get .foo again
189+ return ! target . classList . contains ( 'foo' ) ;
190+ } ) ;
191+ expect ( listenerRemoved ) . toBe ( true ) ;
192+ } ) ;
193+
194+ test ( "cleanup tracks listeners in elt._hyperscript" , async ( { html, find, evaluate} ) => {
195+ await html ( "<div _='on click add .foo'></div>" ) ;
196+ var info = await evaluate ( ( ) => {
197+ var div = document . querySelector ( '#work-area div' ) ;
198+ return {
199+ hasListeners : Array . isArray ( div . _hyperscript . listeners ) ,
200+ listenerCount : div . _hyperscript . listeners . length ,
201+ } ;
202+ } ) ;
203+ expect ( info . hasListeners ) . toBe ( true ) ;
204+ expect ( info . listenerCount ) . toBeGreaterThan ( 0 ) ;
205+ } ) ;
206+
207+ test ( "cleanup clears elt._hyperscript" , async ( { html, find, evaluate} ) => {
208+ await html ( "<div _='on click add .foo'></div>" ) ;
209+ var hasState = await evaluate ( ( ) => {
210+ var div = document . querySelector ( '#work-area div' ) ;
211+ _hyperscript . cleanup ( div ) ;
212+ return '_hyperscript' in div ;
213+ } ) ;
214+ expect ( hasState ) . toBe ( false ) ;
215+ } ) ;
158216} ) ;
0 commit comments