1// svg/dynamic-updates tests set enablePixelTesting=true, as we want to dump text + pixel results
2if (window.layoutTestController)
3    layoutTestController.dumpAsText(window.enablePixelTesting);
4
5function description(msg)
6{
7    // For MSIE 6 compatibility
8    var span = document.createElement("span");
9    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>';
10    var description = document.getElementById("description");
11    if (description.firstChild)
12        description.replaceChild(span, description.firstChild);
13    else
14        description.appendChild(span);
15}
16
17function debug(msg)
18{
19    var span = document.createElement("span");
20    document.getElementById("console").appendChild(span); // insert it first so XHTML knows the namespace
21    span.innerHTML = msg + '<br />';
22}
23
24function escapeHTML(text)
25{
26    return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/\0/g, "\\0");
27}
28
29function testPassed(msg)
30{
31    debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
32}
33
34function testFailed(msg)
35{
36    debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
37}
38
39function areArraysEqual(_a, _b)
40{
41    try {
42        if (_a.length !== _b.length)
43            return false;
44        for (var i = 0; i < _a.length; i++)
45            if (_a[i] !== _b[i])
46                return false;
47    } catch (ex) {
48        return false;
49    }
50    return true;
51}
52
53function isMinusZero(n)
54{
55    // the only way to tell 0 from -0 in JS is the fact that 1/-0 is
56    // -Infinity instead of Infinity
57    return n === 0 && 1/n < 0;
58}
59
60function isResultCorrect(_actual, _expected)
61{
62    if (_expected === 0)
63        return _actual === _expected && (1/_actual) === (1/_expected);
64    if (_actual === _expected)
65        return true;
66    if (typeof(_expected) == "number" && isNaN(_expected))
67        return typeof(_actual) == "number" && isNaN(_actual);
68    if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([]))
69        return areArraysEqual(_actual, _expected);
70    return false;
71}
72
73function stringify(v)
74{
75    if (v === 0 && 1/v < 0)
76        return "-0";
77    else return "" + v;
78}
79
80function evalAndLog(_a)
81{
82  if (typeof _a != "string")
83    debug("WARN: tryAndLog() expects a string argument");
84
85  // Log first in case things go horribly wrong or this causes a sync event.
86  debug(_a);
87
88  var _av;
89  try {
90     _av = eval(_a);
91  } catch (e) {
92    testFailed(_a + " threw exception " + e);
93  }
94  return _av;
95}
96
97function shouldBe(_a, _b)
98{
99  if (typeof _a != "string" || typeof _b != "string")
100    debug("WARN: shouldBe() expects string arguments");
101  var exception;
102  var _av;
103  try {
104     _av = eval(_a);
105  } catch (e) {
106     exception = e;
107  }
108  var _bv = eval(_b);
109
110  if (exception)
111    testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
112  else if (isResultCorrect(_av, _bv))
113    testPassed(_a + " is " + _b);
114  else if (typeof(_av) == typeof(_bv))
115    testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
116  else
117    testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
118}
119
120function shouldBeTrue(_a) { shouldBe(_a, "true"); }
121function shouldBeFalse(_a) { shouldBe(_a, "false"); }
122function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
123function shouldBeNull(_a) { shouldBe(_a, "null"); }
124
125function shouldBeEqualToString(a, b)
126{
127  var unevaledString = '"' + b.replace(/\\/g, "\\\\").replace(/"/g, "\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r") + '"';
128  shouldBe(a, unevaledString);
129}
130
131function shouldEvaluateTo(actual, expected) {
132  // A general-purpose comparator.  'actual' should be a string to be
133  // evaluated, as for shouldBe(). 'expected' may be any type and will be
134  // used without being eval'ed.
135  if (expected == null) {
136    // Do this before the object test, since null is of type 'object'.
137    shouldBeNull(actual);
138  } else if (typeof expected == "undefined") {
139    shouldBeUndefined(actual);
140  } else if (typeof expected == "function") {
141    // All this fuss is to avoid the string-arg warning from shouldBe().
142    try {
143      actualValue = eval(actual);
144    } catch (e) {
145      testFailed("Evaluating " + actual + ": Threw exception " + e);
146      return;
147    }
148    shouldBe("'" + actualValue.toString().replace(/\n/g, "") + "'",
149             "'" + expected.toString().replace(/\n/g, "") + "'");
150  } else if (typeof expected == "object") {
151    shouldBeTrue(actual + " == '" + expected + "'");
152  } else if (typeof expected == "string") {
153    shouldBe(actual, expected);
154  } else if (typeof expected == "boolean") {
155    shouldBe("typeof " + actual, "'boolean'");
156    if (expected)
157      shouldBeTrue(actual);
158    else
159      shouldBeFalse(actual);
160  } else if (typeof expected == "number") {
161    shouldBe(actual, stringify(expected));
162  } else {
163    debug(expected + " is unknown type " + typeof expected);
164    shouldBeTrue(actual, "'"  +expected.toString() + "'");
165  }
166}
167
168function shouldBeNonZero(_a)
169{
170  var exception;
171  var _av;
172  try {
173     _av = eval(_a);
174  } catch (e) {
175     exception = e;
176  }
177
178  if (exception)
179    testFailed(_a + " should be non-zero. Threw exception " + exception);
180  else if (_av != 0)
181    testPassed(_a + " is non-zero.");
182  else
183    testFailed(_a + " should be non-zero. Was " + _av);
184}
185
186function shouldBeNonNull(_a)
187{
188  var exception;
189  var _av;
190  try {
191     _av = eval(_a);
192  } catch (e) {
193     exception = e;
194  }
195
196  if (exception)
197    testFailed(_a + " should be non-null. Threw exception " + exception);
198  else if (_av != null)
199    testPassed(_a + " is non-null.");
200  else
201    testFailed(_a + " should be non-null. Was " + _av);
202}
203
204function shouldBeUndefined(_a)
205{
206  var exception;
207  var _av;
208  try {
209     _av = eval(_a);
210  } catch (e) {
211     exception = e;
212  }
213
214  if (exception)
215    testFailed(_a + " should be undefined. Threw exception " + exception);
216  else if (typeof _av == "undefined")
217    testPassed(_a + " is undefined.");
218  else
219    testFailed(_a + " should be undefined. Was " + _av);
220}
221
222function shouldBeDefined(_a)
223{
224  var exception;
225  var _av;
226  try {
227     _av = eval(_a);
228  } catch (e) {
229     exception = e;
230  }
231
232  if (exception)
233    testFailed(_a + " should be defined. Threw exception " + exception);
234  else if (_av !== undefined)
235    testPassed(_a + " is defined.");
236  else
237    testFailed(_a + " should be defined. Was " + _av);
238}
239
240function shouldBeGreaterThanOrEqual(_a, _b) {
241    if (typeof _a != "string" || typeof _b != "string")
242        debug("WARN: shouldBeGreaterThanOrEqual expects string arguments");
243
244    var exception;
245    var _av;
246    try {
247        _av = eval(_a);
248    } catch (e) {
249        exception = e;
250    }
251    var _bv = eval(_b);
252
253    if (exception)
254        testFailed(_a + " should be >= " + _b + ". Threw exception " + exception);
255    else if (typeof _av == "undefined" || _av < _bv)
256        testFailed(_a + " should be >= " + _b + ". Was " + _av + " (of type " + typeof _av + ").");
257    else
258        testPassed(_a + " is >= " + _b);
259}
260
261function shouldThrow(_a, _e)
262{
263  var exception;
264  var _av;
265  try {
266     _av = eval(_a);
267  } catch (e) {
268     exception = e;
269  }
270
271  var _ev;
272  if (_e)
273      _ev =  eval(_e);
274
275  if (exception) {
276    if (typeof _e == "undefined" || exception == _ev)
277      testPassed(_a + " threw exception " + exception + ".");
278    else
279      testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + ".");
280  } else if (typeof _av == "undefined")
281    testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
282  else
283    testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
284}
285
286function gc() {
287    if (typeof GCController !== "undefined")
288        GCController.collect();
289    else {
290        function gcRec(n) {
291            if (n < 1)
292                return {};
293            var temp = {i: "ab" + i + (i / 100000)};
294            temp += "foo";
295            gcRec(n-1);
296        }
297        for (var i = 0; i < 1000; i++)
298            gcRec(10)
299    }
300}
301
302// It's possible for an async test to call finishJSTest() before js-test-post.js
303// has been parsed.
304function finishJSTest()
305{
306    wasFinishJSTestCalled = true;
307    if (!window.wasPostTestScriptParsed)
308        return;
309    shouldBeTrue("successfullyParsed");
310    debug('<br /><span class="pass">TEST COMPLETE</span>');
311    if (window.jsTestIsAsync && window.layoutTestController)
312        layoutTestController.notifyDone();
313}
314