1
1
/* eslint-env qunit */
2
+ import document from 'global/document' ;
3
+ import window from 'global/window' ;
2
4
import sinon from 'sinon' ;
3
5
import evented from '../../../src/js/mixins/evented' ;
4
6
import * as Dom from '../../../src/js/utils/dom' ;
@@ -11,6 +13,20 @@ const errors = {
11
13
target : new Error ( 'Invalid target; must be a DOM node or evented object.' )
12
14
} ;
13
15
16
+ // Cross-browser event creation.
17
+ const createEvent = ( type ) => {
18
+ let event ;
19
+
20
+ try {
21
+ event = new window . Event ( type ) ;
22
+ } catch ( x ) {
23
+ event = document . createEvent ( 'Event' ) ;
24
+ event . initEvent ( type , true , true ) ;
25
+ }
26
+
27
+ return event ;
28
+ } ;
29
+
14
30
const validateListenerCall = ( call , thisValue , eventExpectation ) => {
15
31
const eventActual = call . args [ 0 ] ;
16
32
@@ -31,7 +47,13 @@ QUnit.module('mixins: evented', {
31
47
} ,
32
48
33
49
afterEach ( ) {
34
- Object . keys ( this . targets ) . forEach ( k => this . targets [ k ] . trigger ( 'dispose' ) ) ;
50
+ Object . keys ( this . targets ) . forEach ( k => {
51
+ if ( typeof this . targets [ k ] . trigger === 'function' ) {
52
+ this . targets [ k ] . trigger ( 'dispose' ) ;
53
+ } else {
54
+ this . targets [ k ] = null ;
55
+ }
56
+ } ) ;
35
57
}
36
58
} ) ;
37
59
@@ -61,7 +83,7 @@ QUnit.test('evented() with custom element', function(assert) {
61
83
) ;
62
84
} ) ;
63
85
64
- QUnit . test ( 'on() and one() errors ' , function ( assert ) {
86
+ QUnit . test ( 'on() and one() error states ' , function ( assert ) {
65
87
const target = this . targets . a = evented ( { } ) ;
66
88
67
89
[ 'on' , 'one' ] . forEach ( method => {
@@ -74,7 +96,7 @@ QUnit.test('on() and one() errors', function(assert) {
74
96
} ) ;
75
97
} ) ;
76
98
77
- QUnit . test ( 'off() errors ' , function ( assert ) {
99
+ QUnit . test ( 'off() error states ' , function ( assert ) {
78
100
const target = this . targets . a = evented ( { } ) ;
79
101
80
102
// An invalid event actually causes an invalid target error because it
@@ -86,7 +108,7 @@ QUnit.test('off() errors', function(assert) {
86
108
assert . throws ( ( ) => target . off ( evented ( { } ) , 'x' , null ) , errors . listener , 'the expected error is thrown' ) ;
87
109
} ) ;
88
110
89
- QUnit . test ( 'on() can add a listener to one event type on this object ' , function ( assert ) {
111
+ QUnit . test ( 'on() can add a listener to one event type on itself ' , function ( assert ) {
90
112
const a = this . targets . a = evented ( { } ) ;
91
113
const spy = sinon . spy ( ) ;
92
114
@@ -101,7 +123,7 @@ QUnit.test('on() can add a listener to one event type on this object', function(
101
123
} ) ;
102
124
} ) ;
103
125
104
- QUnit . test ( 'on() can add a listener to an array of event types on this object ' , function ( assert ) {
126
+ QUnit . test ( 'on() can add a listener to an array of event types on itself ' , function ( assert ) {
105
127
const a = this . targets . a = evented ( { } ) ;
106
128
const spy = sinon . spy ( ) ;
107
129
@@ -122,7 +144,7 @@ QUnit.test('on() can add a listener to an array of event types on this object',
122
144
} ) ;
123
145
} ) ;
124
146
125
- QUnit . test ( 'one() can add a listener to one event type on this object ' , function ( assert ) {
147
+ QUnit . test ( 'one() can add a listener to one event type on itself ' , function ( assert ) {
126
148
const a = this . targets . a = evented ( { } ) ;
127
149
const spy = sinon . spy ( ) ;
128
150
@@ -138,7 +160,7 @@ QUnit.test('one() can add a listener to one event type on this object', function
138
160
} ) ;
139
161
} ) ;
140
162
141
- QUnit . test ( 'one() can add a listener to an array of event types on this object ' , function ( assert ) {
163
+ QUnit . test ( 'one() can add a listener to an array of event types on itself ' , function ( assert ) {
142
164
const a = this . targets . a = evented ( { } ) ;
143
165
const spy = sinon . spy ( ) ;
144
166
@@ -161,7 +183,7 @@ QUnit.test('one() can add a listener to an array of event types on this object',
161
183
} ) ;
162
184
} ) ;
163
185
164
- QUnit . test ( 'on() can add a listener to one event type on a different target object' , function ( assert ) {
186
+ QUnit . test ( 'on() can add a listener to one event type on a different evented object' , function ( assert ) {
165
187
const a = this . targets . a = evented ( { } ) ;
166
188
const b = this . targets . b = evented ( { } ) ;
167
189
const spy = sinon . spy ( ) ;
@@ -180,7 +202,47 @@ QUnit.test('on() can add a listener to one event type on a different target obje
180
202
} ) ;
181
203
} ) ;
182
204
183
- QUnit . test ( 'on() can add a listener to an array of event types on a different target object' , function ( assert ) {
205
+ QUnit . test ( 'on() can add a listener to one event type on a node object' , function ( assert ) {
206
+ const a = this . targets . a = evented ( { } ) ;
207
+ const b = this . targets . b = Dom . createEl ( 'div' ) ;
208
+ const spy = sinon . spy ( ) ;
209
+ const event = createEvent ( 'x' ) ;
210
+
211
+ a . on ( b , 'x' , spy ) ;
212
+ b . dispatchEvent ( event ) ;
213
+
214
+ // Make sure we aren't magically binding a listener to "a".
215
+ a . trigger ( 'x' ) ;
216
+
217
+ assert . strictEqual ( spy . callCount , 1 , 'the listener was called the expected number of times' ) ;
218
+
219
+ validateListenerCall ( spy . getCall ( 0 ) , a , {
220
+ type : 'x' ,
221
+ target : b
222
+ } ) ;
223
+ } ) ;
224
+
225
+ QUnit . test ( 'on() can add a listener to one event type on the window object' , function ( assert ) {
226
+ const a = this . targets . a = evented ( { } ) ;
227
+ const b = this . targets . b = window ;
228
+ const spy = sinon . spy ( ) ;
229
+ const event = createEvent ( 'x' ) ;
230
+
231
+ a . on ( b , 'x' , spy ) ;
232
+ b . dispatchEvent ( event ) ;
233
+
234
+ // Make sure we aren't magically binding a listener to "a".
235
+ a . trigger ( 'x' ) ;
236
+
237
+ assert . strictEqual ( spy . callCount , 1 , 'the listener was called the expected number of times' ) ;
238
+
239
+ validateListenerCall ( spy . getCall ( 0 ) , a , {
240
+ type : 'x' ,
241
+ target : b
242
+ } ) ;
243
+ } ) ;
244
+
245
+ QUnit . test ( 'on() can add a listener to an array of event types on a different evented object' , function ( assert ) {
184
246
const a = this . targets . a = evented ( { } ) ;
185
247
const b = this . targets . b = evented ( { } ) ;
186
248
const spy = sinon . spy ( ) ;
@@ -206,13 +268,70 @@ QUnit.test('on() can add a listener to an array of event types on a different ta
206
268
} ) ;
207
269
} ) ;
208
270
209
- QUnit . test ( 'one() can add a listener to one event type on a different target object' , function ( assert ) {
271
+ QUnit . test ( 'on() can add a listener to an array of event types on a node object' , function ( assert ) {
272
+ const a = this . targets . a = evented ( { } ) ;
273
+ const b = this . targets . b = Dom . createEl ( 'div' ) ;
274
+ const spy = sinon . spy ( ) ;
275
+ const x = createEvent ( 'x' ) ;
276
+ const y = createEvent ( 'y' ) ;
277
+
278
+ a . on ( b , [ 'x' , 'y' ] , spy ) ;
279
+ b . dispatchEvent ( x ) ;
280
+ b . dispatchEvent ( y ) ;
281
+
282
+ // Make sure we aren't magically binding a listener to "a".
283
+ a . trigger ( 'x' ) ;
284
+ a . trigger ( 'y' ) ;
285
+
286
+ assert . strictEqual ( spy . callCount , 2 , 'the listener was called the expected number of times' ) ;
287
+
288
+ validateListenerCall ( spy . getCall ( 0 ) , a , {
289
+ type : 'x' ,
290
+ target : b
291
+ } ) ;
292
+
293
+ validateListenerCall ( spy . getCall ( 1 ) , a , {
294
+ type : 'y' ,
295
+ target : b
296
+ } ) ;
297
+ } ) ;
298
+
299
+ QUnit . test ( 'on() can add a listener to an array of event types on the window object' , function ( assert ) {
300
+ const a = this . targets . a = evented ( { } ) ;
301
+ const b = this . targets . b = window ;
302
+ const spy = sinon . spy ( ) ;
303
+ const x = createEvent ( 'x' ) ;
304
+ const y = createEvent ( 'y' ) ;
305
+
306
+ a . on ( b , [ 'x' , 'y' ] , spy ) ;
307
+ b . dispatchEvent ( x ) ;
308
+ b . dispatchEvent ( y ) ;
309
+
310
+ // Make sure we aren't magically binding a listener to "a".
311
+ a . trigger ( 'x' ) ;
312
+ a . trigger ( 'y' ) ;
313
+
314
+ assert . strictEqual ( spy . callCount , 2 , 'the listener was called the expected number of times' ) ;
315
+
316
+ validateListenerCall ( spy . getCall ( 0 ) , a , {
317
+ type : 'x' ,
318
+ target : b
319
+ } ) ;
320
+
321
+ validateListenerCall ( spy . getCall ( 1 ) , a , {
322
+ type : 'y' ,
323
+ target : b
324
+ } ) ;
325
+ } ) ;
326
+
327
+ QUnit . test ( 'one() can add a listener to one event type on a different evented object' , function ( assert ) {
210
328
const a = this . targets . a = evented ( { } ) ;
211
329
const b = this . targets . b = evented ( { } ) ;
212
330
const spy = sinon . spy ( ) ;
213
331
214
332
a . one ( b , 'x' , spy ) ;
215
333
b . trigger ( 'x' ) ;
334
+ b . trigger ( 'x' ) ;
216
335
217
336
// Make sure we aren't magically binding a listener to "a".
218
337
a . trigger ( 'x' ) ;
@@ -225,9 +344,49 @@ QUnit.test('one() can add a listener to one event type on a different target obj
225
344
} ) ;
226
345
} ) ;
227
346
228
- // The behavior here unfortunately differs from the identical case where "a"
229
- // listens to itself. This is something that should be resolved...
230
- QUnit . test ( 'one() can add a listener to an array of event types on a different target object' , function ( assert ) {
347
+ QUnit . test ( 'one() can add a listener to one event type on a node object' , function ( assert ) {
348
+ const a = this . targets . a = evented ( { } ) ;
349
+ const b = this . targets . b = Dom . createEl ( 'div' ) ;
350
+ const spy = sinon . spy ( ) ;
351
+ const event = createEvent ( 'x' ) ;
352
+
353
+ a . one ( b , 'x' , spy ) ;
354
+ b . dispatchEvent ( event ) ;
355
+ b . dispatchEvent ( event ) ;
356
+
357
+ // Make sure we aren't magically binding a listener to "a".
358
+ a . trigger ( 'x' ) ;
359
+
360
+ assert . strictEqual ( spy . callCount , 1 , 'the listener was called the expected number of times' ) ;
361
+
362
+ validateListenerCall ( spy . getCall ( 0 ) , a , {
363
+ type : 'x' ,
364
+ target : b
365
+ } ) ;
366
+ } ) ;
367
+
368
+ QUnit . test ( 'one() can add a listener to one event type on the window object' , function ( assert ) {
369
+ const a = this . targets . a = evented ( { } ) ;
370
+ const b = this . targets . b = window ;
371
+ const spy = sinon . spy ( ) ;
372
+ const event = createEvent ( 'x' ) ;
373
+
374
+ a . one ( b , 'x' , spy ) ;
375
+ b . dispatchEvent ( event ) ;
376
+ b . dispatchEvent ( event ) ;
377
+
378
+ // Make sure we aren't magically binding a listener to "a".
379
+ a . trigger ( 'x' ) ;
380
+
381
+ assert . strictEqual ( spy . callCount , 1 , 'the listener was called the expected number of times' ) ;
382
+
383
+ validateListenerCall ( spy . getCall ( 0 ) , a , {
384
+ type : 'x' ,
385
+ target : b
386
+ } ) ;
387
+ } ) ;
388
+
389
+ QUnit . test ( 'one() can add a listener to an array of event types on a different evented object' , function ( assert ) {
231
390
const a = this . targets . a = evented ( { } ) ;
232
391
const b = this . targets . b = evented ( { } ) ;
233
392
const spy = sinon . spy ( ) ;
@@ -250,6 +409,56 @@ QUnit.test('one() can add a listener to an array of event types on a different t
250
409
} ) ;
251
410
} ) ;
252
411
412
+ QUnit . test ( 'one() can add a listener to an array of event types on a node object' , function ( assert ) {
413
+ const a = this . targets . a = evented ( { } ) ;
414
+ const b = this . targets . b = Dom . createEl ( 'div' ) ;
415
+ const spy = sinon . spy ( ) ;
416
+ const x = createEvent ( 'x' ) ;
417
+ const y = createEvent ( 'y' ) ;
418
+
419
+ a . one ( b , [ 'x' , 'y' ] , spy ) ;
420
+ b . dispatchEvent ( x ) ;
421
+ b . dispatchEvent ( y ) ;
422
+ b . dispatchEvent ( x ) ;
423
+ b . dispatchEvent ( y ) ;
424
+
425
+ // Make sure we aren't magically binding a listener to "a".
426
+ a . trigger ( 'x' ) ;
427
+ a . trigger ( 'y' ) ;
428
+
429
+ assert . strictEqual ( spy . callCount , 1 , 'the listener was called the expected number of times' ) ;
430
+
431
+ validateListenerCall ( spy . getCall ( 0 ) , a , {
432
+ type : 'x' ,
433
+ target : b
434
+ } ) ;
435
+ } ) ;
436
+
437
+ QUnit . test ( 'one() can add a listener to an array of event types on the window object' , function ( assert ) {
438
+ const a = this . targets . a = evented ( { } ) ;
439
+ const b = this . targets . b = window ;
440
+ const spy = sinon . spy ( ) ;
441
+ const x = createEvent ( 'x' ) ;
442
+ const y = createEvent ( 'y' ) ;
443
+
444
+ a . one ( b , [ 'x' , 'y' ] , spy ) ;
445
+ b . dispatchEvent ( x ) ;
446
+ b . dispatchEvent ( y ) ;
447
+ b . dispatchEvent ( x ) ;
448
+ b . dispatchEvent ( y ) ;
449
+
450
+ // Make sure we aren't magically binding a listener to "a".
451
+ a . trigger ( 'x' ) ;
452
+ a . trigger ( 'y' ) ;
453
+
454
+ assert . strictEqual ( spy . callCount , 1 , 'the listener was called the expected number of times' ) ;
455
+
456
+ validateListenerCall ( spy . getCall ( 0 ) , a , {
457
+ type : 'x' ,
458
+ target : b
459
+ } ) ;
460
+ } ) ;
461
+
253
462
QUnit . test ( 'off() with no arguments will remove all listeners from all events on this object' , function ( assert ) {
254
463
const a = this . targets . a = evented ( { } ) ;
255
464
const spyX = sinon . spy ( ) ;
0 commit comments