UnitTC: Pass,error count save method has been changed
[platform/framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.2.0 / tests / unit / event / event_core.js
1 /*
2  * mobile event unit tests
3  */
4
5 (function($){
6         var libName = "jquery.mobile.events.js",
7             components = [ "events/touch.js", "events/throttledresize.js", "events/orientationchange.js" ],
8             absFn = Math.abs,
9             originalEventFn = $.Event.prototype.originalEvent,
10             preventDefaultFn = $.Event.prototype.preventDefault,
11             events = ("touchstart touchmove touchend tap taphold " +
12                           "swipe swipeleft swiperight scrollstart scrollstop orientationchange").split( " " );
13
14         module(libName, {
15                 setup: function(){
16
17                         // ensure bindings are removed
18                         $.each(events + "vmouseup vmousedown".split(" "), function(i, name){
19                                 $("#qunit-fixture").unbind();
20                         });
21
22                         //NOTE unmock
23                         Math.abs = absFn;
24                         $.Event.prototype.originalEvent = originalEventFn;
25                         $.Event.prototype.preventDefault = preventDefaultFn;
26
27                         // make sure the event objects respond to touches to simulate
28                         // the collections existence in non touch enabled test browsers
29                         $.Event.prototype.touches = [{pageX: 1, pageY: 1 }];
30
31                         $($.mobile.pageContainer).unbind( "throttledresize" );
32                 }
33         });
34
35         $.testHelper.excludeFileProtocol(function(){
36                 test( "new events defined on the jquery object", function(){
37                         $.each(events, function( i, name ) {
38                                 delete $.fn[name];
39                                 deepEqual($.fn[name], undefined);
40                         });
41
42                         $.each( components, function( index, value ) { $.testHelper.reloadLib( value ); });
43
44                         $.each(events, function( i, name ) {
45                                 ok( $.fn[name] !== undefined, name + " should NOT be undefined");
46                         });
47                 });
48         });
49
50         asyncTest( "defined event functions bind a closure when passed", function(){
51                 expect( 1 );
52
53                 $('#qunit-fixture').bind(events[0], function(){
54                         ok(true, "event fired");
55                         start();
56                 });
57
58                 $('#qunit-fixture').trigger(events[0]);
59         });
60
61         asyncTest( "defined event functions trigger the event with no arguments", function(){
62                 expect( 1 );
63
64                 $('#qunit-fixture').bind('touchstart', function(){
65                         ok(true, "event fired");
66                         start();
67                 });
68
69                 $('#qunit-fixture').touchstart();
70         });
71
72         // jQuery < 1.8
73         if ( $.attrFn ) {
74                 test( "defining event functions sets the attrFn to true", function(){
75                         $.each( events, function( index, name ) {
76                                 ok( $.attrFn[ name ], "attribute function is true" );
77                         });
78                 });
79         }
80
81
82         test( "scrollstart enabled defaults to true", function(){
83                 $.event.special.scrollstart.enabled = false;
84                 $.each( components, function( index, value ) { $.testHelper.reloadLib( value ); });
85                 ok($.event.special.scrollstart.enabled, "scrollstart enabled");
86         });
87
88         asyncTest( "scrollstart setup binds a function that returns when its disabled", function(){
89                 expect( 1 );
90                 $.event.special.scrollstart.enabled = false;
91
92                 $( "#qunit-fixture" ).bind("scrollstart", function(){
93                         ok(false, "scrollstart fired");
94                 });
95
96                 $( "#qunit-fixture" ).bind("touchmove", function(){
97                         ok(true, "touchmove fired");
98                         start();
99                 });
100
101                 $( "#qunit-fixture" ).trigger("touchmove");
102         });
103
104         asyncTest( "scrollstart setup binds a function that triggers scroll start when enabled", function(){
105                 $.event.special.scrollstart.enabled = true;
106
107                 $( "#qunit-fixture" ).bind("scrollstart", function(){
108                         ok(true, "scrollstart fired");
109                         start();
110                 });
111
112                 $( "#qunit-fixture" ).trigger("touchmove");
113         });
114
115         asyncTest( "scrollstart setup binds a function that triggers scroll stop after 50 ms", function(){
116                 var triggered = false;
117                 $.event.special.scrollstart.enabled = true;
118
119                 $( "#qunit-fixture" ).bind("scrollstop", function(){
120                         triggered = true;
121                 });
122
123                 ok(!triggered, "not triggered");
124
125                 $( "#qunit-fixture" ).trigger("touchmove");
126
127                 setTimeout(function(){
128                         ok(triggered, "triggered");
129                         start();
130                 }, 50);
131         });
132
133         var forceTouchSupport = function(){
134                 document.ontouchend = function() {};
135                 $.testHelper.reloadLib( "jquery.mobile.support.touch.js" );
136                 $.each( components, function( index, value ) { $.testHelper.reloadLib( value ); });
137
138                 //mock originalEvent information
139                 $.Event.prototype.originalEvent = {
140                         touches: [{ 'pageX' : 0 }, { 'pageY' : 0 }]
141                 };
142         };
143
144         asyncTest( "long press fires tap hold after taphold duration", function(){
145                 var taphold = false,
146                         target = undefined;
147
148                 forceTouchSupport();
149
150                 $( "#qunit-fixture" ).bind("taphold", function( e ){
151                         taphold = true;
152                         target = e.target;
153                 });
154
155                 $( "#qunit-fixture" ).trigger("vmousedown");
156                 // tapholdThreshold has been changed from 100 to 2000
157                 setTimeout(function(){
158                         ok( !taphold, "taphold not fired" );
159                         deepEqual( target, undefined, "taphold target should be #qunit-fixture!" );
160                 }, $.event.special.tap.tapholdThreshold - 2000);
161
162                 setTimeout(function(){
163                         ok( taphold, "taphold fired" );
164                         equal( target, $( "#qunit-fixture" ).get( 0 ), "taphold target should be #qunit-fixture!" );
165                         start();
166                 }, $.event.special.tap.tapholdThreshold + 2000);
167         });
168
169         //NOTE used to simulate movement when checked
170         //TODO find a better way ...
171         var mockAbs = function(value){
172                 Math.abs = function(){
173                         return value;
174                 };
175         };
176
177         asyncTest( "move prevents taphold", function(){
178                 expect( 1 );
179                 var taphold = false;
180
181                 forceTouchSupport();
182                 mockAbs(100);
183
184                 //NOTE record taphold event
185                 $( "#qunit-fixture" ).bind("taphold", function(){
186                         ok(false, "taphold fired");
187                         taphold = true;
188                 });
189
190                 //NOTE start the touch events
191                 $( "#qunit-fixture" ).trigger("vmousedown");
192
193                 //NOTE fire touchmove to push back taphold
194                 setTimeout(function(){
195                         $( "#qunit-fixture" ).trigger("vmousecancel");
196                 }, 100);
197
198                 //NOTE verify that the taphold hasn't been fired
199                 //               with the normal timing
200                 setTimeout(function(){
201                         ok(!taphold, "taphold not fired");
202                         start();
203                 }, 751);
204         });
205
206         asyncTest( "tap event fired without movement", function(){
207                 expect( 1 );
208                 var tap = false,
209                                 checkTap = function(){
210                                         ok(true, "tap fired");
211                                 };
212
213                 forceTouchSupport();
214
215                 //NOTE record the tap event
216                 $( "#qunit-fixture" ).bind("tap", checkTap);
217
218                 $( "#qunit-fixture" ).trigger("vmousedown");
219                 $( "#qunit-fixture" ).trigger("vmouseup");
220                 $( "#qunit-fixture" ).trigger("vclick");
221
222                 setTimeout(function(){
223                         start();
224                 }, 400);
225         });
226
227         asyncTest( "tap event not fired when there is movement", function(){
228                 expect( 1 );
229                 var tap = false;
230                 forceTouchSupport();
231
232                 //NOTE record tap event
233                 $( "#qunit-fixture" ).bind("tap", function(){
234                         ok(false, "tap fired");
235                         tap = true;
236                 });
237
238                 //NOTE make sure movement is recorded
239                 mockAbs(100);
240
241                 //NOTE start and move right away
242                 $( "#qunit-fixture" ).trigger("touchstart");
243                 $( "#qunit-fixture" ).trigger("touchmove");
244
245                 //NOTE end touch sequence after 20 ms
246                 setTimeout(function(){
247                         $( "#qunit-fixture" ).trigger("touchend");
248                 }, 20);
249
250                 setTimeout(function(){
251                         ok(!tap, "not tapped");
252                         start();
253                 }, 40);
254         });
255
256         asyncTest( "tap event propagates up DOM tree", function(){
257                 var tap = 0,
258                         $qf = $( "#qunit-fixture" ),
259                         $doc = $( document ),
260                         docTapCB = function(){
261                                 deepEqual(++tap, 2, "document tap callback called once after #qunit-fixture callback");
262                         };
263
264                 $qf.bind( "tap", function() {
265                         deepEqual(++tap, 1, "#qunit-fixture tap callback called once");
266                 });
267
268                 $doc.bind( "tap", docTapCB );
269
270                 $qf.trigger( "vmousedown" )
271                         .trigger( "vmouseup" )
272                         .trigger( "vclick" );
273
274                 // tap binding should be triggered twice, once for
275                 // #qunit-fixture, and a second time for document.
276                 deepEqual( tap, 2, "final tap callback count is 2" );
277
278                 $doc.unbind( "tap", docTapCB );
279
280                 start();
281         });
282
283         asyncTest( "stopPropagation() prevents tap from propagating up DOM tree", function(){
284                 var tap = 0,
285                         $qf = $( "#qunit-fixture" ),
286                         $doc = $( document ),
287                         docTapCB = function(){
288                                 ok(false, "tap should NOT be triggered on document");
289                         };
290
291                 $qf.bind( "tap", function(e) {
292                         deepEqual(++tap, 1, "tap callback 1 triggered once on #qunit-fixture");
293                         e.stopPropagation();
294                 })
295                 .bind( "tap", function(e) {
296                         deepEqual(++tap, 2, "tap callback 2 triggered once on #qunit-fixture");
297                 });
298
299                 $doc.bind( "tap", docTapCB);
300
301                 $qf.trigger( "vmousedown" )
302                         .trigger( "vmouseup" )
303                         .trigger( "vclick" );
304
305                 // tap binding should be triggered twice.
306                 deepEqual( tap, 2, "final tap count is 2" );
307
308                 $doc.unbind( "tap", docTapCB );
309
310                 start();
311         });
312
313         asyncTest( "stopImmediatePropagation() prevents tap propagation and execution of 2nd handler", function(){
314                 var tap = 0,
315                         $cf = $( "#qunit-fixture" );
316                         $doc = $( document ),
317                         docTapCB = function(){
318                                 ok(false, "tap should NOT be triggered on document");
319                         };
320
321                 // Bind 2 tap callbacks on qunit-fixture. Only the first
322                 // one should ever be called.
323                 $cf.bind( "tap", function(e) {
324                         deepEqual(++tap, 1, "tap callback 1 triggered once on #qunit-fixture");
325                         e.stopImmediatePropagation();
326                 })
327                 .bind( "tap", function(e) {
328                         ok(false, "tap callback 2 should NOT be triggered on #qunit-fixture");
329                 });
330
331                 $doc.bind( "tap", docTapCB);
332
333                 $cf.trigger( "vmousedown" )
334                         .trigger( "vmouseup" )
335                         .trigger( "vclick" );
336
337                 // tap binding should be triggered once.
338                 deepEqual( tap, 1, "final tap count is 1" );
339
340                 $doc.unbind( "tap", docTapCB );
341
342                 start();
343         });
344
345         var swipeTimedTest = function(opts){
346                 var swipe = false;
347
348                 forceTouchSupport();
349
350                 $( "#qunit-fixture" ).bind('swipe', function(){
351                         swipe = true;
352                 });
353
354                 //NOTE bypass the trigger source check
355                 $.Event.prototype.originalEvent = {
356                         touches: [{
357                                 pageX: 0,
358                                 pageY: 0
359                         }]
360                 };
361
362                 $( "#qunit-fixture" ).trigger("touchstart");
363
364                 //NOTE make sure the coordinates are calculated within range
365                 //               to be registered as a swipe
366                 mockAbs(opts.coordChange);
367
368                 setTimeout(function(){
369                         $( "#qunit-fixture" ).trigger("touchmove");
370                         $( "#qunit-fixture" ).trigger("touchend");
371                 }, opts.timeout + 100);
372
373                 setTimeout(function(){
374                         deepEqual(swipe, opts.expected, "swipe expected");
375                         start();
376                 }, opts.timeout + 200);
377
378                 stop();
379         };
380
381         test( "swipe fired when coordinate change in less than a second", function(){
382                 swipeTimedTest({ timeout: 10, coordChange: 35, expected: true });
383         });
384
385         test( "swipe not fired when coordinate change takes more than a second", function(){
386                 swipeTimedTest({ timeout: 1000, coordChange: 35, expected: false });
387         });
388
389         test( "swipe not fired when coordinate change <= 30", function(){
390                 swipeTimedTest({ timeout: 1000, coordChange: 30, expected: false });
391         });
392
393         test( "swipe not fired when coordinate change >= 75", function(){
394                 swipeTimedTest({ timeout: 1000, coordChange: 75, expected: false });
395         });
396
397         asyncTest( "scrolling prevented when coordinate change > 10", function(){
398                 expect( 1 );
399
400                 forceTouchSupport();
401
402                 // ensure the swipe custome event is setup
403                 $( "#qunit-fixture" ).bind('swipe', function(){});
404
405                 $.Event.prototype.preventDefault = function(){
406                         ok(true, "prevent default called");
407                         start();
408                 };
409
410                 //NOTE bypass the trigger source check
411                 $.Event.prototype.originalEvent = {
412                         touches: [{
413                                 pageX: 0,
414                                 pageY: 0
415                         }]
416                 };
417
418                 $( "#qunit-fixture" ).trigger("touchstart");
419
420                 //NOTE bypass the trigger source check
421                 $.Event.prototype.originalEvent = {
422                         touches: [{
423                                 pageX: 200,
424                                 pageY: 0
425                         }]
426                 };
427
428                 $( "#qunit-fixture" ).trigger("touchmove");
429         });
430
431         asyncTest( "move handler returns when touchstart has been fired since touchstop", function(){
432                 expect( 1 );
433
434                 // bypass triggered event check
435                 $.Event.prototype.originalEvent = {
436                         touches: false
437                 };
438
439                 forceTouchSupport();
440
441                 // ensure the swipe custome event is setup
442                 $( "#qunit-fixture" ).bind('swipe', function(){});
443
444                 $( "#qunit-fixture" ).trigger("touchstart");
445                 $( "#qunit-fixture" ).trigger("touchend");
446
447                 $( "#qunit-fixture" ).bind("touchmove", function(){
448                         ok(true, "touchmove bound functions are fired");
449                         start();
450                 });
451
452                 Math.abs = function(){
453                         ok(false, "shouldn't compare coordinates");
454                 };
455
456                 $( "#qunit-fixture" ).trigger("touchmove");
457         });
458
459         var nativeSupportTest = function(opts){
460                 $.support.orientation = opts.orientationSupport;
461                 deepEqual($.event.special.orientationchange[opts.method](), opts.returnValue);
462         };
463
464         test( "orientation change setup should do nothing when natively supported", function(){
465                 nativeSupportTest({
466                         method: 'setup',
467                         orientationSupport: true,
468                         returnValue: false
469                 });
470         });
471
472         test( "orientation change setup should bind resize when not supported natively", function(){
473                 nativeSupportTest({
474                         method: 'setup',
475                         orientationSupport: false,
476                         returnValue: undefined //NOTE result of bind function call
477                 });
478         });
479
480         test( "orientation change teardown should do nothing when natively supported", function(){
481                 nativeSupportTest({
482                         method: 'teardown',
483                         orientationSupport: true,
484                         returnValue: false
485                 });
486         });
487
488         test( "orientation change teardown should unbind resize when not supported natively", function(){
489                 nativeSupportTest({
490                         method: 'teardown',
491                         orientationSupport: false,
492                         returnValue: undefined //NOTE result of unbind function call
493                 });
494         });
495
496         /* The following 4 tests are async so that the throttled event triggers don't interfere with subsequent tests */
497
498         asyncTest( "throttledresize event proxies resize events", function(){
499                 $( window ).one( "throttledresize", function(){
500                         ok( true, "throttledresize called");
501                         start();
502                 });
503
504                 $( window ).trigger( "resize" );
505         });
506
507         asyncTest( "throttledresize event prevents resize events from firing more frequently than one per 250ms", function(){
508                 var called = 0;
509
510                 $(window).bind( "throttledresize", function(){
511                         called++;
512                 });
513
514                 // NOTE 400 ms between two triggers and the check for one callback
515                 // is enough time for the first to fire but not enough for a second
516                 $.testHelper.sequence([
517                         function(){
518                                 $(window).trigger( "resize" ).trigger( "resize" );
519                         },
520
521                         // verify that only one throttled resize was called after 250ms
522                         function(){ deepEqual( called, 1 ); },
523
524                         function(){
525                                 start();
526                         }
527                 ], 400);
528         });
529
530         asyncTest( "throttledresize event promises that a held call will execute only once after throttled timeout", function(){
531                 var called = 0;
532
533                 expect( 2 );
534
535                 $.testHelper.eventSequence( "throttledresize", [
536                         // ignore the first call
537                         $.noop,
538
539                         function(){
540                                 ok( true, "second throttled resize should run" );
541                         },
542
543                         function(timedOut){
544                                 ok( timedOut, "third throttled resize should not run");
545                                 start();
546                         }
547                 ]);
548
549                 $.mobile.pageContainer
550                         .trigger( "resize" )
551                         .trigger( "resize" )
552                         .trigger( "resize" );
553         });
554
555         asyncTest( "mousedown mouseup and click events should add a which when its not defined", function() {
556                 var whichDefined = function( event ){
557                         deepEqual(event.which, 1);
558                 };
559
560                 $( document ).bind( "vclick", whichDefined);
561                 $( document ).trigger( "click" );
562
563                 $( document ).bind( "vmousedown", whichDefined);
564                 $( document ).trigger( "mousedown" );
565
566                 $( document ).bind( "vmouseup", function( event ){
567                         deepEqual(event.which, 1);
568                         start();
569                 });
570
571                 $( document ).trigger( "mouseup" );
572         });
573 })(jQuery);