1 if (window.layoutTestController) 2 layoutTestController.dumpAsText(); 3 4 function description(msg) 5 { 6 // For MSIE 6 compatibility 7 var span = document.createElement("span"); 8 span.innerHTML = '<p>' + msg + '</p><p>On success, you will see a series of "<span class="pass">PASS</span>" messages, followed by "<span class="pass">TEST COMPLETE</span>".</p>'; 9 var description = document.getElementById("description"); 10 if (description.firstChild) 11 description.replaceChild(span, description.firstChild); 12 else 13 description.appendChild(span); 14 } 15 16 function debug(msg) 17 { 18 var span = document.createElement("span"); 19 document.getElementById("console").appendChild(span); // insert it first so XHTML knows the namespace 20 span.innerHTML = msg + '<br />'; 21 } 22 23 function escapeHTML(text) 24 { 25 return text.replace(/&/g, "&").replace(/</g, "<"); 26 } 27 28 function testPassed(msg) 29 { 30 debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>'); 31 } 32 33 function testFailed(msg) 34 { 35 debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>'); 36 } 37 38 function areArraysEqual(_a, _b) 39 { 40 if (_a.length !== _b.length) 41 return false; 42 for (var i = 0; i < _a.length; i++) 43 if (_a[i] !== _b[i]) 44 return false; 45 return true; 46 } 47 48 function isMinusZero(n) 49 { 50 // the only way to tell 0 from -0 in JS is the fact that 1/-0 is 51 // -Infinity instead of Infinity 52 return n === 0 && 1/n < 0; 53 } 54 55 function isResultCorrect(_actual, _expected) 56 { 57 if (_expected === 0) 58 return _actual === _expected && (1/_actual) === (1/_expected); 59 if (_actual === _expected) 60 return true; 61 if (typeof(_expected) == "number" && isNaN(_expected)) 62 return typeof(_actual) == "number" && isNaN(_actual); 63 if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([])) 64 return areArraysEqual(_actual, _expected); 65 return false; 66 } 67 68 function stringify(v) 69 { 70 if (v === 0 && 1/v < 0) 71 return "-0"; 72 else return "" + v; 73 } 74 75 function shouldBe(_a, _b) 76 { 77 if (typeof _a != "string" || typeof _b != "string") 78 debug("WARN: shouldBe() expects string arguments"); 79 var exception; 80 var _av; 81 try { 82 _av = eval(_a); 83 } catch (e) { 84 exception = e; 85 } 86 var _bv = eval(_b); 87 88 if (exception) 89 testFailed(_a + " should be " + _bv + ". Threw exception " + exception); 90 else if (isResultCorrect(_av, _bv)) 91 testPassed(_a + " is " + _b); 92 else if (typeof(_av) == typeof(_bv)) 93 testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + "."); 94 else 95 testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ")."); 96 } 97 98 function shouldBeTrue(_a) { shouldBe(_a, "true"); } 99 function shouldBeFalse(_a) { shouldBe(_a, "false"); } 100 function shouldBeNaN(_a) { shouldBe(_a, "NaN"); } 101 function shouldBeNull(_a) { shouldBe(_a, "null"); } 102 103 function shouldBeEqualToString(a, b) 104 { 105 var unevaledString = '"' + b.replace(/"/g, "\"") + '"'; 106 shouldBe(a, unevaledString); 107 } 108 109 function shouldBeUndefined(_a) 110 { 111 var exception; 112 var _av; 113 try { 114 _av = eval(_a); 115 } catch (e) { 116 exception = e; 117 } 118 119 if (exception) 120 testFailed(_a + " should be undefined. Threw exception " + exception); 121 else if (typeof _av == "undefined") 122 testPassed(_a + " is undefined."); 123 else 124 testFailed(_a + " should be undefined. Was " + _av); 125 } 126 127 function shouldThrow(_a, _e) 128 { 129 var exception; 130 var _av; 131 try { 132 _av = eval(_a); 133 } catch (e) { 134 exception = e; 135 } 136 137 var _ev; 138 if (_e) 139 _ev = eval(_e); 140 141 if (exception) { 142 if (typeof _e == "undefined" || exception == _ev) 143 testPassed(_a + " threw exception " + exception + "."); 144 else 145 testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + "."); 146 } else if (typeof _av == "undefined") 147 testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined."); 148 else 149 testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + "."); 150 } 151 152 var cookies = new Array(); 153 154 // This method sets the cookies using XMLHttpRequest. 155 // We do not set the cookie right away as it is forbidden by the XHR spec. 156 // FIXME: Add the possibility to set multiple cookies in a row. 157 function setCookies(cookie) 158 { 159 try { 160 var xhr = new XMLHttpRequest(); 161 xhr.open("GET", "resources/setCookies.cgi", false); 162 xhr.setRequestHeader("SET_COOKIE", cookie); 163 xhr.send(null); 164 if (xhr.status == 200) { 165 // This is to clear them later. 166 cookies.push(cookie); 167 return true; 168 } else 169 return false; 170 } catch (e) { 171 return false; 172 } 173 } 174 175 // Normalize a cookie string 176 function normalizeCookie(cookie) 177 { 178 // Split the cookie string, sort it and then put it back together. 179 return cookie.split('; ').sort().join('; '); 180 } 181 182 // We get the cookies throught an XMLHttpRequest. 183 function testCookies(result) 184 { 185 var xhr = new XMLHttpRequest(); 186 xhr.open("GET", "resources/getCookies.cgi", false); 187 xhr.send(null); 188 var cookie = xhr.getResponseHeader("HTTP_COOKIE") == null ? '"null"' : xhr.getResponseHeader("HTTP_COOKIE"); 189 190 // Normalize the cookie strings. 191 result = normalizeCookie(result); 192 cookie = normalizeCookie(cookie); 193 194 if (cookie === result) 195 testPassed("cookie is '" + cookie + "'."); 196 else 197 testFailed("cookie was '" + cookie + "'. Expected '" + result + "'."); 198 } 199 200 function clearAllCookies() 201 { 202 var cookieString; 203 while (cookieString = document.cookie) { 204 var cookieName = cookieString.substr(0, cookieString.indexOf("=") || cookieString.length()); 205 cookies.push(cookieName); 206 clearCookies(); 207 } 208 } 209 210 function clearCookies() 211 { 212 if (!cookies.length) 213 return; 214 215 try { 216 var xhr = new XMLHttpRequest(); 217 var cookie; 218 // We need to clean one cookie at a time because to be cleared the 219 // cookie must be exactly the same except for the "Max-Age" 220 // and "Expires" fields. 221 while (cookie = cookies.pop()) { 222 xhr.open("GET", "resources/clearCookies.cgi", false); 223 xhr.setRequestHeader("CLEAR_COOKIE", cookie); 224 xhr.send(null); 225 } 226 } catch (e) { 227 debug("Could not clear the cookies expect the following results to fail"); 228 } 229 } 230 231 // This method check one cookie at a time. 232 function cookiesShouldBe(cookiesToSet, result) 233 { 234 if (!setCookies(cookiesToSet)) { 235 testFailed("could not set cookie(s) " + cookiesToSet); 236 return; 237 } 238 testCookies(result); 239 } 240