js-test-pre.js revision dcc8cf2e65d1aa555cce12431a16547e66b469ee
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}
94
95function shouldBe(_a, _b)
96{
97  if (typeof _a != "string" || typeof _b != "string")
98    debug("WARN: shouldBe() expects string arguments");
99  var exception;
100  var _av;
101  try {
102     _av = eval(_a);
103  } catch (e) {
104     exception = e;
105  }
106  var _bv = eval(_b);
107
108  if (exception)
109    testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
110  else if (isResultCorrect(_av, _bv))
111    testPassed(_a + " is " + _b);
112  else if (typeof(_av) == typeof(_bv))
113    testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
114  else
115    testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
116}
117
118function shouldBeTrue(_a) { shouldBe(_a, "true"); }
119function shouldBeFalse(_a) { shouldBe(_a, "false"); }
120function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
121function shouldBeNull(_a) { shouldBe(_a, "null"); }
122
123function shouldBeEqualToString(a, b)
124{
125  var unevaledString = '"' + b.replace(/\\/g, "\\\\").replace(/"/g, "\"") + '"';
126  shouldBe(a, unevaledString);
127}
128
129function shouldEvaluateTo(actual, expected) {
130  // A general-purpose comparator.  'actual' should be a string to be
131  // evaluated, as for shouldBe(). 'expected' may be any type and will be
132  // used without being eval'ed.
133  if (expected == null) {
134    // Do this before the object test, since null is of type 'object'.
135    shouldBeNull(actual);
136  } else if (typeof expected == "undefined") {
137    shouldBeUndefined(actual);
138  } else if (typeof expected == "function") {
139    // All this fuss is to avoid the string-arg warning from shouldBe().
140    try {
141      actualValue = eval(actual);
142    } catch (e) {
143      testFailed("Evaluating " + actual + ": Threw exception " + e);
144      return;
145    }
146    shouldBe("'" + actualValue.toString().replace(/\n/g, "") + "'",
147             "'" + expected.toString().replace(/\n/g, "") + "'");
148  } else if (typeof expected == "object") {
149    shouldBeTrue(actual + " == '" + expected + "'");
150  } else if (typeof expected == "string") {
151    shouldBe(actual, expected);
152  } else if (typeof expected == "boolean") {
153    shouldBe("typeof " + actual, "'boolean'");
154    if (expected)
155      shouldBeTrue(actual);
156    else
157      shouldBeFalse(actual);
158  } else if (typeof expected == "number") {
159    shouldBe(actual, stringify(expected));
160  } else {
161    debug(expected + " is unknown type " + typeof expected);
162    shouldBeTrue(actual, "'"  +expected.toString() + "'");
163  }
164}
165
166function shouldBeNonZero(_a)
167{
168  var exception;
169  var _av;
170  try {
171     _av = eval(_a);
172  } catch (e) {
173     exception = e;
174  }
175
176  if (exception)
177    testFailed(_a + " should be non-zero. Threw exception " + exception);
178  else if (_av != 0)
179    testPassed(_a + " is non-zero.");
180  else
181    testFailed(_a + " should be non-zero. Was " + _av);
182}
183
184function shouldBeNonNull(_a)
185{
186  var exception;
187  var _av;
188  try {
189     _av = eval(_a);
190  } catch (e) {
191     exception = e;
192  }
193
194  if (exception)
195    testFailed(_a + " should be non-null. Threw exception " + exception);
196  else if (_av != null)
197    testPassed(_a + " is non-null.");
198  else
199    testFailed(_a + " should be non-null. Was " + _av);
200}
201
202function shouldBeUndefined(_a)
203{
204  var exception;
205  var _av;
206  try {
207     _av = eval(_a);
208  } catch (e) {
209     exception = e;
210  }
211
212  if (exception)
213    testFailed(_a + " should be undefined. Threw exception " + exception);
214  else if (typeof _av == "undefined")
215    testPassed(_a + " is undefined.");
216  else
217    testFailed(_a + " should be undefined. Was " + _av);
218}
219
220
221function shouldThrow(_a, _e)
222{
223  var exception;
224  var _av;
225  try {
226     _av = eval(_a);
227  } catch (e) {
228     exception = e;
229  }
230
231  var _ev;
232  if (_e)
233      _ev =  eval(_e);
234
235  if (exception) {
236    if (typeof _e == "undefined" || exception == _ev)
237      testPassed(_a + " threw exception " + exception + ".");
238    else
239      testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + ".");
240  } else if (typeof _av == "undefined")
241    testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
242  else
243    testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
244}
245
246function gc() {
247    if (typeof GCController !== "undefined")
248        GCController.collect();
249    else {
250        function gcRec(n) {
251            if (n < 1)
252                return {};
253            var temp = {i: "ab" + i + (i / 100000)};
254            temp += "foo";
255            gcRec(n-1);
256        }
257        for (var i = 0; i < 1000; i++)
258            gcRec(10)
259    }
260}
261