Removed re-usability from jXHR object (no more open, send & onreadystatechange suppor...
[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 : 4 );
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(false, "error"); },
106                         complete: function(){ ok(supports, "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("Ajax events with context", function() {
413         expect(14);
414
415         stop();
416         var context = document.createElement("div");
417
418         function event(e){
419                 equals( this, context, e.type );
420         }
421
422         function callback(msg){
423                 return function(){
424                         equals( this, context, "context is preserved on callback " + msg );
425                 };
426         }
427
428         function nocallback(msg){
429                 return function(){
430                         equals( typeof this.url, "string", "context is settings on callback " + msg );
431                 };
432         }
433
434         jQuery('#foo').add(context)
435                         .ajaxSend(event)
436                         .ajaxComplete(event)
437                         .ajaxError(event)
438                         .ajaxSuccess(event);
439
440         jQuery.ajax({
441                 url: url("data/name.html"),
442                 beforeSend: callback("beforeSend"),
443                 success: callback("success"),
444                 error: callback("error"),
445                 complete:function(){
446                         callback("complete").call(this);
447
448                         jQuery.ajax({
449                                 url: url("data/404.html"),
450                                 context: context,
451                                 beforeSend: callback("beforeSend"),
452                                 error: callback("error"),
453                                 complete: function(){
454                                         callback("complete").call(this);
455
456                                         jQuery('#foo').add(context).unbind();
457
458                                         jQuery.ajax({
459                                                 url: url("data/404.html"),
460                                                 beforeSend: nocallback("beforeSend"),
461                                                 error: nocallback("error"),
462                                                 complete: function(){
463                                                         nocallback("complete").call(this);
464                                                         start();
465                                                 }
466                                         });
467                                 }
468                         });
469                 },
470                 context:context
471         });
472 });
473
474 test("jQuery.ajax context modification", function() {
475         expect(1);
476
477         stop();
478
479         var obj = {}
480
481         jQuery.ajax({
482                 url: url("data/name.html"),
483                 context: obj,
484                 beforeSend: function(){
485                         this.test = "foo";
486                 },
487                 complete: function() {
488                         start();
489                 }
490         });
491
492         equals( obj.test, "foo", "Make sure the original object is maintained." );
493 });
494
495 test("jQuery.ajax() - disabled globals", function() {
496         expect( 3 );
497         stop();
498
499         jQuery('#foo').ajaxStart(function(){
500                 ok( false, "ajaxStart" );
501         }).ajaxStop(function(){
502                 ok( false, "ajaxStop" );
503         }).ajaxSend(function(){
504                 ok( false, "ajaxSend" );
505         }).ajaxComplete(function(){
506                 ok( false, "ajaxComplete" );
507         }).ajaxError(function(){
508                 ok( false, "ajaxError" );
509         }).ajaxSuccess(function(){
510                 ok( false, "ajaxSuccess" );
511         });
512
513         jQuery.ajax({
514                 global: false,
515                 url: url("data/name.html"),
516                 beforeSend: function(){ ok(true, "beforeSend"); },
517                 success: function(){ ok(true, "success"); },
518                 error: function(){ ok(false, "error"); },
519                 complete: function(){
520                   ok(true, "complete");
521                   setTimeout(function(){ start(); }, 13);
522                 }
523         });
524 });
525
526 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", function() {
527         expect(3);
528         stop();
529         jQuery.ajax({
530           url: url("data/with_fries.xml"),
531           dataType: "xml",
532           success: function(resp) {
533                 equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
534                 equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
535                 equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
536                 start();
537           }
538         });
539 });
540
541 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements (over JSONP)", function() {
542         expect(3);
543         stop();
544         jQuery.ajax({
545           url: url("data/with_fries_over_jsonp.php"),
546           dataType: "jsonp xml",
547           success: function(resp) {
548                 equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
549                 equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
550                 equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
551                 start();
552           },
553           error: function(_1,_2,error) {
554                 ok( false, error );
555                 start();
556           }
557         });
558 });
559
560 test("jQuery.ajax - HEAD requests", function() {
561         expect(2);
562
563         stop();
564         jQuery.ajax({
565                 url: url("data/name.html"),
566                 type: "HEAD",
567                 success: function(data, status, xhr){
568                         var h = xhr.getAllResponseHeaders();
569                         ok( /Date/i.test(h), 'No Date in HEAD response' );
570
571                         jQuery.ajax({
572                                 url: url("data/name.html"),
573                                 data: { whip_it: "good" },
574                                 type: "HEAD",
575                                 success: function(data, status, xhr){
576                                         var h = xhr.getAllResponseHeaders();
577                                         ok( /Date/i.test(h), 'No Date in HEAD response with data' );
578                                         start();
579                                 }
580                         });
581                 }
582         });
583
584 });
585
586 test("jQuery.ajax - beforeSend", function() {
587         expect(1);
588         stop();
589
590         var check = false;
591
592         jQuery.ajaxSetup({ timeout: 0 });
593
594         jQuery.ajax({
595                 url: url("data/name.html"),
596                 beforeSend: function(xml) {
597                         check = true;
598                 },
599                 success: function(data) {
600                         ok( check, "check beforeSend was executed" );
601                         start();
602                 }
603         });
604 });
605
606 test("jQuery.ajax - beforeSend, cancel request (#2688)", function() {
607         expect(2);
608         var request = jQuery.ajax({
609                 url: url("data/name.html"),
610                 beforeSend: function() {
611                         ok( true, "beforeSend got called, canceling" );
612                         return false;
613                 },
614                 success: function() {
615                         ok( false, "request didn't get canceled" );
616                 },
617                 complete: function() {
618                         ok( false, "request didn't get canceled" );
619                 },
620                 error: function() {
621                         ok( false, "request didn't get canceled" );
622                 }
623         });
624         ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
625 });
626
627 test("jQuery.ajax - beforeSend, cancel request manually", function() {
628         expect(2);
629         var request = jQuery.ajax({
630                 url: url("data/name.html"),
631                 beforeSend: function(xhr) {
632                         ok( true, "beforeSend got called, canceling" );
633                         xhr.abort();
634                 },
635                 success: function() {
636                         ok( false, "request didn't get canceled" );
637                 },
638                 complete: function() {
639                         ok( false, "request didn't get canceled" );
640                 },
641                 error: function() {
642                         ok( false, "request didn't get canceled" );
643                 }
644         });
645         ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
646 });
647
648 window.foobar = null;
649 window.testFoo = undefined;
650
651 test("jQuery.ajax - dataType html", function() {
652         expect(5);
653         stop();
654
655         var verifyEvaluation = function() {
656                 equals( testFoo, "foo", 'Check if script was evaluated for datatype html' );
657                 equals( foobar, "bar", 'Check if script src was evaluated for datatype html' );
658
659                 start();
660         };
661
662         jQuery.ajax({
663           dataType: "html",
664           url: url("data/test.html"),
665           success: function(data) {
666                 jQuery("#ap").html(data);
667                 ok( data.match(/^html text/), 'Check content for datatype html' );
668                 setTimeout(verifyEvaluation, 600);
669           }
670         });
671 });
672
673 test("serialize()", function() {
674         expect(5);
675
676         // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers
677         jQuery("#search").after(
678                 '<input type="email" id="html5email" name="email" value="dave@jquery.com" />'+
679                 '<input type="number" id="html5number" name="number" value="43" />'
680         );
681
682         equals( jQuery('#form').serialize(),
683                 "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",
684                 'Check form serialization as query string');
685
686         equals( jQuery('#form :input').serialize(),
687                 "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",
688                 'Check input serialization as query string');
689
690         equals( jQuery('#testForm').serialize(),
691                 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
692                 'Check form serialization as query string');
693
694         equals( jQuery('#testForm :input').serialize(),
695                 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
696                 'Check input serialization as query string');
697
698         equals( jQuery('#form, #testForm').serialize(),
699                 "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=",
700                 'Multiple form serialization as query string');
701
702   /* Temporarily disabled. Opera 10 has problems with form serialization.
703         equals( jQuery('#form, #testForm :input').serialize(),
704                 "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=",
705                 'Mixed form/input serialization as query string');
706         */
707         jQuery("#html5email, #html5number").remove();
708 });
709
710 test("jQuery.param()", function() {
711         expect(22);
712
713         equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" );
714
715         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
716         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
717
718         params = {someName: [1, 2, 3], regularThing: "blah" };
719         equals( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3&regularThing=blah", "with array" );
720
721         params = {foo: ['a', 'b', 'c']};
722         equals( jQuery.param(params), "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c", "with array of strings" );
723
724         params = {foo: ["baz", 42, "All your base are belong to us"] };
725         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
726
727         params = {foo: { bar: 'baz', beep: 42, quux: 'All your base are belong to us' } };
728         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" );
729
730         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?" };
731         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" );
732
733         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 ] };
734         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" );
735
736         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?" };
737         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" );
738
739         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." );
740
741         // Make sure empty arrays and objects are handled #6481
742         equals( jQuery.param({"foo": {"bar": []} }), "foo%5Bbar%5D=", "Empty array param" );
743         equals( jQuery.param({"foo": {"bar": [], foo: 1} }), "foo%5Bbar%5D=&foo%5Bfoo%5D=1", "Empty array param" );
744         equals( jQuery.param({"foo": {"bar": {}} }), "foo%5Bbar%5D=", "Empty object param" );
745
746         jQuery.ajaxSetup({ traditional: true });
747
748         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
749         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
750
751         params = {someName: [1, 2, 3], regularThing: "blah" };
752         equals( jQuery.param(params), "someName=1&someName=2&someName=3&regularThing=blah", "with array" );
753
754         params = {foo: ['a', 'b', 'c']};
755         equals( jQuery.param(params), "foo=a&foo=b&foo=c", "with array of strings" );
756
757         params = {"foo[]":["baz", 42, "All your base are belong to us"]};
758         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
759
760         params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
761         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" );
762
763         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?" };
764         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" );
765
766         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 ] };
767         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)" );
768
769         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?" };
770         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" );
771
772         params = { param1: null };
773         equals( jQuery.param(params,false), "param1=null", "Make sure that null params aren't traversed." );
774 });
775
776 test("synchronous request", function() {
777         expect(1);
778         ok( /^{ "data"/.test( jQuery.ajax({url: url("data/json_obj.js"), dataType: "text", async: false}).responseText ), "check returned text" );
779 });
780
781 test("synchronous request with callbacks", function() {
782         expect(2);
783         var result;
784         jQuery.ajax({url: url("data/json_obj.js"), async: false, dataType: "text", success: function(data) { ok(true, "sucess callback executed"); result = data; } });
785         ok( /^{ "data"/.test( result ), "check returned text" );
786 });
787
788 test("pass-through request object", function() {
789         expect(8);
790         stop();
791
792         var target = "data/name.html";
793         var successCount = 0;
794         var errorCount = 0;
795         var errorEx = "";
796         var success = function() {
797                 successCount++;
798         };
799         jQuery("#foo").ajaxError(function (e, xml, s, ex) {
800                 errorCount++;
801                 errorEx += ": " + xml.status;
802         });
803         jQuery("#foo").one('ajaxStop', function () {
804                 equals(successCount, 5, "Check all ajax calls successful");
805                 equals(errorCount, 0, "Check no ajax errors (status" + errorEx + ")");
806                 jQuery("#foo").unbind('ajaxError');
807
808                 start();
809         });
810
811         ok( jQuery.get(url(target), success), "get" );
812         ok( jQuery.post(url(target), success), "post" );
813         ok( jQuery.getScript(url("data/test.js"), success), "script" );
814         ok( jQuery.getJSON(url("data/json_obj.js"), success), "json" );
815         ok( jQuery.ajax({url: url(target), success: success}), "generic" );
816 });
817
818 test("ajax cache", function () {
819         expect(18);
820
821         stop();
822
823         var count = 0;
824
825         jQuery("#firstp").bind("ajaxSuccess", function (e, xml, s) {
826                 var re = /_=(.*?)(&|$)/g;
827                 var oldOne = null;
828                 for (var i = 0; i < 6; i++) {
829                         var ret = re.exec(s.url);
830                         if (!ret) {
831                                 break;
832                         }
833                         oldOne = ret[1];
834                 }
835                 equals(i, 1, "Test to make sure only one 'no-cache' parameter is there");
836                 ok(oldOne != "tobereplaced555", "Test to be sure parameter (if it was there) was replaced");
837                 if(++count == 6)
838                         start();
839         });
840
841         ok( jQuery.ajax({url: "data/text.php", cache:false}), "test with no parameters" );
842         ok( jQuery.ajax({url: "data/text.php?pizza=true", cache:false}), "test with 1 parameter" );
843         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555", cache:false}), "test with _= parameter" );
844         ok( jQuery.ajax({url: "data/text.php?pizza=true&_=tobereplaced555", cache:false}), "test with 1 parameter plus _= one" );
845         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555&tv=false", cache:false}), "test with 1 parameter plus _= one before it" );
846         ok( jQuery.ajax({url: "data/text.php?name=David&_=tobereplaced555&washere=true", cache:false}), "test with 2 parameters surrounding _= one" );
847 });
848
849 /*
850  * Test disabled.
851  * The assertions expect that the passed-in object will be modified,
852  * which shouldn't be the case. Fixes #5439.
853 test("global ajaxSettings", function() {
854         expect(2);
855
856         var tmp = jQuery.extend({}, jQuery.ajaxSettings);
857         var orig = { url: "data/with_fries.xml" };
858         var t;
859
860         jQuery.ajaxSetup({ data: {foo: 'bar', bar: 'BAR'} });
861
862         t = jQuery.extend({}, orig);
863         t.data = {};
864         jQuery.ajax(t);
865         ok( t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending {}" );
866
867         t = jQuery.extend({}, orig);
868         t.data = { zoo: 'a', ping: 'b' };
869         jQuery.ajax(t);
870         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' }" );
871
872         jQuery.ajaxSettings = tmp;
873 });
874 */
875
876 test("load(String)", function() {
877         expect(1);
878         stop(); // check if load can be called with only url
879         jQuery('#first').load("data/name.html", start);
880 });
881
882 test("load('url selector')", function() {
883         expect(1);
884         stop(); // check if load can be called with only url
885         jQuery('#first').load("data/test3.html div.user", function(){
886                 equals( jQuery(this).children("div").length, 2, "Verify that specific elements were injected" );
887                 start();
888         });
889 });
890
891 test("load(String, Function) with ajaxSetup on dataType json, see #2046", function() {
892         expect(1);
893         stop();
894         jQuery.ajaxSetup({ dataType: "json" });
895         jQuery("#first").ajaxComplete(function (e, xml, s) {
896                 equals( s.dataType, "html", "Verify the load() dataType was html" );
897                 jQuery("#first").unbind("ajaxComplete");
898                 jQuery.ajaxSetup({ dataType: "" });
899                 start();
900         });
901         jQuery('#first').load("data/test3.html");
902 });
903
904 test("load(String, Function) - simple: inject text into DOM", function() {
905         expect(2);
906         stop();
907         jQuery('#first').load(url("data/name.html"), function() {
908                 ok( /^ERROR/.test(jQuery('#first').text()), 'Check if content was injected into the DOM' );
909                 start();
910         });
911 });
912
913 test("load(String, Function) - check scripts", function() {
914         expect(7);
915         stop();
916
917         var verifyEvaluation = function() {
918                 equals( foobar, "bar", 'Check if script src was evaluated after load' );
919                 equals( jQuery('#ap').html(), 'bar', 'Check if script evaluation has modified DOM');
920
921                 start();
922         };
923         jQuery('#first').load(url('data/test.html'), function() {
924                 ok( jQuery('#first').html().match(/^html text/), 'Check content after loading html' );
925                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
926                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
927                 setTimeout(verifyEvaluation, 600);
928         });
929 });
930
931 test("load(String, Function) - check file with only a script tag", function() {
932         expect(3);
933         stop();
934
935         jQuery('#first').load(url('data/test2.html'), function() {
936                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
937                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
938
939                 start();
940         });
941 });
942
943 test("load(String, Object, Function)", function() {
944         expect(2);
945         stop();
946
947         jQuery('<div />').load(url('data/params_html.php'), { foo:3, bar:'ok' }, function() {
948                 var $post = jQuery(this).find('#post');
949                 equals( $post.find('#foo').text(), '3', 'Check if a hash of data is passed correctly');
950                 equals( $post.find('#bar').text(), 'ok', 'Check if a hash of data is passed correctly');
951                 start();
952         });
953 });
954
955 test("load(String, String, Function)", function() {
956         expect(2);
957         stop();
958
959         jQuery('<div />').load(url('data/params_html.php'), 'foo=3&bar=ok', function() {
960                 var $get = jQuery(this).find('#get');
961                 equals( $get.find('#foo').text(), '3', 'Check if a string of data is passed correctly');
962                 equals( $get.find('#bar').text(), 'ok', 'Check if a      of data is passed correctly');
963                 start();
964         });
965 });
966
967 test("jQuery.get(String, Hash, Function) - parse xml and use text() on nodes", function() {
968         expect(2);
969         stop();
970         jQuery.get(url('data/dashboard.xml'), function(xml) {
971                 var content = [];
972                 jQuery('tab', xml).each(function() {
973                         content.push(jQuery(this).text());
974                 });
975                 equals( content[0], 'blabla', 'Check first tab');
976                 equals( content[1], 'blublu', 'Check second tab');
977                 start();
978         });
979 });
980
981 test("jQuery.getScript(String, Function) - with callback", function() {
982         expect(2);
983         stop();
984         jQuery.getScript(url("data/test.js"), function() {
985                 equals( foobar, "bar", 'Check if script was evaluated' );
986                 setTimeout(start, 100);
987         });
988 });
989
990 test("jQuery.getScript(String, Function) - no callback", function() {
991         expect(1);
992         stop();
993         jQuery.getScript(url("data/test.js"), function(){
994                 start();
995         });
996 });
997
998 test("jQuery.ajax() - JSONP, Local", function() {
999         expect(9);
1000
1001         var count = 0;
1002         function plus(){ if ( ++count == 9 ) start(); }
1003
1004         stop();
1005
1006         jQuery.ajax({
1007                 url: "data/jsonp.php",
1008                 dataType: "jsonp",
1009                 success: function(data){
1010                         ok( data.data, "JSON results returned (GET, no callback)" );
1011                         plus();
1012                 },
1013                 error: function(data){
1014                         ok( false, "Ajax error JSON (GET, no callback)" );
1015                         plus();
1016                 }
1017         });
1018
1019         jQuery.ajax({
1020                 url: "data/jsonp.php?callback=?",
1021                 dataType: "jsonp",
1022                 success: function(data){
1023                         ok( data.data, "JSON results returned (GET, url callback)" );
1024                         plus();
1025                 },
1026                 error: function(data){
1027                         ok( false, "Ajax error JSON (GET, url callback)" );
1028                         plus();
1029                 }
1030         });
1031
1032         jQuery.ajax({
1033                 url: "data/jsonp.php",
1034                 dataType: "jsonp",
1035                 data: "callback=?",
1036                 success: function(data){
1037                         ok( data.data, "JSON results returned (GET, data callback)" );
1038                         plus();
1039                 },
1040                 error: function(data){
1041                         ok( false, "Ajax error JSON (GET, data callback)" );
1042                         plus();
1043                 }
1044         });
1045
1046         jQuery.ajax({
1047                 url: "data/jsonp.php",
1048                 dataType: "jsonp",
1049                 jsonp: "callback",
1050                 success: function(data){
1051                         ok( data.data, "JSON results returned (GET, data obj callback)" );
1052                         plus();
1053                 },
1054                 error: function(data){
1055                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1056                         plus();
1057                 }
1058         });
1059
1060         jQuery.ajax({
1061                 url: "data/jsonp.php",
1062                 dataType: "jsonp",
1063                 jsonpCallback: "jsonpResults",
1064                 success: function(data){
1065                         ok( data.data, "JSON results returned (GET, custom callback name)" );
1066                         plus();
1067                 },
1068                 error: function(data){
1069                         ok( false, "Ajax error JSON (GET, custom callback name)" );
1070                         plus();
1071                 }
1072         });
1073
1074         jQuery.ajax({
1075                 type: "POST",
1076                 url: "data/jsonp.php",
1077                 dataType: "jsonp",
1078                 success: function(data){
1079                         ok( data.data, "JSON results returned (POST, no callback)" );
1080                         plus();
1081                 },
1082                 error: function(data){
1083                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1084                         plus();
1085                 }
1086         });
1087
1088         jQuery.ajax({
1089                 type: "POST",
1090                 url: "data/jsonp.php",
1091                 data: "callback=?",
1092                 dataType: "jsonp",
1093                 success: function(data){
1094                         ok( data.data, "JSON results returned (POST, data callback)" );
1095                         plus();
1096                 },
1097                 error: function(data){
1098                         ok( false, "Ajax error JSON (POST, data callback)" );
1099                         plus();
1100                 }
1101         });
1102
1103         jQuery.ajax({
1104                 type: "POST",
1105                 url: "data/jsonp.php",
1106                 jsonp: "callback",
1107                 dataType: "jsonp",
1108                 success: function(data){
1109                         ok( data.data, "JSON results returned (POST, data obj callback)" );
1110                         plus();
1111                 },
1112                 error: function(data){
1113                         ok( false, "Ajax error JSON (POST, data obj callback)" );
1114                         plus();
1115                 }
1116         });
1117
1118         //#7578
1119         jQuery.ajax({
1120                 url: "data/jsonp.php",
1121                 dataType: "jsonp",
1122                 beforeSend: function(){
1123                         strictEqual( this.cache, false, "cache must be false on JSON request" );
1124                         plus();
1125                         return false;
1126                 }
1127         });
1128 });
1129
1130 test("jQuery.ajax() - JSONP - Custom JSONP Callback", function() {
1131         expect(1);
1132         stop();
1133
1134         window.jsonpResults = function(data) {
1135                 ok( data.data, "JSON results returned (GET, custom callback function)" );
1136                 window.jsonpResults = undefined;
1137                 start();
1138         };
1139
1140         jQuery.ajax({
1141                 url: "data/jsonp.php",
1142                 dataType: "jsonp",
1143                 jsonpCallback: "jsonpResults"
1144         });
1145 });
1146
1147 test("jQuery.ajax() - JSONP, Remote", function() {
1148         expect(4);
1149
1150         var count = 0;
1151         function plus(){ if ( ++count == 4 ) start(); }
1152
1153         var base = window.location.href.replace(/[^\/]*$/, "");
1154
1155         stop();
1156
1157         jQuery.ajax({
1158                 url: base + "data/jsonp.php",
1159                 dataType: "jsonp",
1160                 success: function(data){
1161                         ok( data.data, "JSON results returned (GET, no callback)" );
1162                         plus();
1163                 },
1164                 error: function(data){
1165                         ok( false, "Ajax error JSON (GET, no callback)" );
1166                         plus();
1167                 }
1168         });
1169
1170         jQuery.ajax({
1171                 url: base + "data/jsonp.php?callback=?",
1172                 dataType: "jsonp",
1173                 success: function(data){
1174                         ok( data.data, "JSON results returned (GET, url callback)" );
1175                         plus();
1176                 },
1177                 error: function(data){
1178                         ok( false, "Ajax error JSON (GET, url callback)" );
1179                         plus();
1180                 }
1181         });
1182
1183         jQuery.ajax({
1184                 url: base + "data/jsonp.php",
1185                 dataType: "jsonp",
1186                 data: "callback=?",
1187                 success: function(data){
1188                         ok( data.data, "JSON results returned (GET, data callback)" );
1189                         plus();
1190                 },
1191                 error: function(data){
1192                         ok( false, "Ajax error JSON (GET, data callback)" );
1193                         plus();
1194                 }
1195         });
1196
1197         jQuery.ajax({
1198                 url: base + "data/jsonp.php",
1199                 dataType: "jsonp",
1200                 jsonp: "callback",
1201                 success: function(data){
1202                         ok( data.data, "JSON results returned (GET, data obj callback)" );
1203                         plus();
1204                 },
1205                 error: function(data){
1206                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1207                         plus();
1208                 }
1209         });
1210 });
1211
1212 test("jQuery.ajax() - script, Remote", function() {
1213         expect(2);
1214
1215         var base = window.location.href.replace(/[^\/]*$/, "");
1216
1217         stop();
1218
1219         jQuery.ajax({
1220                 url: base + "data/test.js",
1221                 dataType: "script",
1222                 success: function(data){
1223                         ok( foobar, "Script results returned (GET, no callback)" );
1224                         start();
1225                 }
1226         });
1227 });
1228
1229 test("jQuery.ajax() - script, Remote with POST", function() {
1230         expect(3);
1231
1232         var base = window.location.href.replace(/[^\/]*$/, "");
1233
1234         stop();
1235
1236         jQuery.ajax({
1237                 url: base + "data/test.js",
1238                 type: "POST",
1239                 dataType: "script",
1240                 success: function(data, status){
1241                         ok( foobar, "Script results returned (POST, no callback)" );
1242                         equals( status, "success", "Script results returned (POST, no callback)" );
1243                         start();
1244                 },
1245                 error: function(xhr) {
1246                         ok( false, "ajax error, status code: " + xhr.status );
1247                         start();
1248                 }
1249         });
1250 });
1251
1252 test("jQuery.ajax() - script, Remote with scheme-less URL", function() {
1253         expect(2);
1254
1255         var base = window.location.href.replace(/[^\/]*$/, "");
1256         base = base.replace(/^.*?\/\//, "//");
1257
1258         stop();
1259
1260         jQuery.ajax({
1261                 url: base + "data/test.js",
1262                 dataType: "script",
1263                 success: function(data){
1264                         ok( foobar, "Script results returned (GET, no callback)" );
1265                         start();
1266                 }
1267         });
1268 });
1269
1270 test("jQuery.ajax() - malformed JSON", function() {
1271         expect(2);
1272
1273         stop();
1274
1275         jQuery.ajax({
1276                 url: "data/badjson.js",
1277                 dataType: "json",
1278                 success: function(){
1279                         ok( false, "Success." );
1280                         start();
1281                 },
1282                 error: function(xhr, msg, detailedMsg) {
1283                         equals( "parsererror", msg, "A parse error occurred." );
1284                         ok( /^Invalid JSON/.test(detailedMsg), "Detailed parsererror message provided" );
1285                         start();
1286                 }
1287         });
1288 });
1289
1290 test("jQuery.ajax() - script by content-type", function() {
1291         expect(1);
1292
1293         stop();
1294
1295         jQuery.ajax({
1296                 url: "data/script.php",
1297                 data: { header: "script" },
1298                 success: function() {
1299                         start();
1300                 }
1301         });
1302 });
1303
1304 test("jQuery.ajax() - json by content-type", function() {
1305         expect(5);
1306
1307         stop();
1308
1309         jQuery.ajax({
1310                 url: "data/json.php",
1311                 data: { header: "json", json: "array" },
1312                 success: function( json ) {
1313                         ok( json.length >= 2, "Check length");
1314                         equals( json[0].name, 'John', 'Check JSON: first, name' );
1315                         equals( json[0].age, 21, 'Check JSON: first, age' );
1316                         equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1317                         equals( json[1].age, 25, 'Check JSON: second, age' );
1318                         start();
1319                 }
1320         });
1321 });
1322
1323 test("jQuery.ajax() - json by content-type disabled with options", function() {
1324         expect(6);
1325
1326         stop();
1327
1328         jQuery.ajax({
1329                 url: url("data/json.php"),
1330                 data: { header: "json", json: "array" },
1331                 autoDataType: {
1332                         json: false
1333                 },
1334                 success: function( text ) {
1335                         equals( typeof text , "string" , "json wasn't auto-determined" );
1336                         var json = this.dataConverters["text json"]( text );
1337                         ok( json.length >= 2, "Check length");
1338                         equals( json[0].name, 'John', 'Check JSON: first, name' );
1339                         equals( json[0].age, 21, 'Check JSON: first, age' );
1340                         equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1341                         equals( json[1].age, 25, 'Check JSON: second, age' );
1342                         start();
1343                 }
1344         });
1345 });
1346
1347 test("jQuery.getJSON(String, Hash, Function) - JSON array", function() {
1348         expect(5);
1349         stop();
1350         jQuery.getJSON(url("data/json.php"), {json: "array"}, function(json) {
1351           ok( json.length >= 2, "Check length");
1352           equals( json[0].name, 'John', 'Check JSON: first, name' );
1353           equals( json[0].age, 21, 'Check JSON: first, age' );
1354           equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1355           equals( json[1].age, 25, 'Check JSON: second, age' );
1356           start();
1357         });
1358 });
1359
1360 test("jQuery.getJSON(String, Function) - JSON object", function() {
1361         expect(2);
1362         stop();
1363         jQuery.getJSON(url("data/json.php"), function(json) {
1364           if (json && json.data) {
1365                   equals( json.data.lang, 'en', 'Check JSON: lang' );
1366                   equals( json.data.length, 25, 'Check JSON: length' );
1367           }
1368           start();
1369         });
1370 });
1371
1372 test("jQuery.getJSON - Using Native JSON", function() {
1373         expect(2);
1374
1375         var old = window.JSON;
1376         JSON = {
1377                 parse: function(str){
1378                         ok( true, "Verifying that parse method was run" );
1379                         return true;
1380                 }
1381         };
1382
1383         stop();
1384         jQuery.getJSON(url("data/json.php"), function(json) {
1385                 window.JSON = old;
1386                 equals( json, true, "Verifying return value" );
1387                 start();
1388         });
1389 });
1390
1391 test("jQuery.getJSON(String, Function) - JSON object with absolute url to local content", function() {
1392         expect(2);
1393
1394         var base = window.location.href.replace(/[^\/]*$/, "");
1395
1396         stop();
1397         jQuery.getJSON(url(base + "data/json.php"), function(json) {
1398           equals( json.data.lang, 'en', 'Check JSON: lang' );
1399           equals( json.data.length, 25, 'Check JSON: length' );
1400           start();
1401         });
1402 });
1403
1404 test("jQuery.post - data", function() {
1405         expect(2);
1406         stop();
1407
1408         jQuery.post(url("data/name.php"), {xml: "5-2", length: 3}, function(xml){
1409                 jQuery('math', xml).each(function() {
1410                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1411                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1412                 });
1413                 start();
1414         });
1415 });
1416
1417 test("jQuery.post(String, Hash, Function) - simple with xml", function() {
1418         expect(4);
1419         stop();
1420         var done = 0;
1421
1422         jQuery.post(url("data/name.php"), {xml: "5-2"}, function(xml){
1423           jQuery('math', xml).each(function() {
1424                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1425                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1426                  });
1427           if ( ++done === 2 ) start();
1428         });
1429
1430         jQuery.post(url("data/name.php?xml=5-2"), {}, function(xml){
1431           jQuery('math', xml).each(function() {
1432                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1433                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1434                  });
1435           if ( ++done === 2 ) start();
1436         });
1437 });
1438
1439 test("jQuery.ajaxSetup({timeout: Number}) - with global timeout", function() {
1440         stop();
1441
1442         var passed = 0;
1443
1444         jQuery.ajaxSetup({timeout: 1000});
1445
1446         var pass = function() {
1447                 passed++;
1448                 if ( passed == 2 ) {
1449                         ok( true, 'Check local and global callbacks after timeout' );
1450                         jQuery('#main').unbind("ajaxError");
1451                         start();
1452                 }
1453         };
1454
1455         var fail = function(a,b,c) {
1456                 ok( false, 'Check for timeout failed ' + a + ' ' + b );
1457                 start();
1458         };
1459
1460         jQuery('#main').ajaxError(pass);
1461
1462         jQuery.ajax({
1463           type: "GET",
1464           url: url("data/name.php?wait=5"),
1465           error: pass,
1466           success: fail
1467         });
1468
1469         // reset timeout
1470         jQuery.ajaxSetup({timeout: 0});
1471 });
1472
1473 test("jQuery.ajaxSetup({timeout: Number}) with localtimeout", function() {
1474         stop();
1475         jQuery.ajaxSetup({timeout: 50});
1476
1477         jQuery.ajax({
1478           type: "GET",
1479           timeout: 15000,
1480           url: url("data/name.php?wait=1"),
1481           error: function() {
1482                    ok( false, 'Check for local timeout failed' );
1483                    start();
1484           },
1485           success: function() {
1486                 ok( true, 'Check for local timeout' );
1487                 start();
1488           }
1489         });
1490
1491         // reset timeout
1492         jQuery.ajaxSetup({timeout: 0});
1493 });
1494
1495 test("jQuery.ajax - simple get", function() {
1496         expect(1);
1497         stop();
1498         jQuery.ajax({
1499           type: "GET",
1500           url: url("data/name.php?name=foo"),
1501           success: function(msg){
1502                 equals( msg, 'bar', 'Check for GET' );
1503                 start();
1504           }
1505         });
1506 });
1507
1508 test("jQuery.ajax - simple post", function() {
1509         expect(1);
1510         stop();
1511         jQuery.ajax({
1512           type: "POST",
1513           url: url("data/name.php"),
1514           data: "name=peter",
1515           success: function(msg){
1516                 equals( msg, 'pan', 'Check for POST' );
1517                 start();
1518           }
1519         });
1520 });
1521
1522 test("ajaxSetup()", function() {
1523         expect(1);
1524         stop();
1525         jQuery.ajaxSetup({
1526                 url: url("data/name.php?name=foo"),
1527                 success: function(msg){
1528                         equals( msg, 'bar', 'Check for GET' );
1529                         start();
1530                 }
1531         });
1532         jQuery.ajax();
1533 });
1534
1535 /*
1536 test("custom timeout does not set error message when timeout occurs, see #970", function() {
1537         stop();
1538         jQuery.ajax({
1539                 url: "data/name.php?wait=1",
1540                 timeout: 500,
1541                 error: function(request, status) {
1542                         ok( status != null, "status shouldn't be null in error handler" );
1543                         equals( "timeout", status );
1544                         start();
1545                 }
1546         });
1547 });
1548 */
1549
1550 test("data option: evaluate function values (#2806)", function() {
1551         stop();
1552         jQuery.ajax({
1553                 url: "data/echoQuery.php",
1554                 data: {
1555                         key: function() {
1556                                 return "value";
1557                         }
1558                 },
1559                 success: function(result) {
1560                         equals( result, "key=value" );
1561                         start();
1562                 }
1563         })
1564 });
1565
1566 test("data option: empty bodies for non-GET requests", function() {
1567         stop();
1568         jQuery.ajax({
1569                 url: "data/echoData.php",
1570                 data: undefined,
1571                 type: "post",
1572                 success: function(result) {
1573                         equals( result, "" );
1574                         start();
1575                 }
1576         })
1577 });
1578
1579 test("jQuery.ajax - If-Modified-Since support", function() {
1580         expect( 3 );
1581
1582         stop();
1583
1584         var url = "data/if_modified_since.php?ts=" + new Date();
1585
1586         jQuery.ajax({
1587                 url: url,
1588                 ifModified: true,
1589                 success: function(data, status) {
1590                         equals(status, "success");
1591
1592                         jQuery.ajax({
1593                                 url: url,
1594                                 ifModified: true,
1595                                 success: function(data, status) {
1596                                         if ( data === "FAIL" ) {
1597                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1598                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1599                                         } else {
1600                                                 equals(status, "notmodified");
1601                                                 ok(data == null, "response body should be empty")
1602                                         }
1603                                         start();
1604                         },
1605                                 error: function() {
1606                                         // Do this because opera simply refuses to implement 304 handling :(
1607                                         // A feature-driven way of detecting this would be appreciated
1608                                         // See: http://gist.github.com/599419
1609                                         ok(jQuery.browser.opera, "error");
1610                                         ok(jQuery.browser.opera, "error");
1611                                         start();
1612                         }
1613                         });
1614                 },
1615                 error: function() {
1616                         equals(false, "error");
1617                         // Do this because opera simply refuses to implement 304 handling :(
1618                         // A feature-driven way of detecting this would be appreciated
1619                         // See: http://gist.github.com/599419
1620                         ok(jQuery.browser.opera, "error");
1621                         start();
1622                 }
1623         });
1624 });
1625
1626 test("jQuery.ajax - Etag support", function() {
1627         expect( 3 );
1628
1629         stop();
1630
1631         var url = "data/etag.php?ts=" + new Date();
1632
1633         jQuery.ajax({
1634                 url: url,
1635                 ifModified: true,
1636                 success: function(data, status) {
1637                         equals(status, "success");
1638
1639                         jQuery.ajax({
1640                                 url: url,
1641                                 ifModified: true,
1642                                 success: function(data, status) {
1643                                         if ( data === "FAIL" ) {
1644                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1645                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1646                                         } else {
1647                                                 equals(status, "notmodified");
1648                                                 ok(data == null, "response body should be empty")
1649                                         }
1650                                         start();
1651                         },
1652                         error: function() {
1653                                         // Do this because opera simply refuses to implement 304 handling :(
1654                                         // A feature-driven way of detecting this would be appreciated
1655                                         // See: http://gist.github.com/599419
1656                                         ok(jQuery.browser.opera, "error");
1657                                         ok(jQuery.browser.opera, "error");
1658                                         start();
1659                                 }
1660                         });
1661                 },
1662                 error: function() {
1663                         // Do this because opera simply refuses to implement 304 handling :(
1664                         // A feature-driven way of detecting this would be appreciated
1665                         // See: http://gist.github.com/599419
1666                         ok(jQuery.browser.opera, "error");
1667                         start();
1668                 }
1669         });
1670 });
1671
1672 test("jQuery ajax - failing cross-domain", function() {
1673
1674         expect( 2 );
1675
1676         stop();
1677
1678         var i = 2;
1679
1680         jQuery.ajax({
1681                 url: 'http://somewebsitethatdoesnotexist.com',
1682                 success: function(){ ok( false , "success" ); },
1683                 error: function(xhr,_,e){ ok( true , "file not found: " + xhr.status + " => " + e ); },
1684                 complete: function() { if ( ! --i ) start(); }
1685         });
1686
1687         jQuery.ajax({
1688                 url: 'http://www.google.com',
1689                 success: function(){ ok( false , "success" ); },
1690                 error: function(xhr,_,e){ ok( true , "access denied: " + xhr.status + " => " + e ); },
1691                 complete: function() { if ( ! --i ) start(); }
1692         });
1693
1694 });
1695
1696 test("jQuery ajax - atom+xml", function() {
1697
1698         stop();
1699
1700         jQuery.ajax({
1701                 url: url( 'data/atom+xml.php' ),
1702                 success: function(){ ok( true , "success" ); },
1703                 error: function(){ ok( false , "error" ); },
1704                 complete: function() { start(); }
1705         });
1706
1707 });
1708
1709 test("jQuery.ajax - active counter", function() {
1710     ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
1711 });
1712
1713 test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
1714         var success = false;
1715         try {
1716                 var xhr = jQuery.ajax({ url: window.location });
1717                 success = true;
1718                 xhr.abort();
1719         } catch (e) {}
1720
1721         ok( success, "document.location did not generate exception" );
1722 });
1723
1724 }
1725
1726 //}