beec2c537655639748e463e3cb788aaa077baf70
[jquery.git] / test / unit / ajax.js
1 module("ajax");
2
3 // Safari 3 randomly crashes when running these tests,
4 // but only in the full suite - you can run just the Ajax
5 // tests and they'll pass
6 //if ( !jQuery.browser.safari ) {
7
8 if ( !isLocal ) {
9
10 test("jQuery.ajax() - success callbacks", function() {
11         expect( 8 );
12
13         jQuery.ajaxSetup({ timeout: 0 });
14
15         stop();
16
17         jQuery('#foo').ajaxStart(function(){
18                 ok( true, "ajaxStart" );
19         }).ajaxStop(function(){
20                 ok( true, "ajaxStop" );
21                 start();
22         }).ajaxSend(function(){
23                 ok( true, "ajaxSend" );
24         }).ajaxComplete(function(){
25                 ok( true, "ajaxComplete" );
26         }).ajaxError(function(){
27                 ok( false, "ajaxError" );
28         }).ajaxSuccess(function(){
29                 ok( true, "ajaxSuccess" );
30         });
31
32         jQuery.ajax({
33                 url: url("data/name.html"),
34                 beforeSend: function(){ ok(true, "beforeSend"); },
35                 success: function(){ ok(true, "success"); },
36                 error: function(){ ok(false, "error"); },
37                 complete: function(){ ok(true, "complete"); }
38         });
39 });
40
41 test("jQuery.ajax() - success callbacks - (url, options) syntax", function() {
42         expect( 8 );
43
44         jQuery.ajaxSetup({ timeout: 0 });
45
46         stop();
47
48         setTimeout(function(){
49                 jQuery('#foo').ajaxStart(function(){
50                         ok( true, "ajaxStart" );
51                 }).ajaxStop(function(){
52                         ok( true, "ajaxStop" );
53                         start();
54                 }).ajaxSend(function(){
55                         ok( true, "ajaxSend" );
56                 }).ajaxComplete(function(){
57                         ok( true, "ajaxComplete" );
58                 }).ajaxError(function(){
59                         ok( false, "ajaxError" );
60                 }).ajaxSuccess(function(){
61                         ok( true, "ajaxSuccess" );
62                 });
63
64                 jQuery.ajax( url("data/name.html") , {
65                         beforeSend: function(){ ok(true, "beforeSend"); },
66                         success: function(){ ok(true, "success"); },
67                         error: function(){ ok(false, "error"); },
68                         complete: function(){ ok(true, "complete"); }
69                 });
70         }, 13);
71 });
72
73 test("jQuery.ajax() - success/error callbacks (remote)", function() {
74
75         var supports = jQuery.support.cors;
76
77         expect( supports ? 9 : 6 );
78
79         jQuery.ajaxSetup({ timeout: 0 });
80
81         stop();
82
83         setTimeout(function(){
84                 jQuery('#foo').ajaxStart(function(){
85                         ok( true, "ajaxStart" );
86                 }).ajaxStop(function(){
87                         ok( true, "ajaxStop" );
88                         start();
89                 }).ajaxSend(function(){
90                         ok( supports , "ajaxSend" );
91                 }).ajaxComplete(function(){
92                         ok( true, "ajaxComplete" );
93                 }).ajaxError(function(){
94                         ok( ! supports, "ajaxError" );
95                 }).ajaxSuccess(function(){
96                         ok( supports, "ajaxSuccess" );
97                 });
98
99                 jQuery.ajax({
100                         // JULIAN TODO: Get an url especially for jQuery
101                         url: "http://rockstarapps.com/test.php",
102                         dataType: "text",
103                         beforeSend: function(){ ok(supports, "beforeSend"); },
104                         success: function( val ){ ok(supports, "success"); ok(supports && val.length, "data received"); },
105                         error: function(_ , a , b ){ ok(!supports, "error"); },
106                         complete: function(){ ok(true, "complete"); }
107                 });
108         }, 13);
109 });
110
111 test("jQuery.ajax() - success callbacks (late binding)", function() {
112         expect( 8 );
113
114         jQuery.ajaxSetup({ timeout: 0 });
115
116         stop();
117
118         setTimeout(function(){
119                 jQuery('#foo').ajaxStart(function(){
120                         ok( true, "ajaxStart" );
121                 }).ajaxStop(function(){
122                         ok( true, "ajaxStop" );
123                         start();
124                 }).ajaxSend(function(){
125                         ok( true, "ajaxSend" );
126                 }).ajaxComplete(function(){
127                         ok( true, "ajaxComplete" );
128                 }).ajaxError(function(){
129                         ok( false, "ajaxError" );
130                 }).ajaxSuccess(function(){
131                         ok( true, "ajaxSuccess" );
132                 });
133
134                 jQuery.ajax({
135                         url: url("data/name.html"),
136                         beforeSend: function(){ ok(true, "beforeSend"); }
137                 })
138                         .complete(function(){ ok(true, "complete"); })
139                         .success(function(){ ok(true, "success"); })
140                         .error(function(){ ok(false, "error"); });
141         }, 13);
142 });
143
144 test("jQuery.ajax() - success callbacks (oncomplete binding)", function() {
145         expect( 8 );
146
147         jQuery.ajaxSetup({ timeout: 0 });
148
149         stop();
150
151         setTimeout(function(){
152                 jQuery('#foo').ajaxStart(function(){
153                         ok( true, "ajaxStart" );
154                 }).ajaxStop(function(){
155                         ok( true, "ajaxStop" );
156                 }).ajaxSend(function(){
157                         ok( true, "ajaxSend" );
158                 }).ajaxComplete(function(){
159                         ok( true, "ajaxComplete" );
160                 }).ajaxError(function(){
161                         ok( false, "ajaxError" );
162                 }).ajaxSuccess(function(){
163                         ok( true, "ajaxSuccess" );
164                 });
165
166                 jQuery.ajax({
167                         url: url("data/name.html"),
168                         beforeSend: function(){ ok(true, "beforeSend"); },
169                         complete: function(xhr) {
170                                 xhr
171                                 .complete(function(){ ok(true, "complete"); })
172                                 .success(function(){ ok(true, "success"); })
173                                 .error(function(){ ok(false, "error"); })
174                                 .complete(function(){ start(); });
175                         }
176                 })
177         }, 13);
178 });
179
180 test("jQuery.ajax() - success callbacks (very late binding)", function() {
181         expect( 8 );
182
183         jQuery.ajaxSetup({ timeout: 0 });
184
185         stop();
186
187         setTimeout(function(){
188                 jQuery('#foo').ajaxStart(function(){
189                         ok( true, "ajaxStart" );
190                 }).ajaxStop(function(){
191                         ok( true, "ajaxStop" );
192                 }).ajaxSend(function(){
193                         ok( true, "ajaxSend" );
194                 }).ajaxComplete(function(){
195                         ok( true, "ajaxComplete" );
196                 }).ajaxError(function(){
197                         ok( false, "ajaxError" );
198                 }).ajaxSuccess(function(){
199                         ok( true, "ajaxSuccess" );
200                 });
201
202                 jQuery.ajax({
203                         url: url("data/name.html"),
204                         beforeSend: function(){ ok(true, "beforeSend"); },
205                         complete: function(xhr) {
206                                 setTimeout (function() {
207                                         xhr
208                                         .complete(function(){ ok(true, "complete"); })
209                                         .success(function(){ ok(true, "success"); })
210                                         .error(function(){ ok(false, "error"); })
211                                         .complete(function(){ start(); });
212                                 },100);
213                         }
214                 })
215         }, 13);
216 });
217
218 test("jQuery.ajax() - success callbacks (order)", function() {
219         expect( 1 );
220
221         jQuery.ajaxSetup({ timeout: 0 });
222
223         stop();
224
225         var testString = "";
226
227         setTimeout(function(){
228                 jQuery.ajax({
229                         url: url("data/name.html"),
230                         success: function( _1 , _2 , xhr ) {
231                                 xhr.success(function() {
232                                         xhr.success(function() {
233                                                 testString += "E";
234                                         });
235                                         testString += "D";
236                                 });
237                                 testString += "A";
238                         },
239                         complete: function() {
240                                 strictEqual(testString, "ABCDE", "Proper order");
241                                 start();
242                         }
243                 }).success(function() {
244                         testString += "B";
245                 }).success(function() {
246                         testString += "C";
247                 });
248         }, 13);
249 });
250
251 test("jQuery.ajax() - error callbacks", function() {
252         expect( 8 );
253         stop();
254
255         jQuery('#foo').ajaxStart(function(){
256                 ok( true, "ajaxStart" );
257         }).ajaxStop(function(){
258                 ok( true, "ajaxStop" );
259                 start();
260         }).ajaxSend(function(){
261                 ok( true, "ajaxSend" );
262         }).ajaxComplete(function(){
263                 ok( true, "ajaxComplete" );
264         }).ajaxError(function(){
265                 ok( true, "ajaxError" );
266         }).ajaxSuccess(function(){
267                 ok( false, "ajaxSuccess" );
268         });
269
270         jQuery.ajaxSetup({ timeout: 500 });
271
272         jQuery.ajax({
273                 url: url("data/name.php?wait=5"),
274                 beforeSend: function(){ ok(true, "beforeSend"); },
275                 success: function(){ ok(false, "success"); },
276                 error: function(){ ok(true, "error"); },
277                 complete: function(){ ok(true, "complete"); }
278         });
279 });
280
281 test(".ajax() - headers" , function() {
282
283         expect( 2 );
284
285         stop();
286
287         var requestHeaders = {
288                 siMPle: "value",
289                 "SometHing-elsE": "other value",
290                 OthEr: "something else"
291                 },
292                 list = [],
293                 i;
294
295         for( i in requestHeaders ) {
296                 list.push( i );
297         }
298
299         jQuery.ajax(url("data/headers.php?keys="+list.join( "_" ) ), {
300                 headers: requestHeaders,
301                 success: function( data , _ , xhr ) {
302                         var tmp = [];
303                         for ( i in requestHeaders ) {
304                                 tmp.push( i , ": " , requestHeaders[ i ] , "\n" );
305                         }
306                         tmp = tmp.join( "" );
307
308                         equals( data , tmp , "Headers were sent" );
309                         equals( xhr.getResponseHeader( "Sample-Header" ) , "Hello World" , "Sample header received" );
310                         start();
311                 },
312                 error: function(){ ok(false, "error"); }
313         });
314
315 });
316
317 test(".ajax() - hash", function() {
318         expect(3);
319
320         jQuery.ajax({
321                 url: "data/name.html#foo",
322                 beforeSend: function( xhr, settings ) {
323                         equals(settings.url, "data/name.html", "Make sure that the URL is trimmed.");
324                         return false;
325                 }
326         });
327
328         jQuery.ajax({
329                 url: "data/name.html?abc#foo",
330                 beforeSend: function( xhr, settings ) {
331                 equals(settings.url, "data/name.html?abc", "Make sure that the URL is trimmed.");
332                         return false;
333                 }
334         });
335
336         jQuery.ajax({
337                 url: "data/name.html?abc#foo",
338                 data: { "test": 123 },
339                 beforeSend: function( xhr, settings ) {
340                         equals(settings.url, "data/name.html?abc&test=123", "Make sure that the URL is trimmed.");
341                         return false;
342                 }
343         });
344 });
345
346 test(".ajax() - 304", function() {
347         expect( 1 );
348         stop();
349
350         jQuery.ajax({
351                 url: url("data/notmodified.php"),
352                 success: function(){ ok(true, "304 ok"); },
353                 // Do this because opera simply refuses to implement 304 handling :(
354                 // A feature-driven way of detecting this would be appreciated
355                 // See: http://gist.github.com/599419
356                 error: function(){ ok(jQuery.browser.opera, "304 not ok "); },
357                 complete: function(xhr){ start(); }
358         });
359 });
360
361 test(".load()) - 404 error callbacks", function() {
362         expect( 6 );
363         stop();
364
365         jQuery('#foo').ajaxStart(function(){
366                 ok( true, "ajaxStart" );
367         }).ajaxStop(function(){
368                 ok( true, "ajaxStop" );
369                 start();
370         }).ajaxSend(function(){
371                 ok( true, "ajaxSend" );
372         }).ajaxComplete(function(){
373                 ok( true, "ajaxComplete" );
374         }).ajaxError(function(){
375                 ok( true, "ajaxError" );
376         }).ajaxSuccess(function(){
377                 ok( false, "ajaxSuccess" );
378         });
379
380         jQuery("<div/>").load("data/404.html", function(){
381                 ok(true, "complete");
382         });
383 });
384
385 test("jQuery.ajax() - abort", function() {
386         expect( 8 );
387         stop();
388
389         jQuery('#foo').ajaxStart(function(){
390                 ok( true, "ajaxStart" );
391         }).ajaxStop(function(){
392                 ok( true, "ajaxStop" );
393                 start();
394         }).ajaxSend(function(){
395                 ok( true, "ajaxSend" );
396         }).ajaxComplete(function(){
397                 ok( true, "ajaxComplete" );
398         });
399
400         var xhr = jQuery.ajax({
401                 url: url("data/name.php?wait=5"),
402                 beforeSend: function(){ ok(true, "beforeSend"); },
403                 complete: function(){ ok(true, "complete"); }
404         });
405
406         equals( xhr.readyState, 1, "XHR readyState indicates successful dispatch" );
407
408         xhr.abort();
409         equals( xhr.readyState, 0, "XHR readyState indicates successful abortion" );
410 });
411
412 test("jQuery.ajax() - readyState (success)", function() {
413         expect( 1 );
414
415         jQuery.ajaxSetup({ timeout: 0 });
416
417         stop();
418
419         var control = "";
420
421         setTimeout(function(){
422                 jQuery.ajax({
423                         url: url("data/name.html"),
424                         beforeSend: function( xhr ) {
425                                 xhr.onreadystatechange = function() {
426                                         control += xhr.readyState;
427                                 }
428                         },
429                         complete: function(){
430                                 setTimeout( function() {
431                                         equals( control , "1234" , "onreadystatechange was properly called" );
432                                 }, 13 );
433                                 start();
434                         }
435                 });
436         }, 13);
437 });
438
439 test("jQuery.ajax() - readyState (abort)", function() {
440         expect( 2 );
441
442         jQuery.ajaxSetup({ timeout: 0 });
443
444         stop();
445
446         var control = "";
447
448         setTimeout(function(){
449
450                 jQuery.ajaxSetup({ timeout: 500 });
451
452                 jQuery.ajax({
453                         url: url("data/name.php?wait=5"),
454                         beforeSend: function( xhr ) {
455                                 xhr.onreadystatechange = function() {
456                                         control += xhr.readyState;
457                                 }
458                         },
459                         complete: function( xhr ){
460                                 setTimeout( function() {
461                                         equals( control , "14" , "onreadystatechange was properly called" );
462                                         equals( xhr.readyState, 0 , "readyState is 0" );
463                                 }, 13 );
464                                 start();
465                         }
466                 });
467         }, 13);
468 });
469
470 test("jQuery.xhr() - reuse", function() {
471         expect( 15 );
472
473         jQuery.ajaxSetup({ timeout: 0 });
474
475         stop();
476
477         var number = 0;
478
479         setTimeout(function(){
480                 jQuery('#foo').ajaxStart(function(){
481                         ok( true, "ajaxStart" );
482                 }).ajaxStop(function(){
483                         ok( true, "ajaxStop" );
484                         start();
485                 }).ajaxSend(function(){
486                         number++;
487                         ok( true, "ajaxSend (" + number +")" );
488                 }).ajaxComplete(function(){
489                         ok( true, "ajaxComplete (" + number +")" );
490                 }).ajaxError(function(){
491                         ok( false, "ajaxError (" + number +")" );
492                 }).ajaxSuccess(function(){
493                         ok( true, "ajaxSuccess (" + number +")" );
494                 });
495
496                 jQuery.ajax({
497                         url: url("data/name.html"),
498                         beforeSend: function(){ ok(true, "beforeSend (1)"); },
499                         success: function( _1 , _2 , xhr ){
500                                 ok(true, "success (1)");
501                                 xhr.complete(function() {
502                                         ok(true, "complete (1bis)");
503                                 });
504                                 xhr.open( "GET", url("data/name.html") );
505                                 xhr.success( function(){ ok(true, "beforeSend (2)"); } )
506                                 xhr.send( null, {
507                                         success: function(){ ok(true, "success (2)"); },
508                                         error: function(){ ok(false, "error (2)"); },
509                                         complete: function(){ ok(true, "complete (2)"); }
510                                 } );
511                         },
512                         error: function(){ ok(false, "error (1)"); },
513                         complete: function(){ ok(true, "complete (1)"); }
514                 });
515         }, 13);
516 });
517
518 test("jQuery.xhr() - early binding", function() {
519         expect( 2 );
520
521         jQuery.ajaxSetup({ timeout: 0 });
522
523         stop();
524
525         jQuery.xhr()
526                 .success( function(){ ok(true, "success"); } )
527                 .error( function(){ ok(false, "error"); } )
528                 .complete( function(){ ok(true, "complete"); start(); } )
529                 .open( "GET", url("data/name.html") )
530                 .send();
531 });
532
533 test("jQuery.xhr() - get native implementation", function() {
534
535         var xhr = jQuery.xhr(true);
536
537         ok( xhr.readyState !== undefined , "implements XMLHttpRequest" );
538         ok( ! jQuery.isFunction( xhr.success ) , "is not jQuery's abstraction" );
539
540 });
541
542 test("Ajax events with context", function() {
543         expect(14);
544
545         stop();
546         var context = document.createElement("div");
547
548         function event(e){
549                 equals( this, context, e.type );
550         }
551
552         function callback(msg){
553                 return function(){
554                         equals( this, context, "context is preserved on callback " + msg );
555                 };
556         }
557
558         function nocallback(msg){
559                 return function(){
560                         equals( typeof this.url, "string", "context is settings on callback " + msg );
561                 };
562         }
563
564         jQuery('#foo').add(context)
565                         .ajaxSend(event)
566                         .ajaxComplete(event)
567                         .ajaxError(event)
568                         .ajaxSuccess(event);
569
570         jQuery.ajax({
571                 url: url("data/name.html"),
572                 beforeSend: callback("beforeSend"),
573                 success: callback("success"),
574                 error: callback("error"),
575                 complete:function(){
576                         callback("complete").call(this);
577
578                         jQuery.ajax({
579                                 url: url("data/404.html"),
580                                 context: context,
581                                 beforeSend: callback("beforeSend"),
582                                 error: callback("error"),
583                                 complete: function(){
584                                         callback("complete").call(this);
585
586                                         jQuery('#foo').add(context).unbind();
587
588                                         jQuery.ajax({
589                                                 url: url("data/404.html"),
590                                                 beforeSend: nocallback("beforeSend"),
591                                                 error: nocallback("error"),
592                                                 complete: function(){
593                                                         nocallback("complete").call(this);
594                                                         start();
595                                                 }
596                                         });
597                                 }
598                         });
599                 },
600                 context:context
601         });
602 });
603
604 test("jQuery.ajax context modification", function() {
605         expect(1);
606
607         stop();
608
609         var obj = {}
610
611         jQuery.ajax({
612                 url: url("data/name.html"),
613                 context: obj,
614                 beforeSend: function(){
615                         this.test = "foo";
616                 },
617                 complete: function() {
618                         start();
619                 }
620         });
621
622         equals( obj.test, "foo", "Make sure the original object is maintained." );
623 });
624
625 test("jQuery.ajax() - disabled globals", function() {
626         expect( 3 );
627         stop();
628
629         jQuery('#foo').ajaxStart(function(){
630                 ok( false, "ajaxStart" );
631         }).ajaxStop(function(){
632                 ok( false, "ajaxStop" );
633         }).ajaxSend(function(){
634                 ok( false, "ajaxSend" );
635         }).ajaxComplete(function(){
636                 ok( false, "ajaxComplete" );
637         }).ajaxError(function(){
638                 ok( false, "ajaxError" );
639         }).ajaxSuccess(function(){
640                 ok( false, "ajaxSuccess" );
641         });
642
643         jQuery.ajax({
644                 global: false,
645                 url: url("data/name.html"),
646                 beforeSend: function(){ ok(true, "beforeSend"); },
647                 success: function(){ ok(true, "success"); },
648                 error: function(){ ok(false, "error"); },
649                 complete: function(){
650                   ok(true, "complete");
651                   setTimeout(function(){ start(); }, 13);
652                 }
653         });
654 });
655
656 test("jQuery.xhr() - disabled globals through xhr.send(data , false)", function() {
657         expect( 2 );
658         stop();
659
660         jQuery('#foo').ajaxStart(function(){
661                 ok( false, "ajaxStart" );
662         }).ajaxStop(function(){
663                 ok( false, "ajaxStop" );
664         }).ajaxSend(function(){
665                 ok( false, "ajaxSend" );
666         }).ajaxComplete(function(){
667                 ok( false, "ajaxComplete" );
668         }).ajaxError(function(){
669                 ok( false, "ajaxError" );
670         }).ajaxSuccess(function(){
671                 ok( false, "ajaxSuccess" );
672         });
673
674         jQuery.xhr()
675                 .success(function(){ ok(true, "success"); })
676                 .error(function(){ ok(false, "error"); })
677                 .complete(function(){
678                   ok(true, "complete");
679                   setTimeout(function(){ start(); }, 13);
680                 })
681                 .open("GET", url("data/name.html")).send(undefined, false);
682 });
683
684 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", function() {
685         expect(3);
686         stop();
687         jQuery.ajax({
688           url: url("data/with_fries.xml"),
689           dataType: "xml",
690           success: function(resp) {
691                 equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
692                 equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
693                 equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
694                 start();
695           }
696         });
697 });
698
699 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements (over JSONP)", function() {
700         expect(3);
701         stop();
702         jQuery.ajax({
703           url: url("data/with_fries_over_jsonp.php"),
704           dataType: "jsonp xml",
705           success: function(resp) {
706                 equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
707                 equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
708                 equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
709                 start();
710           }
711         });
712 });
713
714 test("jQuery.ajax - HEAD requests", function() {
715         expect(2);
716
717         stop();
718         jQuery.ajax({
719                 url: url("data/name.html"),
720                 type: "HEAD",
721                 success: function(data, status, xhr){
722                         var h = xhr.getAllResponseHeaders();
723                         ok( /Date/i.test(h), 'No Date in HEAD response' );
724
725                         jQuery.ajax({
726                                 url: url("data/name.html"),
727                                 data: { whip_it: "good" },
728                                 type: "HEAD",
729                                 success: function(data, status, xhr){
730                                         var h = xhr.getAllResponseHeaders();
731                                         ok( /Date/i.test(h), 'No Date in HEAD response with data' );
732                                         start();
733                                 }
734                         });
735                 }
736         });
737
738 });
739
740 test("jQuery.ajax - beforeSend", function() {
741         expect(1);
742         stop();
743
744         var check = false;
745
746         jQuery.ajaxSetup({ timeout: 0 });
747
748         jQuery.ajax({
749                 url: url("data/name.html"),
750                 beforeSend: function(xml) {
751                         check = true;
752                 },
753                 success: function(data) {
754                         ok( check, "check beforeSend was executed" );
755                         start();
756                 }
757         });
758 });
759
760 test("jQuery.ajax - beforeSend, cancel request (#2688)", function() {
761         expect(2);
762         var request = jQuery.ajax({
763                 url: url("data/name.html"),
764                 beforeSend: function() {
765                         ok( true, "beforeSend got called, canceling" );
766                         return false;
767                 },
768                 success: function() {
769                         ok( false, "request didn't get canceled" );
770                 },
771                 complete: function() {
772                         ok( false, "request didn't get canceled" );
773                 },
774                 error: function() {
775                         ok( false, "request didn't get canceled" );
776                 }
777         });
778         ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
779 });
780
781 test("jQuery.ajax - beforeSend, cancel request manually", function() {
782         expect(2);
783         var request = jQuery.ajax({
784                 url: url("data/name.html"),
785                 beforeSend: function(xhr) {
786                         ok( true, "beforeSend got called, canceling" );
787                         xhr.abort();
788                 },
789                 success: function() {
790                         ok( false, "request didn't get canceled" );
791                 },
792                 complete: function() {
793                         ok( false, "request didn't get canceled" );
794                 },
795                 error: function() {
796                         ok( false, "request didn't get canceled" );
797                 }
798         });
799         ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
800 });
801
802 window.foobar = null;
803 window.testFoo = undefined;
804
805 test("jQuery.ajax - dataType html", function() {
806         expect(5);
807         stop();
808
809         var verifyEvaluation = function() {
810                 equals( testFoo, "foo", 'Check if script was evaluated for datatype html' );
811                 equals( foobar, "bar", 'Check if script src was evaluated for datatype html' );
812
813                 start();
814         };
815
816         jQuery.ajax({
817           dataType: "html",
818           url: url("data/test.html"),
819           success: function(data) {
820                 jQuery("#ap").html(data);
821                 ok( data.match(/^html text/), 'Check content for datatype html' );
822                 setTimeout(verifyEvaluation, 600);
823           }
824         });
825 });
826
827 test("serialize()", function() {
828         expect(5);
829
830         // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers
831         jQuery("#search").after(
832                 '<input type="email" id="html5email" name="email" value="dave@jquery.com" />'+
833                 '<input type="number" id="html5number" name="number" value="43" />'
834         );
835
836         equals( jQuery('#form').serialize(),
837                 "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3",
838                 'Check form serialization as query string');
839
840         equals( jQuery('#form :input').serialize(),
841                 "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3",
842                 'Check input serialization as query string');
843
844         equals( jQuery('#testForm').serialize(),
845                 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
846                 'Check form serialization as query string');
847
848         equals( jQuery('#testForm :input').serialize(),
849                 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
850                 'Check input serialization as query string');
851
852         equals( jQuery('#form, #testForm').serialize(),
853                 "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&select5=3&T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
854                 'Multiple form serialization as query string');
855
856   /* Temporarily disabled. Opera 10 has problems with form serialization.
857         equals( jQuery('#form, #testForm :input').serialize(),
858                 "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
859                 'Mixed form/input serialization as query string');
860         */
861         jQuery("#html5email, #html5number").remove();
862 });
863
864 test("jQuery.param()", function() {
865         expect(22);
866
867         equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" );
868
869         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
870         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
871
872         params = {someName: [1, 2, 3], regularThing: "blah" };
873         equals( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3&regularThing=blah", "with array" );
874
875         params = {foo: ['a', 'b', 'c']};
876         equals( jQuery.param(params), "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c", "with array of strings" );
877
878         params = {foo: ["baz", 42, "All your base are belong to us"] };
879         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
880
881         params = {foo: { bar: 'baz', beep: 42, quux: 'All your base are belong to us' } };
882         equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
883
884         params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
885         equals( decodeURIComponent( jQuery.param(params) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure" );
886
887         params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
888         equals( decodeURIComponent( jQuery.param(params) ), "a[]=0&a[1][]=1&a[1][]=2&a[2][]=3&a[2][1][]=4&a[2][1][]=5&a[2][2][]=6&a[3][b][]=7&a[3][b][1][]=8&a[3][b][1][]=9&a[3][b][2][0][c]=10&a[3][b][2][0][d]=11&a[3][b][3][0][]=12&a[3][b][4][0][0][]=13&a[3][b][5][e][f][g][]=14&a[3][b][5][e][f][g][1][]=15&a[3][b][]=16&a[]=17", "nested arrays" );
889
890         params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
891         equals( jQuery.param(params,true), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure, forced traditional" );
892
893         equals( decodeURIComponent( jQuery.param({ a: [1,2,3], 'b[]': [4,5,6], 'c[d]': [7,8,9], e: { f: [10], g: [11,12], h: 13 } }) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." );
894
895         // Make sure empty arrays and objects are handled #6481
896         equals( jQuery.param({"foo": {"bar": []} }), "foo%5Bbar%5D=", "Empty array param" );
897         equals( jQuery.param({"foo": {"bar": [], foo: 1} }), "foo%5Bbar%5D=&foo%5Bfoo%5D=1", "Empty array param" );
898         equals( jQuery.param({"foo": {"bar": {}} }), "foo%5Bbar%5D=", "Empty object param" );
899
900         jQuery.ajaxSetup({ traditional: true });
901
902         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
903         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
904
905         params = {someName: [1, 2, 3], regularThing: "blah" };
906         equals( jQuery.param(params), "someName=1&someName=2&someName=3&regularThing=blah", "with array" );
907
908         params = {foo: ['a', 'b', 'c']};
909         equals( jQuery.param(params), "foo=a&foo=b&foo=c", "with array of strings" );
910
911         params = {"foo[]":["baz", 42, "All your base are belong to us"]};
912         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
913
914         params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
915         equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
916
917         params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
918         equals( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure" );
919
920         params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
921         equals( jQuery.param(params), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject+Object%5D&a=17", "nested arrays (not possible when jQuery.param.traditional == true)" );
922
923         params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
924         equals( decodeURIComponent( jQuery.param(params,false) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure, forced not traditional" );
925
926         params = { param1: null };
927         equals( jQuery.param(params,false), "param1=null", "Make sure that null params aren't traversed." );
928 });
929
930 test("synchronous request", function() {
931         expect(1);
932         ok( /^{ "data"/.test( jQuery.ajax({url: url("data/json_obj.js"), dataType: "text", async: false}).responseText ), "check returned text" );
933 });
934
935 test("synchronous request with callbacks", function() {
936         expect(2);
937         var result;
938         jQuery.ajax({url: url("data/json_obj.js"), async: false, dataType: "text", success: function(data) { ok(true, "sucess callback executed"); result = data; } });
939         ok( /^{ "data"/.test( result ), "check returned text" );
940 });
941
942 test("pass-through request object", function() {
943         expect(8);
944         stop();
945
946         var target = "data/name.html";
947         var successCount = 0;
948         var errorCount = 0;
949         var errorEx = "";
950         var success = function() {
951                 successCount++;
952         };
953         jQuery("#foo").ajaxError(function (e, xml, s, ex) {
954                 errorCount++;
955                 errorEx += ": " + xml.status;
956         });
957         jQuery("#foo").one('ajaxStop', function () {
958                 equals(successCount, 5, "Check all ajax calls successful");
959                 equals(errorCount, 0, "Check no ajax errors (status" + errorEx + ")");
960                 jQuery("#foo").unbind('ajaxError');
961
962                 start();
963         });
964
965         ok( jQuery.get(url(target), success), "get" );
966         ok( jQuery.post(url(target), success), "post" );
967         ok( jQuery.getScript(url("data/test.js"), success), "script" );
968         ok( jQuery.getJSON(url("data/json_obj.js"), success), "json" );
969         ok( jQuery.ajax({url: url(target), success: success}), "generic" );
970 });
971
972 test("ajax cache", function () {
973         expect(18);
974
975         stop();
976
977         var count = 0;
978
979         jQuery("#firstp").bind("ajaxSuccess", function (e, xml, s) {
980                 var re = /_=(.*?)(&|$)/g;
981                 var oldOne = null;
982                 for (var i = 0; i < 6; i++) {
983                         var ret = re.exec(s.url);
984                         if (!ret) {
985                                 break;
986                         }
987                         oldOne = ret[1];
988                 }
989                 equals(i, 1, "Test to make sure only one 'no-cache' parameter is there");
990                 ok(oldOne != "tobereplaced555", "Test to be sure parameter (if it was there) was replaced");
991                 if(++count == 6)
992                         start();
993         });
994
995         ok( jQuery.ajax({url: "data/text.php", cache:false}), "test with no parameters" );
996         ok( jQuery.ajax({url: "data/text.php?pizza=true", cache:false}), "test with 1 parameter" );
997         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555", cache:false}), "test with _= parameter" );
998         ok( jQuery.ajax({url: "data/text.php?pizza=true&_=tobereplaced555", cache:false}), "test with 1 parameter plus _= one" );
999         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555&tv=false", cache:false}), "test with 1 parameter plus _= one before it" );
1000         ok( jQuery.ajax({url: "data/text.php?name=David&_=tobereplaced555&washere=true", cache:false}), "test with 2 parameters surrounding _= one" );
1001 });
1002
1003 /*
1004  * Test disabled.
1005  * The assertions expect that the passed-in object will be modified,
1006  * which shouldn't be the case. Fixes #5439.
1007 test("global ajaxSettings", function() {
1008         expect(2);
1009
1010         var tmp = jQuery.extend({}, jQuery.ajaxSettings);
1011         var orig = { url: "data/with_fries.xml" };
1012         var t;
1013
1014         jQuery.ajaxSetup({ data: {foo: 'bar', bar: 'BAR'} });
1015
1016         t = jQuery.extend({}, orig);
1017         t.data = {};
1018         jQuery.ajax(t);
1019         ok( t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending {}" );
1020
1021         t = jQuery.extend({}, orig);
1022         t.data = { zoo: 'a', ping: 'b' };
1023         jQuery.ajax(t);
1024         ok( t.url.indexOf('ping') > -1 && t.url.indexOf('zoo') > -1 && t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending { zoo: 'a', ping: 'b' }" );
1025
1026         jQuery.ajaxSettings = tmp;
1027 });
1028 */
1029
1030 test("load(String)", function() {
1031         expect(1);
1032         stop(); // check if load can be called with only url
1033         jQuery('#first').load("data/name.html", start);
1034 });
1035
1036 test("load('url selector')", function() {
1037         expect(1);
1038         stop(); // check if load can be called with only url
1039         jQuery('#first').load("data/test3.html div.user", function(){
1040                 equals( jQuery(this).children("div").length, 2, "Verify that specific elements were injected" );
1041                 start();
1042         });
1043 });
1044
1045 test("load(String, Function) with ajaxSetup on dataType json, see #2046", function() {
1046         expect(1);
1047         stop();
1048         jQuery.ajaxSetup({ dataType: "json" });
1049         jQuery("#first").ajaxComplete(function (e, xml, s) {
1050                 equals( s.dataType, "html", "Verify the load() dataType was html" );
1051                 jQuery("#first").unbind("ajaxComplete");
1052                 jQuery.ajaxSetup({ dataType: "" });
1053                 start();
1054         });
1055         jQuery('#first').load("data/test3.html");
1056 });
1057
1058 test("load(String, Function) - simple: inject text into DOM", function() {
1059         expect(2);
1060         stop();
1061         jQuery('#first').load(url("data/name.html"), function() {
1062                 ok( /^ERROR/.test(jQuery('#first').text()), 'Check if content was injected into the DOM' );
1063                 start();
1064         });
1065 });
1066
1067 test("load(String, Function) - check scripts", function() {
1068         expect(7);
1069         stop();
1070
1071         var verifyEvaluation = function() {
1072                 equals( foobar, "bar", 'Check if script src was evaluated after load' );
1073                 equals( jQuery('#ap').html(), 'bar', 'Check if script evaluation has modified DOM');
1074
1075                 start();
1076         };
1077         jQuery('#first').load(url('data/test.html'), function() {
1078                 ok( jQuery('#first').html().match(/^html text/), 'Check content after loading html' );
1079                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
1080                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
1081                 setTimeout(verifyEvaluation, 600);
1082         });
1083 });
1084
1085 test("load(String, Function) - check file with only a script tag", function() {
1086         expect(3);
1087         stop();
1088
1089         jQuery('#first').load(url('data/test2.html'), function() {
1090                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
1091                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
1092
1093                 start();
1094         });
1095 });
1096
1097 test("load(String, Object, Function)", function() {
1098         expect(2);
1099         stop();
1100
1101         jQuery('<div />').load(url('data/params_html.php'), { foo:3, bar:'ok' }, function() {
1102                 var $post = jQuery(this).find('#post');
1103                 equals( $post.find('#foo').text(), '3', 'Check if a hash of data is passed correctly');
1104                 equals( $post.find('#bar').text(), 'ok', 'Check if a hash of data is passed correctly');
1105                 start();
1106         });
1107 });
1108
1109 test("load(String, String, Function)", function() {
1110         expect(2);
1111         stop();
1112
1113         jQuery('<div />').load(url('data/params_html.php'), 'foo=3&bar=ok', function() {
1114                 var $get = jQuery(this).find('#get');
1115                 equals( $get.find('#foo').text(), '3', 'Check if a string of data is passed correctly');
1116                 equals( $get.find('#bar').text(), 'ok', 'Check if a      of data is passed correctly');
1117                 start();
1118         });
1119 });
1120
1121 test("jQuery.get(String, Hash, Function) - parse xml and use text() on nodes", function() {
1122         expect(2);
1123         stop();
1124         jQuery.get(url('data/dashboard.xml'), function(xml) {
1125                 var content = [];
1126                 jQuery('tab', xml).each(function() {
1127                         content.push(jQuery(this).text());
1128                 });
1129                 equals( content[0], 'blabla', 'Check first tab');
1130                 equals( content[1], 'blublu', 'Check second tab');
1131                 start();
1132         });
1133 });
1134
1135 test("jQuery.getScript(String, Function) - with callback", function() {
1136         expect(2);
1137         stop();
1138         jQuery.getScript(url("data/test.js"), function() {
1139                 equals( foobar, "bar", 'Check if script was evaluated' );
1140                 setTimeout(start, 100);
1141         });
1142 });
1143
1144 test("jQuery.getScript(String, Function) - no callback", function() {
1145         expect(1);
1146         stop();
1147         jQuery.getScript(url("data/test.js"), function(){
1148                 start();
1149         });
1150 });
1151
1152 test("jQuery.ajax() - JSONP, Local", function() {
1153         expect(9);
1154
1155         var count = 0;
1156         function plus(){ if ( ++count == 9 ) start(); }
1157
1158         stop();
1159
1160         jQuery.ajax({
1161                 url: "data/jsonp.php",
1162                 dataType: "jsonp",
1163                 success: function(data){
1164                         ok( data.data, "JSON results returned (GET, no callback)" );
1165                         plus();
1166                 },
1167                 error: function(data){
1168                         ok( false, "Ajax error JSON (GET, no callback)" );
1169                         plus();
1170                 }
1171         });
1172
1173         jQuery.ajax({
1174                 url: "data/jsonp.php?callback=?",
1175                 dataType: "jsonp",
1176                 success: function(data){
1177                         ok( data.data, "JSON results returned (GET, url callback)" );
1178                         plus();
1179                 },
1180                 error: function(data){
1181                         ok( false, "Ajax error JSON (GET, url callback)" );
1182                         plus();
1183                 }
1184         });
1185
1186         jQuery.ajax({
1187                 url: "data/jsonp.php",
1188                 dataType: "jsonp",
1189                 data: "callback=?",
1190                 success: function(data){
1191                         ok( data.data, "JSON results returned (GET, data callback)" );
1192                         plus();
1193                 },
1194                 error: function(data){
1195                         ok( false, "Ajax error JSON (GET, data callback)" );
1196                         plus();
1197                 }
1198         });
1199
1200         jQuery.ajax({
1201                 url: "data/jsonp.php",
1202                 dataType: "jsonp",
1203                 jsonp: "callback",
1204                 success: function(data){
1205                         ok( data.data, "JSON results returned (GET, data obj callback)" );
1206                         plus();
1207                 },
1208                 error: function(data){
1209                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1210                         plus();
1211                 }
1212         });
1213
1214         jQuery.ajax({
1215                 url: "data/jsonp.php",
1216                 dataType: "jsonp",
1217                 jsonpCallback: "jsonpResults",
1218                 success: function(data){
1219                         ok( data.data, "JSON results returned (GET, custom callback name)" );
1220                         plus();
1221                 },
1222                 error: function(data){
1223                         ok( false, "Ajax error JSON (GET, custom callback name)" );
1224                         plus();
1225                 }
1226         });
1227
1228         jQuery.ajax({
1229                 type: "POST",
1230                 url: "data/jsonp.php",
1231                 dataType: "jsonp",
1232                 success: function(data){
1233                         ok( data.data, "JSON results returned (POST, no callback)" );
1234                         plus();
1235                 },
1236                 error: function(data){
1237                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1238                         plus();
1239                 }
1240         });
1241
1242         jQuery.ajax({
1243                 type: "POST",
1244                 url: "data/jsonp.php",
1245                 data: "callback=?",
1246                 dataType: "jsonp",
1247                 success: function(data){
1248                         ok( data.data, "JSON results returned (POST, data callback)" );
1249                         plus();
1250                 },
1251                 error: function(data){
1252                         ok( false, "Ajax error JSON (POST, data callback)" );
1253                         plus();
1254                 }
1255         });
1256
1257         jQuery.ajax({
1258                 type: "POST",
1259                 url: "data/jsonp.php",
1260                 jsonp: "callback",
1261                 dataType: "jsonp",
1262                 success: function(data){
1263                         ok( data.data, "JSON results returned (POST, data obj callback)" );
1264                         plus();
1265                 },
1266                 error: function(data){
1267                         ok( false, "Ajax error JSON (POST, data obj callback)" );
1268                         plus();
1269                 }
1270         });
1271
1272         //#7578
1273         jQuery.ajax({
1274                 url: "data/jsonp.php",
1275                 dataType: "jsonp",
1276                 beforeSend: function(){
1277                         strictEqual( this.cache, false, "cache must be false on JSON request" );
1278                         plus();
1279                         return false;
1280                 }
1281         });
1282 });
1283
1284 test("jQuery.ajax() - JSONP - Custom JSONP Callback", function() {
1285         expect(1);
1286         stop();
1287
1288         window.jsonpResults = function(data) {
1289                 ok( data.data, "JSON results returned (GET, custom callback function)" );
1290                 window.jsonpResults = undefined;
1291                 start();
1292         };
1293
1294         jQuery.ajax({
1295                 url: "data/jsonp.php",
1296                 dataType: "jsonp",
1297                 jsonpCallback: "jsonpResults"
1298         });
1299 });
1300
1301 test("jQuery.ajax() - JSONP, Remote", function() {
1302         expect(4);
1303
1304         var count = 0;
1305         function plus(){ if ( ++count == 4 ) start(); }
1306
1307         var base = window.location.href.replace(/[^\/]*$/, "");
1308
1309         stop();
1310
1311         jQuery.ajax({
1312                 url: base + "data/jsonp.php",
1313                 dataType: "jsonp",
1314                 success: function(data){
1315                         ok( data.data, "JSON results returned (GET, no callback)" );
1316                         plus();
1317                 },
1318                 error: function(data){
1319                         ok( false, "Ajax error JSON (GET, no callback)" );
1320                         plus();
1321                 }
1322         });
1323
1324         jQuery.ajax({
1325                 url: base + "data/jsonp.php?callback=?",
1326                 dataType: "jsonp",
1327                 success: function(data){
1328                         ok( data.data, "JSON results returned (GET, url callback)" );
1329                         plus();
1330                 },
1331                 error: function(data){
1332                         ok( false, "Ajax error JSON (GET, url callback)" );
1333                         plus();
1334                 }
1335         });
1336
1337         jQuery.ajax({
1338                 url: base + "data/jsonp.php",
1339                 dataType: "jsonp",
1340                 data: "callback=?",
1341                 success: function(data){
1342                         ok( data.data, "JSON results returned (GET, data callback)" );
1343                         plus();
1344                 },
1345                 error: function(data){
1346                         ok( false, "Ajax error JSON (GET, data callback)" );
1347                         plus();
1348                 }
1349         });
1350
1351         jQuery.ajax({
1352                 url: base + "data/jsonp.php",
1353                 dataType: "jsonp",
1354                 jsonp: "callback",
1355                 success: function(data){
1356                         ok( data.data, "JSON results returned (GET, data obj callback)" );
1357                         plus();
1358                 },
1359                 error: function(data){
1360                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1361                         plus();
1362                 }
1363         });
1364 });
1365
1366 test("jQuery.ajax() - script, Remote", function() {
1367         expect(2);
1368
1369         var base = window.location.href.replace(/[^\/]*$/, "");
1370
1371         stop();
1372
1373         jQuery.ajax({
1374                 url: base + "data/test.js",
1375                 dataType: "script",
1376                 success: function(data){
1377                         ok( foobar, "Script results returned (GET, no callback)" );
1378                         start();
1379                 }
1380         });
1381 });
1382
1383 test("jQuery.ajax() - script, Remote with POST", function() {
1384         expect(3);
1385
1386         var base = window.location.href.replace(/[^\/]*$/, "");
1387
1388         stop();
1389
1390         jQuery.ajax({
1391                 url: base + "data/test.js",
1392                 type: "POST",
1393                 dataType: "script",
1394                 success: function(data, status){
1395                         ok( foobar, "Script results returned (POST, no callback)" );
1396                         equals( status, "success", "Script results returned (POST, no callback)" );
1397                         start();
1398                 },
1399                 error: function(xhr) {
1400                         ok( false, "ajax error, status code: " + xhr.status );
1401                         start();
1402                 }
1403         });
1404 });
1405
1406 test("jQuery.ajax() - script, Remote with scheme-less URL", function() {
1407         expect(2);
1408
1409         var base = window.location.href.replace(/[^\/]*$/, "");
1410         base = base.replace(/^.*?\/\//, "//");
1411
1412         stop();
1413
1414         jQuery.ajax({
1415                 url: base + "data/test.js",
1416                 dataType: "script",
1417                 success: function(data){
1418                         ok( foobar, "Script results returned (GET, no callback)" );
1419                         start();
1420                 }
1421         });
1422 });
1423
1424 test("jQuery.ajax() - malformed JSON", function() {
1425         expect(2);
1426
1427         stop();
1428
1429         jQuery.ajax({
1430                 url: "data/badjson.js",
1431                 dataType: "json",
1432                 success: function(){
1433                         ok( false, "Success." );
1434                         start();
1435                 },
1436                 error: function(xhr, msg, detailedMsg) {
1437                         equals( "parsererror", msg, "A parse error occurred." );
1438                         ok( /^Invalid JSON/.test(detailedMsg), "Detailed parsererror message provided" );
1439                         start();
1440                 }
1441         });
1442 });
1443
1444 test("jQuery.ajax() - script by content-type", function() {
1445         expect(1);
1446
1447         stop();
1448
1449         jQuery.ajax({
1450                 url: "data/script.php",
1451                 data: { header: "script" },
1452                 success: function() {
1453                         start();
1454                 }
1455         });
1456 });
1457
1458 test("jQuery.ajax() - json by content-type", function() {
1459         expect(5);
1460
1461         stop();
1462
1463         jQuery.ajax({
1464                 url: "data/json.php",
1465                 data: { header: "json", json: "array" },
1466                 success: function( json ) {
1467                         ok( json.length >= 2, "Check length");
1468                         equals( json[0].name, 'John', 'Check JSON: first, name' );
1469                         equals( json[0].age, 21, 'Check JSON: first, age' );
1470                         equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1471                         equals( json[1].age, 25, 'Check JSON: second, age' );
1472                         start();
1473                 }
1474         });
1475 });
1476
1477 test("jQuery.ajax() - json by content-type disabled with options", function() {
1478         expect(6);
1479
1480         stop();
1481
1482         jQuery.ajax({
1483                 url: url("data/json.php"),
1484                 data: { header: "json", json: "array" },
1485                 autoDataType: {
1486                         json: false
1487                 },
1488                 success: function( text ) {
1489                         equals( typeof text , "string" , "json wasn't auto-determined" );
1490                         var json = this.dataConverters["text => json"]( text );
1491                         ok( json.length >= 2, "Check length");
1492                         equals( json[0].name, 'John', 'Check JSON: first, name' );
1493                         equals( json[0].age, 21, 'Check JSON: first, age' );
1494                         equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1495                         equals( json[1].age, 25, 'Check JSON: second, age' );
1496                         start();
1497                 }
1498         });
1499 });
1500
1501 test("jQuery.getJSON(String, Hash, Function) - JSON array", function() {
1502         expect(5);
1503         stop();
1504         jQuery.getJSON(url("data/json.php"), {json: "array"}, function(json) {
1505           ok( json.length >= 2, "Check length");
1506           equals( json[0].name, 'John', 'Check JSON: first, name' );
1507           equals( json[0].age, 21, 'Check JSON: first, age' );
1508           equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1509           equals( json[1].age, 25, 'Check JSON: second, age' );
1510           start();
1511         });
1512 });
1513
1514 test("jQuery.getJSON(String, Function) - JSON object", function() {
1515         expect(2);
1516         stop();
1517         jQuery.getJSON(url("data/json.php"), function(json) {
1518           if (json && json.data) {
1519                   equals( json.data.lang, 'en', 'Check JSON: lang' );
1520                   equals( json.data.length, 25, 'Check JSON: length' );
1521           }
1522           start();
1523         });
1524 });
1525
1526 test("jQuery.getJSON - Using Native JSON", function() {
1527         expect(2);
1528
1529         var old = window.JSON;
1530         JSON = {
1531                 parse: function(str){
1532                         ok( true, "Verifying that parse method was run" );
1533                         return true;
1534                 }
1535         };
1536
1537         stop();
1538         jQuery.getJSON(url("data/json.php"), function(json) {
1539                 window.JSON = old;
1540                 equals( json, true, "Verifying return value" );
1541                 start();
1542         });
1543 });
1544
1545 test("jQuery.getJSON(String, Function) - JSON object with absolute url to local content", function() {
1546         expect(2);
1547
1548         var base = window.location.href.replace(/[^\/]*$/, "");
1549
1550         stop();
1551         jQuery.getJSON(url(base + "data/json.php"), function(json) {
1552           equals( json.data.lang, 'en', 'Check JSON: lang' );
1553           equals( json.data.length, 25, 'Check JSON: length' );
1554           start();
1555         });
1556 });
1557
1558 test("jQuery.post - data", function() {
1559         expect(2);
1560         stop();
1561
1562         jQuery.post(url("data/name.php"), {xml: "5-2", length: 3}, function(xml){
1563                 jQuery('math', xml).each(function() {
1564                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1565                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1566                 });
1567                 start();
1568         });
1569 });
1570
1571 test("jQuery.post(String, Hash, Function) - simple with xml", function() {
1572         expect(4);
1573         stop();
1574         var done = 0;
1575
1576         jQuery.post(url("data/name.php"), {xml: "5-2"}, function(xml){
1577           jQuery('math', xml).each(function() {
1578                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1579                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1580                  });
1581           if ( ++done === 2 ) start();
1582         });
1583
1584         jQuery.post(url("data/name.php?xml=5-2"), {}, function(xml){
1585           jQuery('math', xml).each(function() {
1586                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1587                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1588                  });
1589           if ( ++done === 2 ) start();
1590         });
1591 });
1592
1593 test("jQuery.ajaxSetup({timeout: Number}) - with global timeout", function() {
1594         stop();
1595
1596         var passed = 0;
1597
1598         jQuery.ajaxSetup({timeout: 1000});
1599
1600         var pass = function() {
1601                 passed++;
1602                 if ( passed == 2 ) {
1603                         ok( true, 'Check local and global callbacks after timeout' );
1604                         jQuery('#main').unbind("ajaxError");
1605                         start();
1606                 }
1607         };
1608
1609         var fail = function(a,b,c) {
1610                 ok( false, 'Check for timeout failed ' + a + ' ' + b );
1611                 start();
1612         };
1613
1614         jQuery('#main').ajaxError(pass);
1615
1616         jQuery.ajax({
1617           type: "GET",
1618           url: url("data/name.php?wait=5"),
1619           error: pass,
1620           success: fail
1621         });
1622
1623         // reset timeout
1624         jQuery.ajaxSetup({timeout: 0});
1625 });
1626
1627 test("jQuery.ajaxSetup({timeout: Number}) with localtimeout", function() {
1628         stop();
1629         jQuery.ajaxSetup({timeout: 50});
1630
1631         jQuery.ajax({
1632           type: "GET",
1633           timeout: 15000,
1634           url: url("data/name.php?wait=1"),
1635           error: function() {
1636                    ok( false, 'Check for local timeout failed' );
1637                    start();
1638           },
1639           success: function() {
1640                 ok( true, 'Check for local timeout' );
1641                 start();
1642           }
1643         });
1644
1645         // reset timeout
1646         jQuery.ajaxSetup({timeout: 0});
1647 });
1648
1649 test("jQuery.ajax - simple get", function() {
1650         expect(1);
1651         stop();
1652         jQuery.ajax({
1653           type: "GET",
1654           url: url("data/name.php?name=foo"),
1655           success: function(msg){
1656                 equals( msg, 'bar', 'Check for GET' );
1657                 start();
1658           }
1659         });
1660 });
1661
1662 test("jQuery.ajax - simple post", function() {
1663         expect(1);
1664         stop();
1665         jQuery.ajax({
1666           type: "POST",
1667           url: url("data/name.php"),
1668           data: "name=peter",
1669           success: function(msg){
1670                 equals( msg, 'pan', 'Check for POST' );
1671                 start();
1672           }
1673         });
1674 });
1675
1676 test("ajaxSetup()", function() {
1677         expect(1);
1678         stop();
1679         jQuery.ajaxSetup({
1680                 url: url("data/name.php?name=foo"),
1681                 success: function(msg){
1682                         equals( msg, 'bar', 'Check for GET' );
1683                         start();
1684                 }
1685         });
1686         jQuery.ajax();
1687 });
1688
1689 /*
1690 test("custom timeout does not set error message when timeout occurs, see #970", function() {
1691         stop();
1692         jQuery.ajax({
1693                 url: "data/name.php?wait=1",
1694                 timeout: 500,
1695                 error: function(request, status) {
1696                         ok( status != null, "status shouldn't be null in error handler" );
1697                         equals( "timeout", status );
1698                         start();
1699                 }
1700         });
1701 });
1702 */
1703
1704 test("data option: evaluate function values (#2806)", function() {
1705         stop();
1706         jQuery.ajax({
1707                 url: "data/echoQuery.php",
1708                 data: {
1709                         key: function() {
1710                                 return "value";
1711                         }
1712                 },
1713                 success: function(result) {
1714                         equals( result, "key=value" );
1715                         start();
1716                 }
1717         })
1718 });
1719
1720 test("data option: empty bodies for non-GET requests", function() {
1721         stop();
1722         jQuery.ajax({
1723                 url: "data/echoData.php",
1724                 data: undefined,
1725                 type: "post",
1726                 success: function(result) {
1727                         equals( result, "" );
1728                         start();
1729                 }
1730         })
1731 });
1732
1733 test("jQuery.ajax - If-Modified-Since support", function() {
1734         expect( 3 );
1735
1736         stop();
1737
1738         var url = "data/if_modified_since.php?ts=" + new Date();
1739
1740         jQuery.ajax({
1741                 url: url,
1742                 ifModified: true,
1743                 success: function(data, status) {
1744                         equals(status, "success");
1745
1746                         jQuery.ajax({
1747                                 url: url,
1748                                 ifModified: true,
1749                                 success: function(data, status) {
1750                                         if ( data === "FAIL" ) {
1751                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1752                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1753                                         } else {
1754                                                 equals(status, "notmodified");
1755                                                 ok(data == null, "response body should be empty")
1756                                         }
1757                                         start();
1758                         },
1759                                 error: function() {
1760                                         // Do this because opera simply refuses to implement 304 handling :(
1761                                         // A feature-driven way of detecting this would be appreciated
1762                                         // See: http://gist.github.com/599419
1763                                         ok(jQuery.browser.opera, "error");
1764                                         ok(jQuery.browser.opera, "error");
1765                                         start();
1766                         }
1767                         });
1768                 },
1769                 error: function() {
1770                         equals(false, "error");
1771                         // Do this because opera simply refuses to implement 304 handling :(
1772                         // A feature-driven way of detecting this would be appreciated
1773                         // See: http://gist.github.com/599419
1774                         ok(jQuery.browser.opera, "error");
1775                         start();
1776                 }
1777         });
1778 });
1779
1780 test("jQuery.ajax - Etag support", function() {
1781         expect( 3 );
1782
1783         stop();
1784
1785         var url = "data/etag.php?ts=" + new Date();
1786
1787         jQuery.ajax({
1788                 url: url,
1789                 ifModified: true,
1790                 success: function(data, status) {
1791                         equals(status, "success");
1792
1793                         jQuery.ajax({
1794                                 url: url,
1795                                 ifModified: true,
1796                                 success: function(data, status) {
1797                                         if ( data === "FAIL" ) {
1798                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1799                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1800                                         } else {
1801                                                 equals(status, "notmodified");
1802                                                 ok(data == null, "response body should be empty")
1803                                         }
1804                                         start();
1805                         },
1806                         error: function() {
1807                                         // Do this because opera simply refuses to implement 304 handling :(
1808                                         // A feature-driven way of detecting this would be appreciated
1809                                         // See: http://gist.github.com/599419
1810                                         ok(jQuery.browser.opera, "error");
1811                                         ok(jQuery.browser.opera, "error");
1812                                         start();
1813                                 }
1814                         });
1815                 },
1816                 error: function() {
1817                         // Do this because opera simply refuses to implement 304 handling :(
1818                         // A feature-driven way of detecting this would be appreciated
1819                         // See: http://gist.github.com/599419
1820                         ok(jQuery.browser.opera, "error");
1821                         start();
1822                 }
1823         });
1824 });
1825
1826 test("jQuery ajax - failing cross-domain", function() {
1827
1828         expect( 2 );
1829
1830         stop();
1831
1832         var i = 2;
1833
1834         jQuery.ajax({
1835                 url: 'http://somewebsitethatdoesnotexist.com',
1836                 success: function(){ ok( false , "success" ); },
1837                 error: function(xhr,_,e){ ok( true , "file not found: " + xhr.status + " => " + e ); },
1838                 complete: function() { if ( ! --i ) start(); }
1839         });
1840
1841         jQuery.ajax({
1842                 url: 'http://www.google.com',
1843                 success: function(){ ok( false , "success" ); },
1844                 error: function(xhr,_,e){ ok( true , "access denied: " + xhr.status + " => " + e ); },
1845                 complete: function() { if ( ! --i ) start(); }
1846         });
1847
1848 });
1849
1850 test("jQuery ajax - atom+xml", function() {
1851
1852         stop();
1853
1854         jQuery.ajax({
1855                 url: url( 'data/atom+xml.php' ),
1856                 success: function(){ ok( true , "success" ); },
1857                 error: function(){ ok( false , "error" ); },
1858                 complete: function() { start(); }
1859         });
1860
1861 });
1862
1863 test("jQuery.ajax - active counter", function() {
1864     ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
1865 });
1866
1867 test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
1868         var success = false;
1869         try {
1870                 var xhr = jQuery.ajax({ url: window.location });
1871                 success = true;
1872                 xhr.abort();
1873         } catch (e) {}
1874
1875         ok( success, "document.location did not generate exception" );
1876 });
1877
1878 }
1879
1880 //}