Don't set the context in .load() as it stops the global ajax events from firing....
[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         setTimeout(function(){
18                 jQuery('#foo').ajaxStart(function(){
19                         ok( true, "ajaxStart" );
20                 }).ajaxStop(function(){
21                         ok( true, "ajaxStop" );
22                         start();
23                 }).ajaxSend(function(){
24                         ok( true, "ajaxSend" );
25                 }).ajaxComplete(function(){
26                         ok( true, "ajaxComplete" );
27                 }).ajaxError(function(){
28                         ok( false, "ajaxError" );
29                 }).ajaxSuccess(function(){
30                         ok( true, "ajaxSuccess" );
31                 });
32
33                 jQuery.ajax({
34                         url: url("data/name.html"),
35                         beforeSend: function(){ ok(true, "beforeSend"); },
36                         success: function(){ ok(true, "success"); },
37                         error: function(){ ok(false, "error"); },
38                         complete: function(){ ok(true, "complete"); }
39                 });
40         }, 13);
41 });
42
43 test("jQuery.ajax() - error callbacks", function() {
44         expect( 8 );
45         stop();
46
47         jQuery('#foo').ajaxStart(function(){
48                 ok( true, "ajaxStart" );
49         }).ajaxStop(function(){
50                 ok( true, "ajaxStop" );
51                 start();
52         }).ajaxSend(function(){
53                 ok( true, "ajaxSend" );
54         }).ajaxComplete(function(){
55                 ok( true, "ajaxComplete" );
56         }).ajaxError(function(){
57                 ok( true, "ajaxError" );
58         }).ajaxSuccess(function(){
59                 ok( false, "ajaxSuccess" );
60         });
61
62         jQuery.ajaxSetup({ timeout: 500 });
63
64         jQuery.ajax({
65                 url: url("data/name.php?wait=5"),
66                 beforeSend: function(){ ok(true, "beforeSend"); },
67                 success: function(){ ok(false, "success"); },
68                 error: function(){ ok(true, "error"); },
69                 complete: function(){ ok(true, "complete"); }
70         });
71 });
72
73 test(".load()) - 404 error callbacks", function() {
74         expect( 6 );
75         stop();
76
77         jQuery('#foo').ajaxStart(function(){
78                 ok( true, "ajaxStart" );
79         }).ajaxStop(function(){
80                 ok( true, "ajaxStop" );
81                 start();
82         }).ajaxSend(function(){
83                 ok( true, "ajaxSend" );
84         }).ajaxComplete(function(){
85                 ok( true, "ajaxComplete" );
86         }).ajaxError(function(){
87                 ok( true, "ajaxError" );
88         }).ajaxSuccess(function(){
89                 ok( false, "ajaxSuccess" );
90         });
91
92         jQuery("<div/>").load("data/404.html", function(){
93                 ok(true, "complete");
94         });
95 });
96
97 test("jQuery.ajax() - abort", function() {
98         expect( 6 );
99         stop();
100
101         jQuery('#foo').ajaxStart(function(){
102                 ok( true, "ajaxStart" );
103         }).ajaxStop(function(){
104                 ok( true, "ajaxStop" );
105                 start();
106         }).ajaxSend(function(){
107                 ok( true, "ajaxSend" );
108         }).ajaxComplete(function(){
109                 ok( true, "ajaxComplete" );
110         });
111
112         var xhr = jQuery.ajax({
113                 url: url("data/name.php?wait=5"),
114                 beforeSend: function(){ ok(true, "beforeSend"); },
115                 complete: function(){ ok(true, "complete"); }
116         });
117
118         xhr.abort();
119 });
120
121 test("Ajax events with context", function() {
122         expect(14);
123         
124         stop();
125         var context = document.createElement("div");
126         
127         function event(e){
128                 equals( this, context, e.type );
129         }
130
131         function callback(msg){
132                 return function(){
133                         equals( this, context, "context is preserved on callback " + msg );
134                 };
135         }
136
137         function nocallback(msg){
138                 return function(){
139                         equals( typeof this.url, "string", "context is settings on callback " + msg );
140                 };
141         }
142         
143         jQuery('#foo').add(context)
144                         .ajaxSend(event)
145                         .ajaxComplete(event)
146                         .ajaxError(event)
147                         .ajaxSuccess(event);
148
149         jQuery.ajax({
150                 url: url("data/name.html"),
151                 beforeSend: callback("beforeSend"),
152                 success: callback("success"),
153                 error: callback("error"),
154                 complete:function(){
155                         callback("complete").call(this);
156
157                         jQuery.ajax({
158                                 url: url("data/404.html"),
159                                 context: context,
160                                 beforeSend: callback("beforeSend"),
161                                 error: callback("error"),
162                                 complete: function(){
163                                         callback("complete").call(this);
164
165                                         jQuery('#foo').add(context).unbind();
166
167                                         jQuery.ajax({
168                                                 url: url("data/404.html"),
169                                                 beforeSend: nocallback("beforeSend"),
170                                                 error: nocallback("error"),
171                                                 complete: function(){
172                                                         nocallback("complete").call(this);
173                                                         start();
174                                                 }
175                                         });
176                                 }
177                         });
178                 },
179                 context:context
180         });
181 });
182
183 test("jQuery.ajax() - disabled globals", function() {
184         expect( 3 );
185         stop();
186
187         jQuery('#foo').ajaxStart(function(){
188                 ok( false, "ajaxStart" );
189         }).ajaxStop(function(){
190                 ok( false, "ajaxStop" );
191         }).ajaxSend(function(){
192                 ok( false, "ajaxSend" );
193         }).ajaxComplete(function(){
194                 ok( false, "ajaxComplete" );
195         }).ajaxError(function(){
196                 ok( false, "ajaxError" );
197         }).ajaxSuccess(function(){
198                 ok( false, "ajaxSuccess" );
199         });
200
201         jQuery.ajax({
202                 global: false,
203                 url: url("data/name.html"),
204                 beforeSend: function(){ ok(true, "beforeSend"); },
205                 success: function(){ ok(true, "success"); },
206                 error: function(){ ok(false, "error"); },
207                 complete: function(){
208                   ok(true, "complete");
209                   setTimeout(function(){ start(); }, 13);
210                 }
211         });
212 });
213
214 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", function() {
215         expect(3);
216         stop();
217         jQuery.ajax({
218           url: url("data/with_fries.xml"),
219           dataType: "xml",
220           success: function(resp) {
221                 equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
222                 equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
223                 equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
224                 start();
225           }
226         });
227 });
228
229 test("jQuery.ajax - beforeSend", function() {
230         expect(1);
231         stop();
232
233         var check = false;
234
235         jQuery.ajaxSetup({ timeout: 0 });
236
237         jQuery.ajax({
238                 url: url("data/name.html"),
239                 beforeSend: function(xml) {
240                         check = true;
241                 },
242                 success: function(data) {
243                         ok( check, "check beforeSend was executed" );
244                         start();
245                 }
246         });
247 });
248
249 test("jQuery.ajax - beforeSend, cancel request (#2688)", function() {
250         expect(2);
251         var request = jQuery.ajax({
252                 url: url("data/name.html"),
253                 beforeSend: function() {
254                         ok( true, "beforeSend got called, canceling" );
255                         return false;
256                 },
257                 success: function() {
258                         ok( false, "request didn't get canceled" );
259                 },
260                 complete: function() {
261                         ok( false, "request didn't get canceled" );
262                 },
263                 error: function() {
264                         ok( false, "request didn't get canceled" );
265                 }
266         });
267         ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
268 });
269
270 window.foobar = null;
271 window.testFoo = undefined;
272
273 test("jQuery.ajax - dataType html", function() {
274         expect(5);
275         stop();
276
277         var verifyEvaluation = function() {
278                 equals( testFoo, "foo", 'Check if script was evaluated for datatype html' );
279                 equals( foobar, "bar", 'Check if script src was evaluated for datatype html' );
280
281                 start();
282         };
283
284         jQuery.ajax({
285           dataType: "html",
286           url: url("data/test.html"),
287           success: function(data) {
288                 jQuery("#ap").html(data);
289                 ok( data.match(/^html text/), 'Check content for datatype html' );
290                 setTimeout(verifyEvaluation, 600);
291           }
292         });
293 });
294
295 test("serialize()", function() {
296         expect(5);
297
298         // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers
299         jQuery("#search").after(
300                 '<input type="email" id="html5email" name="email" value="dave@jquery.com" />'+
301                 '<input type="number" id="html5number" name="number" value="43" />'
302         );
303
304         equals( jQuery('#form').serialize(),
305                 "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",
306                 'Check form serialization as query string');
307
308         equals( jQuery('#form :input').serialize(),
309                 "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",
310                 'Check input serialization as query string');
311
312         equals( jQuery('#testForm').serialize(),
313                 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
314                 'Check form serialization as query string');
315
316         equals( jQuery('#testForm :input').serialize(),
317                 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
318                 'Check input serialization as query string');
319
320         equals( jQuery('#form, #testForm').serialize(),
321                 "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=",
322                 'Multiple form serialization as query string');
323
324   /* Temporarily disabled. Opera 10 has problems with form serialization.
325         equals( jQuery('#form, #testForm :input').serialize(),
326                 "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=",
327                 'Mixed form/input serialization as query string');
328         */
329         jQuery("#html5email, #html5number").remove();
330 });
331
332 test("jQuery.param()", function() {
333         expect(18);
334         
335   equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" );
336   
337         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
338         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
339
340         params = {someName: [1, 2, 3], regularThing: "blah" };
341         equals( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3&regularThing=blah", "with array" );
342
343         params = {foo: ['a', 'b', 'c']};
344         equals( jQuery.param(params), "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c", "with array of strings" );
345
346         params = {foo: ["baz", 42, "All your base are belong to us"] };
347         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
348
349         params = {foo: { bar: 'baz', beep: 42, quux: 'All your base are belong to us' } };
350         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" );
351         
352         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?" };
353         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" );
354         
355         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 ] };
356         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" );
357         
358         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?" };
359         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" );
360         
361         jQuery.ajaxSetup({ traditional: true });
362         
363         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
364         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
365
366         params = {someName: [1, 2, 3], regularThing: "blah" };
367         equals( jQuery.param(params), "someName=1&someName=2&someName=3&regularThing=blah", "with array" );
368
369         params = {foo: ['a', 'b', 'c']};
370         equals( jQuery.param(params), "foo=a&foo=b&foo=c", "with array of strings" );
371
372         params = {"foo[]":["baz", 42, "All your base are belong to us"]};
373         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
374
375         params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
376         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" );
377         
378         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?" };
379         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" );
380         
381         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 ] };
382         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)" );
383         
384         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?" };
385         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" );
386         
387         params = { param1: null };
388         equals( jQuery.param(params,false), "param1=null", "Make sure that null params aren't traversed." );
389 });
390
391 test("synchronous request", function() {
392         expect(1);
393         ok( /^{ "data"/.test( jQuery.ajax({url: url("data/json_obj.js"), dataType: "text", async: false}).responseText ), "check returned text" );
394 });
395
396 test("synchronous request with callbacks", function() {
397         expect(2);
398         var result;
399         jQuery.ajax({url: url("data/json_obj.js"), async: false, dataType: "text", success: function(data) { ok(true, "sucess callback executed"); result = data; } });
400         ok( /^{ "data"/.test( result ), "check returned text" );
401 });
402
403 test("pass-through request object", function() {
404         expect(8);
405         stop();
406
407         var target = "data/name.html";
408         var successCount = 0;
409         var errorCount = 0;
410         var errorEx = "";
411         var success = function() {
412                 successCount++;
413         };
414         jQuery("#foo").ajaxError(function (e, xml, s, ex) {
415                 errorCount++;
416                 errorEx += ": " + xml.status;
417         });
418         jQuery("#foo").one('ajaxStop', function () {
419                 equals(successCount, 5, "Check all ajax calls successful");
420                 equals(errorCount, 0, "Check no ajax errors (status" + errorEx + ")");
421                 jQuery("#foo").unbind('ajaxError');
422
423                 start();
424         });
425
426         ok( jQuery.get(url(target), success), "get" );
427         ok( jQuery.post(url(target), success), "post" );
428         ok( jQuery.getScript(url("data/test.js"), success), "script" );
429         ok( jQuery.getJSON(url("data/json_obj.js"), success), "json" );
430         ok( jQuery.ajax({url: url(target), success: success}), "generic" );
431 });
432
433 test("ajax cache", function () {
434         expect(18);
435         
436         stop();
437
438         var count = 0;
439
440         jQuery("#firstp").bind("ajaxSuccess", function (e, xml, s) {
441                 var re = /_=(.*?)(&|$)/g;
442                 var oldOne = null;
443                 for (var i = 0; i < 6; i++) {
444                         var ret = re.exec(s.url);
445                         if (!ret) {
446                                 break;
447                         }
448                         oldOne = ret[1];
449                 }
450                 equals(i, 1, "Test to make sure only one 'no-cache' parameter is there");
451                 ok(oldOne != "tobereplaced555", "Test to be sure parameter (if it was there) was replaced");
452                 if(++count == 6)
453                         start();
454         });
455
456         ok( jQuery.ajax({url: "data/text.php", cache:false}), "test with no parameters" );
457         ok( jQuery.ajax({url: "data/text.php?pizza=true", cache:false}), "test with 1 parameter" );
458         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555", cache:false}), "test with _= parameter" );
459         ok( jQuery.ajax({url: "data/text.php?pizza=true&_=tobereplaced555", cache:false}), "test with 1 parameter plus _= one" );
460         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555&tv=false", cache:false}), "test with 1 parameter plus _= one before it" );
461         ok( jQuery.ajax({url: "data/text.php?name=David&_=tobereplaced555&washere=true", cache:false}), "test with 2 parameters surrounding _= one" );
462 });
463
464 /*
465  * Test disabled.
466  * The assertions expect that the passed-in object will be modified,
467  * which shouldn't be the case. Fixes #5439.
468 test("global ajaxSettings", function() {
469         expect(2);
470
471         var tmp = jQuery.extend({}, jQuery.ajaxSettings);
472         var orig = { url: "data/with_fries.xml" };
473         var t;
474
475         jQuery.ajaxSetup({ data: {foo: 'bar', bar: 'BAR'} });
476
477         t = jQuery.extend({}, orig);
478         t.data = {};
479         jQuery.ajax(t);
480         ok( t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending {}" );
481
482         t = jQuery.extend({}, orig);
483         t.data = { zoo: 'a', ping: 'b' };
484         jQuery.ajax(t);
485         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' }" );
486
487         jQuery.ajaxSettings = tmp;
488 });
489 */
490
491 test("load(String)", function() {
492         expect(1);
493         stop(); // check if load can be called with only url
494         jQuery('#first').load("data/name.html", start);
495 });
496
497 test("load('url selector')", function() {
498         expect(1);
499         stop(); // check if load can be called with only url
500         jQuery('#first').load("data/test3.html div.user", function(){
501                 equals( jQuery(this).children("div").length, 2, "Verify that specific elements were injected" );
502                 start();
503         });
504 });
505
506 test("load(String, Function) with ajaxSetup on dataType json, see #2046", function() {
507         expect(1);
508         stop();
509         jQuery.ajaxSetup({ dataType: "json" });
510         jQuery("#first").ajaxComplete(function (e, xml, s) {
511                 equals( s.dataType, "html", "Verify the load() dataType was html" );
512                 jQuery("#first").unbind("ajaxComplete");
513                 jQuery.ajaxSetup({ dataType: "" });
514                 start();
515         });
516         jQuery('#first').load("data/test3.html");
517 });
518
519 test("load(String, Function) - simple: inject text into DOM", function() {
520         expect(2);
521         stop();
522         jQuery('#first').load(url("data/name.html"), function() {
523                 ok( /^ERROR/.test(jQuery('#first').text()), 'Check if content was injected into the DOM' );
524                 start();
525         });
526 });
527
528 test("load(String, Function) - check scripts", function() {
529         expect(7);
530         stop();
531
532         var verifyEvaluation = function() {
533                 equals( foobar, "bar", 'Check if script src was evaluated after load' );
534                 equals( jQuery('#ap').html(), 'bar', 'Check if script evaluation has modified DOM');
535
536                 start();
537         };
538         jQuery('#first').load(url('data/test.html'), function() {
539                 ok( jQuery('#first').html().match(/^html text/), 'Check content after loading html' );
540                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
541                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
542                 setTimeout(verifyEvaluation, 600);
543         });
544 });
545
546 test("load(String, Function) - check file with only a script tag", function() {
547         expect(3);
548         stop();
549
550         jQuery('#first').load(url('data/test2.html'), function() {
551                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
552                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
553
554                 start();
555         });
556 });
557
558 test("load(String, Object, Function)", function() {
559         expect(2);
560         stop();
561
562         jQuery('<div />').load(url('data/params_html.php'), { foo:3, bar:'ok' }, function() {
563                 var $post = jQuery(this).find('#post');
564                 equals( $post.find('#foo').text(), '3', 'Check if a hash of data is passed correctly');
565                 equals( $post.find('#bar').text(), 'ok', 'Check if a hash of data is passed correctly');
566                 start();
567         });
568 });
569
570 test("load(String, String, Function)", function() {
571         expect(2);
572         stop();
573
574         jQuery('<div />').load(url('data/params_html.php'), 'foo=3&bar=ok', function() {
575                 var $get = jQuery(this).find('#get');
576                 equals( $get.find('#foo').text(), '3', 'Check if a string of data is passed correctly');
577                 equals( $get.find('#bar').text(), 'ok', 'Check if a      of data is passed correctly');
578                 start();
579         });
580 });
581
582 test("jQuery.get(String, Hash, Function) - parse xml and use text() on nodes", function() {
583         expect(2);
584         stop();
585         jQuery.get(url('data/dashboard.xml'), function(xml) {
586                 var content = [];
587                 jQuery('tab', xml).each(function() {
588                         content.push(jQuery(this).text());
589                 });
590                 equals( content[0], 'blabla', 'Check first tab');
591                 equals( content[1], 'blublu', 'Check second tab');
592                 start();
593         });
594 });
595
596 test("jQuery.getScript(String, Function) - with callback", function() {
597         expect(2);
598         stop();
599         jQuery.getScript(url("data/test.js"), function() {
600                 equals( foobar, "bar", 'Check if script was evaluated' );
601                 setTimeout(start, 100);
602         });
603 });
604
605 test("jQuery.getScript(String, Function) - no callback", function() {
606         expect(1);
607         stop();
608         jQuery.getScript(url("data/test.js"), function(){
609                 start();
610         });
611 });
612
613 test("jQuery.ajax() - JSONP, Local", function() {
614         expect(8);
615
616         var count = 0;
617         function plus(){ if ( ++count == 8 ) start(); }
618
619         stop();
620
621         jQuery.ajax({
622                 url: "data/jsonp.php",
623                 dataType: "jsonp",
624                 success: function(data){
625                         ok( data.data, "JSON results returned (GET, no callback)" );
626                         plus();
627                 },
628                 error: function(data){
629                         ok( false, "Ajax error JSON (GET, no callback)" );
630                         plus();
631                 }
632         });
633
634         jQuery.ajax({
635                 url: "data/jsonp.php?callback=?",
636                 dataType: "jsonp",
637                 success: function(data){
638                         ok( data.data, "JSON results returned (GET, url callback)" );
639                         plus();
640                 },
641                 error: function(data){
642                         ok( false, "Ajax error JSON (GET, url callback)" );
643                         plus();
644                 }
645         });
646
647         jQuery.ajax({
648                 url: "data/jsonp.php",
649                 dataType: "jsonp",
650                 data: "callback=?",
651                 success: function(data){
652                         ok( data.data, "JSON results returned (GET, data callback)" );
653                         plus();
654                 },
655                 error: function(data){
656                         ok( false, "Ajax error JSON (GET, data callback)" );
657                         plus();
658                 }
659         });
660
661         jQuery.ajax({
662                 url: "data/jsonp.php",
663                 dataType: "jsonp",
664                 jsonp: "callback",
665                 success: function(data){
666                         ok( data.data, "JSON results returned (GET, data obj callback)" );
667                         plus();
668                 },
669                 error: function(data){
670                         ok( false, "Ajax error JSON (GET, data obj callback)" );
671                         plus();
672                 }
673         });
674
675         jQuery.ajax({
676                 url: "data/jsonp.php",
677                 dataType: "jsonp",
678                 jsonpCallback: "jsonpResults",
679                 success: function(data){
680                         ok( data.data, "JSON results returned (GET, custom callback name)" );
681                         plus();
682                 },
683                 error: function(data){
684                         ok( false, "Ajax error JSON (GET, custom callback name)" );
685                         plus();
686                 }
687         });
688
689         jQuery.ajax({
690                 type: "POST",
691                 url: "data/jsonp.php",
692                 dataType: "jsonp",
693                 success: function(data){
694                         ok( data.data, "JSON results returned (POST, no callback)" );
695                         plus();
696                 },
697                 error: function(data){
698                         ok( false, "Ajax error JSON (GET, data obj callback)" );
699                         plus();
700                 }
701         });
702
703         jQuery.ajax({
704                 type: "POST",
705                 url: "data/jsonp.php",
706                 data: "callback=?",
707                 dataType: "jsonp",
708                 success: function(data){
709                         ok( data.data, "JSON results returned (POST, data callback)" );
710                         plus();
711                 },
712                 error: function(data){
713                         ok( false, "Ajax error JSON (POST, data callback)" );
714                         plus();
715                 }
716         });
717
718         jQuery.ajax({
719                 type: "POST",
720                 url: "data/jsonp.php",
721                 jsonp: "callback",
722                 dataType: "jsonp",
723                 success: function(data){
724                         ok( data.data, "JSON results returned (POST, data obj callback)" );
725                         plus();
726                 },
727                 error: function(data){
728                         ok( false, "Ajax error JSON (POST, data obj callback)" );
729                         plus();
730                 }
731         });
732 });
733
734 test("JSONP - Custom JSONP Callback", function() {
735         expect(1);
736         stop();
737
738         window.jsonpResults = function(data) {
739                 ok( data.data, "JSON results returned (GET, custom callback function)" );
740                 start();
741         };
742
743         jQuery.ajax({
744                 url: "data/jsonp.php",
745                 dataType: "jsonp",
746                 jsonpCallback: "jsonpResults"
747         });
748 });
749
750 test("jQuery.ajax() - JSONP, Remote", function() {
751         expect(4);
752
753         var count = 0;
754         function plus(){ if ( ++count == 4 ) start(); }
755
756         var base = window.location.href.replace(/\?.*$/, "");
757
758         stop();
759
760         jQuery.ajax({
761                 url: base + "data/jsonp.php",
762                 dataType: "jsonp",
763                 success: function(data){
764                         ok( data.data, "JSON results returned (GET, no callback)" );
765                         plus();
766                 },
767                 error: function(data){
768                         ok( false, "Ajax error JSON (GET, no callback)" );
769                         plus();
770                 }
771         });
772
773         jQuery.ajax({
774                 url: base + "data/jsonp.php?callback=?",
775                 dataType: "jsonp",
776                 success: function(data){
777                         ok( data.data, "JSON results returned (GET, url callback)" );
778                         plus();
779                 },
780                 error: function(data){
781                         ok( false, "Ajax error JSON (GET, url callback)" );
782                         plus();
783                 }
784         });
785
786         jQuery.ajax({
787                 url: base + "data/jsonp.php",
788                 dataType: "jsonp",
789                 data: "callback=?",
790                 success: function(data){
791                         ok( data.data, "JSON results returned (GET, data callback)" );
792                         plus();
793                 },
794                 error: function(data){
795                         ok( false, "Ajax error JSON (GET, data callback)" );
796                         plus();
797                 }
798         });
799
800         jQuery.ajax({
801                 url: base + "data/jsonp.php",
802                 dataType: "jsonp",
803                 jsonp: "callback",
804                 success: function(data){
805                         ok( data.data, "JSON results returned (GET, data obj callback)" );
806                         plus();
807                 },
808                 error: function(data){
809                         ok( false, "Ajax error JSON (GET, data obj callback)" );
810                         plus();
811                 }
812         });
813 });
814
815 test("jQuery.ajax() - script, Remote", function() {
816         expect(2);
817
818         var base = window.location.href.replace(/\?.*$/, "");
819
820         stop();
821
822         jQuery.ajax({
823                 url: base + "data/test.js",
824                 dataType: "script",
825                 success: function(data){
826                         ok( foobar, "Script results returned (GET, no callback)" );
827                         start();
828                 }
829         });
830 });
831
832 test("jQuery.ajax() - script, Remote with POST", function() {
833         expect(3);
834
835         var base = window.location.href.replace(/\?.*$/, "");
836
837         stop();
838
839         jQuery.ajax({
840                 url: base + "data/test.js",
841                 type: "POST",
842                 dataType: "script",
843                 success: function(data, status){
844                         ok( foobar, "Script results returned (POST, no callback)" );
845                         equals( status, "success", "Script results returned (POST, no callback)" );
846                         start();
847                 },
848                 error: function(xhr) {
849                         ok( false, "ajax error, status code: " + xhr.status );
850                         start();
851                 }
852         });
853 });
854
855 test("jQuery.ajax() - script, Remote with scheme-less URL", function() {
856         expect(2);
857
858         var base = window.location.href.replace(/\?.*$/, "");
859         base = base.replace(/^.*?\/\//, "//");
860
861         stop();
862
863         jQuery.ajax({
864                 url: base + "data/test.js",
865                 dataType: "script",
866                 success: function(data){
867                         ok( foobar, "Script results returned (GET, no callback)" );
868                         start();
869                 }
870         });
871 });
872
873 test("jQuery.ajax() - malformed JSON", function() {
874         expect(1);
875
876         stop();
877
878         jQuery.ajax({
879                 url: "data/badjson.js",
880                 dataType: "json",
881                 success: function(){
882                         ok( false, "Success." );
883                         start();
884                 },
885                 error: function(xhr, msg) {
886                         equals( "parsererror", msg, "A parse error occurred." );
887                         start();
888                 }
889         });
890 });
891
892 test("jQuery.ajax() - script by content-type", function() {
893         expect(1);
894
895         stop();
896
897         jQuery.ajax({
898                 url: "data/script.php",
899                 data: { header: "script" },
900                 success: function() {
901                         start();
902                 }
903         });
904 });
905
906 test("jQuery.ajax() - json by content-type", function() {
907         expect(5);
908
909         stop();
910
911         jQuery.ajax({
912                 url: "data/json.php",
913                 data: { header: "json", json: "array" },
914                 success: function( json ) {
915                         ok( json.length >= 2, "Check length");
916                         equals( json[0].name, 'John', 'Check JSON: first, name' );
917                         equals( json[0].age, 21, 'Check JSON: first, age' );
918                         equals( json[1].name, 'Peter', 'Check JSON: second, name' );
919                         equals( json[1].age, 25, 'Check JSON: second, age' );
920                         start();
921                 }
922         });
923 });
924
925 test("jQuery.getJSON(String, Hash, Function) - JSON array", function() {
926         expect(5);
927         stop();
928         jQuery.getJSON(url("data/json.php"), {json: "array"}, function(json) {
929           ok( json.length >= 2, "Check length");
930           equals( json[0].name, 'John', 'Check JSON: first, name' );
931           equals( json[0].age, 21, 'Check JSON: first, age' );
932           equals( json[1].name, 'Peter', 'Check JSON: second, name' );
933           equals( json[1].age, 25, 'Check JSON: second, age' );
934           start();
935         });
936 });
937
938 test("jQuery.getJSON(String, Function) - JSON object", function() {
939         expect(2);
940         stop();
941         jQuery.getJSON(url("data/json.php"), function(json) {
942           if (json && json.data) {
943                   equals( json.data.lang, 'en', 'Check JSON: lang' );
944                   equals( json.data.length, 25, 'Check JSON: length' );
945           }
946           start();
947         });
948 });
949
950 test("jQuery.getJSON - Using Native JSON", function() {
951         expect(2);
952         
953         var old = window.JSON;
954         JSON = {
955                 parse: function(str){
956                         ok( true, "Verifying that parse method was run" );
957                         return true;
958                 }
959         };
960
961         stop();
962         jQuery.getJSON(url("data/json.php"), function(json) {
963                 window.JSON = old;
964                 equals( json, true, "Verifying return value" );
965                 start();
966         });
967 });
968
969 test("jQuery.getJSON(String, Function) - JSON object with absolute url to local content", function() {
970         expect(2);
971
972         var base = window.location.href.replace(/\?.*$/, "");
973
974         stop();
975         jQuery.getJSON(url(base + "data/json.php"), function(json) {
976           equals( json.data.lang, 'en', 'Check JSON: lang' );
977           equals( json.data.length, 25, 'Check JSON: length' );
978           start();
979         });
980 });
981
982 test("jQuery.post(String, Hash, Function) - simple with xml", function() {
983         expect(4);
984         stop();
985         var done = 0;
986
987         jQuery.post(url("data/name.php"), {xml: "5-2"}, function(xml){
988           jQuery('math', xml).each(function() {
989                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
990                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
991                  });
992           if ( ++done === 2 ) start();
993         });
994
995         jQuery.post(url("data/name.php?xml=5-2"), {}, function(xml){
996           jQuery('math', xml).each(function() {
997                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
998                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
999                  });
1000           if ( ++done === 2 ) start();
1001         });
1002 });
1003
1004 test("jQuery.ajaxSetup({timeout: Number}) - with global timeout", function() {
1005         stop();
1006
1007         var passed = 0;
1008
1009         jQuery.ajaxSetup({timeout: 1000});
1010
1011         var pass = function() {
1012                 passed++;
1013                 if ( passed == 2 ) {
1014                         ok( true, 'Check local and global callbacks after timeout' );
1015                         jQuery('#main').unbind("ajaxError");
1016                         start();
1017                 }
1018         };
1019
1020         var fail = function(a,b,c) {
1021                 ok( false, 'Check for timeout failed ' + a + ' ' + b );
1022                 start();
1023         };
1024
1025         jQuery('#main').ajaxError(pass);
1026
1027         jQuery.ajax({
1028           type: "GET",
1029           url: url("data/name.php?wait=5"),
1030           error: pass,
1031           success: fail
1032         });
1033
1034         // reset timeout
1035         jQuery.ajaxSetup({timeout: 0});
1036 });
1037
1038 test("jQuery.ajaxSetup({timeout: Number}) with localtimeout", function() {
1039         stop();
1040         jQuery.ajaxSetup({timeout: 50});
1041
1042         jQuery.ajax({
1043           type: "GET",
1044           timeout: 15000,
1045           url: url("data/name.php?wait=1"),
1046           error: function() {
1047                    ok( false, 'Check for local timeout failed' );
1048                    start();
1049           },
1050           success: function() {
1051                 ok( true, 'Check for local timeout' );
1052                 start();
1053           }
1054         });
1055
1056         // reset timeout
1057         jQuery.ajaxSetup({timeout: 0});
1058 });
1059
1060 test("jQuery.ajax - simple get", function() {
1061         expect(1);
1062         stop();
1063         jQuery.ajax({
1064           type: "GET",
1065           url: url("data/name.php?name=foo"),
1066           success: function(msg){
1067                 equals( msg, 'bar', 'Check for GET' );
1068                 start();
1069           }
1070         });
1071 });
1072
1073 test("jQuery.ajax - simple post", function() {
1074         expect(1);
1075         stop();
1076         jQuery.ajax({
1077           type: "POST",
1078           url: url("data/name.php"),
1079           data: "name=peter",
1080           success: function(msg){
1081                 equals( msg, 'pan', 'Check for POST' );
1082                 start();
1083           }
1084         });
1085 });
1086
1087 test("ajaxSetup()", function() {
1088         expect(1);
1089         stop();
1090         jQuery.ajaxSetup({
1091                 url: url("data/name.php?name=foo"),
1092                 success: function(msg){
1093                         equals( msg, 'bar', 'Check for GET' );
1094                         start();
1095                 }
1096         });
1097         jQuery.ajax();
1098 });
1099
1100 /*
1101 test("custom timeout does not set error message when timeout occurs, see #970", function() {
1102         stop();
1103         jQuery.ajax({
1104                 url: "data/name.php?wait=1",
1105                 timeout: 500,
1106                 error: function(request, status) {
1107                         ok( status != null, "status shouldn't be null in error handler" );
1108                         equals( "timeout", status );
1109                         start();
1110                 }
1111         });
1112 });
1113 */
1114
1115 test("data option: evaluate function values (#2806)", function() {
1116         stop();
1117         jQuery.ajax({
1118                 url: "data/echoQuery.php",
1119                 data: {
1120                         key: function() {
1121                                 return "value";
1122                         }
1123                 },
1124                 success: function(result) {
1125                         equals( result, "key=value" );
1126                         start();
1127                 }
1128         })
1129 });
1130
1131 test("jQuery.ajax - If-Modified-Since support", function() {
1132         expect( 3 );
1133
1134         stop();
1135
1136         var url = "data/if_modified_since.php?ts=" + new Date();
1137
1138         jQuery.ajax({
1139                 url: url,
1140                 ifModified: true,
1141                 success: function(data, status) { 
1142                         equals(status, "success");
1143                         
1144                         jQuery.ajax({
1145                                 url: url,
1146                                 ifModified: true,
1147                                 success: function(data, status) { 
1148                                         if ( data === "FAIL" ) {
1149                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1150                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1151                                         } else {
1152                                                 equals(status, "notmodified");
1153                                                 ok(data == null, "response body should be empty")
1154                                         }
1155                                         start();
1156                                 }
1157                         });
1158                 }
1159         });
1160 });
1161
1162 test("jQuery.ajax - Etag support", function() {
1163         expect( 3 );
1164
1165         stop();
1166
1167         var url = "data/etag.php?ts=" + new Date();
1168
1169         jQuery.ajax({
1170                 url: url,
1171                 ifModified: true,
1172                 success: function(data, status) { 
1173                         equals(status, "success");
1174                         
1175                         jQuery.ajax({
1176                                 url: url,
1177                                 ifModified: true,
1178                                 success: function(data, status) { 
1179                                         if ( data === "FAIL" ) {
1180                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1181                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1182                                         } else {
1183                                                 equals(status, "notmodified");
1184                                                 ok(data == null, "response body should be empty")
1185                                         }
1186                                         start();
1187                                 }
1188                         });
1189                 }
1190         });
1191 });
1192
1193 }
1194
1195 //}