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