js-test-pre.js revision 6c2af9490927c3c5959b5cb07461b646f8b32f6c
1if (window.layoutTestController)
2    layoutTestController.dumpAsText();
3
4function 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
16function 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
23function escapeHTML(text)
24{
25    return text.replace(/&/g, "&amp;").replace(/</g, "&lt;");
26}
27
28function testPassed(msg)
29{
30    debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
31}
32
33function testFailed(msg)
34{
35    debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
36}
37
38function areArraysEqual(_a, _b)
39{
40    try {
41        if (_a.length !== _b.length)
42            return false;
43        for (var i = 0; i < _a.length; i++)
44            if (_a[i] !== _b[i])
45                return false;
46    } catch (ex) {
47        return false;
48    }
49    return true;
50}
51
52function isMinusZero(n)
53{
54    // the only way to tell 0 from -0 in JS is the fact that 1/-0 is
55    // -Infinity instead of Infinity
56    return n === 0 && 1/n < 0;
57}
58
59function isResultCorrect(_actual, _expected)
60{
61    if (_expected === 0)
62        return _actual === _expected && (1/_actual) === (1/_expected);
63    if (_actual === _expected)
64        return true;
65    if (typeof(_expected) == "number" && isNaN(_expected))
66        return typeof(_actual) == "number" && isNaN(_actual);
67    if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([]))
68        return areArraysEqual(_actual, _expected);
69    return false;
70}
71
72function stringify(v)
73{
74    if (v === 0 && 1/v < 0)
75        return "-0";
76    else return "" + v;
77}
78
79function evalAndLog(_a)
80{
81  if (typeof _a != "string")
82    debug("WARN: tryAndLog() expects a string argument");
83
84  // Log first in case things go horribly wrong or this causes a sync event.
85  debug(_a);
86
87  var _av;
88  try {
89     _av = eval(_a);
90  } catch (e) {
91    testFailed(_a + " threw exception " + e);
92  }
93  return _av;
94}
95
96function shouldBe(_a, _b)
97{
98  if (typeof _a != "string" || typeof _b != "string")
99    debug("WARN: shouldBe() expects string arguments");
100  var exception;
101  var _av;
102  try {
103     _av = eval(_a);
104  } catch (e) {
105     exception = e;
106  }
107  var _bv = eval(_b);
108
109  if (exception)
110    testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
111  else if (isResultCorrect(_av, _bv))
112    testPassed(_a + " is " + _b);
113  else if (typeof(_av) == typeof(_bv))
114    testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
115  else
116    testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
117}
118
119function shouldBeTrue(_a) { shouldBe(_a, "true"); }
120function shouldBeFalse(_a) { shouldBe(_a, "false"); }
121function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
122function shouldBeNull(_a) { shouldBe(_a, "null"); }
123
124function shouldBeEqualToString(a, b)
125{
126  var unevaledString = '"' + b.replace(/\\/g, "\\\\").replace(/"/g, "\"") + '"';
127  shouldBe(a, unevaledString);
128}
129
130function shouldEvaluateTo(actual, expected) {
131  // A general-purpose comparator.  'actual' should be a string to be
132  // evaluated, as for shouldBe(). 'expected' may be any type and will be
133  // used without being eval'ed.
134  if (expected == null) {
135    // Do this before the object test, since null is of type 'object'.
136    shouldBeNull(actual);
137  } else if (typeof expected == "undefined") {
138    shouldBeUndefined(actual);
139  } else if (typeof expected == "function") {
140    // All this fuss is to avoid the string-arg warning from shouldBe().
141    try {
142      actualValue = eval(actual);
143    } catch (e) {
144      testFailed("Evaluating " + actual + ": Threw exception " + e);
145      return;
146    }
147    shouldBe("'" + actualValue.toString().replace(/\n/g, "") + "'",
148             "'" + expected.toString().replace(/\n/g, "") + "'");
149  } else if (typeof expected == "object") {
150    shouldBeTrue(actual + " == '" + expected + "'");
151  } else if (typeof expected == "string") {
152    shouldBe(actual, expected);
153  } else if (typeof expected == "boolean") {
154    shouldBe("typeof " + actual, "'boolean'");
155    if (expected)
156      shouldBeTrue(actual);
157    else
158      shouldBeFalse(actual);
159  } else if (typeof expected == "number") {
160    shouldBe(actual, stringify(expected));
161  } else {
162    debug(expected + " is unknown type " + typeof expected);
163    shouldBeTrue(actual, "'"  +expected.toString() + "'");
164  }
165}
166
167function shouldBeNonZero(_a)
168{
169  var exception;
170  var _av;
171  try {
172     _av = eval(_a);
173  } catch (e) {
174     exception = e;
175  }
176
177  if (exception)
178    testFailed(_a + " should be non-zero. Threw exception " + exception);
179  else if (_av != 0)
180    testPassed(_a + " is non-zero.");
181  else
182    testFailed(_a + " should be non-zero. Was " + _av);
183}
184
185function shouldBeNonNull(_a)
186{
187  var exception;
188  var _av;
189  try {
190     _av = eval(_a);
191  } catch (e) {
192     exception = e;
193  }
194
195  if (exception)
196    testFailed(_a + " should be non-null. Threw exception " + exception);
197  else if (_av != null)
198    testPassed(_a + " is non-null.");
199  else
200    testFailed(_a + " should be non-null. Was " + _av);
201}
202
203function shouldBeUndefined(_a)
204{
205  var exception;
206  var _av;
207  try {
208     _av = eval(_a);
209  } catch (e) {
210     exception = e;
211  }
212
213  if (exception)
214    testFailed(_a + " should be undefined. Threw exception " + exception);
215  else if (typeof _av == "undefined")
216    testPassed(_a + " is undefined.");
217  else
218    testFailed(_a + " should be undefined. Was " + _av);
219}
220
221
222function shouldThrow(_a, _e)
223{
224  var exception;
225  var _av;
226  try {
227     _av = eval(_a);
228  } catch (e) {
229     exception = e;
230  }
231
232  var _ev;
233  if (_e)
234      _ev =  eval(_e);
235
236  if (exception) {
237    if (typeof _e == "undefined" || exception == _ev)
238      testPassed(_a + " threw exception " + exception + ".");
239    else
240      testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + ".");
241  } else if (typeof _av == "undefined")
242    testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
243  else
244    testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
245}
246
247function gc() {
248    if (typeof GCController !== "undefined")
249        GCController.collect();
250    else {
251        function gcRec(n) {
252            if (n < 1)
253                return {};
254            var temp = {i: "ab" + i + (i / 100000)};
255            temp += "foo";
256            gcRec(n-1);
257        }
258        for (var i = 0; i < 1000; i++)
259            gcRec(10)
260    }
261}
262