Refactored ajax module: Dropped internal arguments from ajax(); Modified testsuite...
[jquery.git] / build / test / data / testrunner.js
1 var asyncTimeout = 2 // seconds for async timeout
2
3 var fixture;
4 var Test;
5 var stats = {
6         all: 0,
7         bad: 0
8 };
9 var queue = [];
10 var blocking = false;
11 var timeout;
12
13 function synchronize(callback) {
14         queue[queue.length] = callback;
15         if(!blocking) {
16                 process();
17         }
18 }
19
20 function process() {
21         while(queue.length && !blocking) {
22                 var call = queue[0];
23                 queue = queue.slice(1);
24                 call();
25         }
26 }
27
28 function stop() {
29         blocking = true;
30         timeout = setTimeout(start, asyncTimeout * 1000);
31 }
32 function start() {
33         if(timeout)
34                 clearTimeout(timeout);
35         blocking = false;
36         process();
37 }
38
39 function runTest(tests) {
40         var startTime = new Date();
41         fixture = document.getElementById('main').innerHTML;
42         tests();
43         synchronize(function() {
44                 var runTime = new Date() - startTime;
45                 var result = document.createElement("div");
46                                 result.innerHTML = '<p class="result">Tests completed in ' + 
47                         runTime + ' milliseconds.<br/>' +
48                         stats.bad + ' tests of ' + stats.all + ' failed.</p>';
49                 document.getElementsByTagName("body")[0].appendChild(result);
50         });
51 }
52
53 function test(name, callback) {
54         synchronize(function() {
55                 Test = [];
56                 try {
57                         callback();
58                 } catch(e) {
59                         if( typeof console != "undefined" && console.error && console.warn ) {
60                                 console.error("Test " + name + " died, exception and test follows");
61                                 console.error(e);
62                                 console.warn(callback.toString());
63                         }
64                         Test.push( [ false, "Died on test #" + (Test.length+1) + ": " + e ] );
65                 }
66         });
67         synchronize(function() {
68                 reset();
69                 
70                 var good = 0, bad = 0;
71                 var ol = document.createElement("ol");
72                 ol.style.display = "none";
73                 var li = "", state = "pass";
74                 for ( var i = 0; i < Test.length; i++ ) {
75                         var li = document.createElement("li");
76                         li.className = Test[i][0] ? "pass" : "fail";
77                         li.innerHTML = Test[i][1];
78                         ol.appendChild( li );
79                         
80                         stats.all++;
81                         if ( !Test[i][0] ) {
82                                 state = "fail";
83                                 bad++;
84                                 stats.bad++;
85                         } else good++;
86                 }
87         
88                 var li = document.createElement("li");
89                 li.className = state;
90         
91                 var b = document.createElement("b");
92                 b.innerHTML = name + " <b style='color:black;'>(<b class='fail'>" + bad + "</b>, <b class='pass'>" + good + "</b>, " + Test.length + ")</b>";
93                 b.onclick = function(){
94                         var n = this.nextSibling;
95                         if ( jQuery.css( n, "display" ) == "none" )
96                                 n.style.display = "block";
97                         else
98                                 n.style.display = "none";
99                 };
100                 li.appendChild( b );
101                 li.appendChild( ol );
102         
103                 document.getElementById("tests").appendChild( li );             
104         });
105 }
106
107 /**
108  * Resets the test setup. Useful for tests that modify the DOM.
109  */
110 function reset() {
111         document.getElementById('main').innerHTML = fixture;
112 }
113
114 /**
115  * Asserts true.
116  * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
117  */
118 function ok(a, msg) {
119         Test.push( [ !!a, msg ] );
120 }
121
122 /**
123  * Asserts that two arrays are the same
124  */
125 function isSet(a, b, msg) {
126         var ret = true;
127         if ( a && b && a.length == b.length ) {
128                 for ( var i in a )
129                         if ( a[i] != b[i] )
130                                 ret = false;
131         } else
132                 ret = false;
133         if ( !ret )
134                 Test.push( [ ret, msg + " expected: " + b + " result: " + a ] );
135         else 
136                 Test.push( [ ret, msg ] );
137 }
138
139 /**
140  * Returns an array of elements with the given IDs, eg.
141  * @example q("main", "foo", "bar")
142  * @result [<div id="main">, <span id="foo">, <input id="bar">]
143  */
144 function q() {
145         var r = [];
146         for ( var i = 0; i < arguments.length; i++ )
147                 r.push( document.getElementById( arguments[i] ) );
148         return r;
149 }
150
151 /**
152  * Asserts that a select matches the given IDs
153  * @example t("Check for something", "//[a]", ["foo", "baar"]);
154  * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
155  */
156 function t(a,b,c) {
157         var f = jQuery.find(b);
158         var s = "";
159         for ( var i = 0; i < f.length; i++ )
160                 s += (s && ",") + '"' + f[i].id + '"';
161         isSet(f, q.apply(q,c), a + " (" + b + ")");
162 }