Enhance shouldBe()/shouldNotBe() to accept anonymous function arguments
[WebKit-https.git] / JSTests / stress / resources / standalone-pre.js
1 var errorMessage;
2 var self = this;
3
4 self.testRunner = {
5     neverInlineFunction: neverInlineFunction,
6     numberOfDFGCompiles: numberOfDFGCompiles
7 };
8
9 var silentMode = true;
10 var throwOnFirstFail = true;
11 var silentTestPass, didPassSomeTestsSilently, didFailSomeTests, successfullyParsed;
12 silentTestPass = false;
13 didPassSomeTestsSilenty = false;
14 didFailSomeTests = false;
15
16 function description(msg)
17 {
18     if (silentMode)
19         return;
20     print(msg);
21     print("\nOn success, you will see a series of \"PASS\" messages, followed by \"TEST COMPLETE\".\n");
22     print();
23 }
24
25 function debug(msg)
26 {
27     if (silentMode)
28         return;
29     print(msg);
30 }
31
32 function escapeString(text)
33 {
34     return text.replace(/\0/g, "");
35 }
36
37 function testPassed(msg)
38 {
39     if (silentTestPass)
40         didPassSomeTestsSilently = true;
41     else if (silentMode)
42         return;
43     else
44         print("PASS", escapeString(msg));
45 }
46
47 function testFailed(msg)
48 {
49     didFailSomeTests = true;
50     if (!silentMode)
51         print("FAIL", escapeString(msg));
52     if (throwOnFirstFail)
53         throw new Error(escapeString(msg));
54 }
55
56 function areNumbersEqual(_actual, _expected)
57 {
58     if (_expected === 0)
59         return _actual === _expected && (1/_actual) === (1/_expected);
60     if (_actual === _expected)
61         return true;
62     if (typeof(_expected) == "number" && isNaN(_expected))
63         return typeof(_actual) == "number" && isNaN(_actual);
64     return false;
65 }
66
67 function areArraysEqual(_a, _b)
68 {
69     try {
70         if (_a.length !== _b.length)
71             return false;
72         for (var i = 0; i < _a.length; i++)
73             if (!areNumbersEqual(_a[i], _b[i]))
74                 return false;
75     } catch (ex) {
76         return false;
77     }
78     return true;
79 }
80
81 function isMinusZero(n)
82 {
83     // the only way to tell 0 from -0 in JS is the fact that 1/-0 is
84     // -Infinity instead of Infinity
85     return n === 0 && 1/n < 0;
86 }
87
88 function isTypedArray(array)
89 {
90     return array instanceof Int8Array
91         || array instanceof Int16Array
92         || array instanceof Int32Array
93         || array instanceof Uint8Array
94         || array instanceof Uint8ClampedArray
95         || array instanceof Uint16Array
96         || array instanceof Uint32Array
97         || array instanceof Float32Array
98         || array instanceof Float64Array;
99 }
100
101 function isResultCorrect(_actual, _expected)
102 {
103     if (areNumbersEqual(_actual, _expected))
104         return true;
105     if (_expected
106         && (Object.prototype.toString.call(_expected) ==
107             Object.prototype.toString.call([])
108             || isTypedArray(_expected)))
109         return areArraysEqual(_actual, _expected);
110     return false;
111 }
112
113 function stringify(v)
114 {
115     if (v === 0 && 1/v < 0)
116         return "-0";
117     else if (isTypedArray(v))
118         return v.__proto__.constructor.name + ":[" + Array.prototype.join.call(v, ",") + "]";
119     else
120         return "" + v;
121 }
122
123 function shouldBe(_a, _b, quiet)
124 {
125   if ((typeof _a != "function" && typeof _a != "string") || (typeof _b != "function" && typeof _b != "string"))
126     debug("WARN: shouldBe() expects function or string arguments");
127   var exception;
128   var _av;
129   try {
130     _av = (typeof _a == "function" ? _a() : eval(_a));
131   } catch (e) {
132     exception = e;
133   }
134   var _bv = (typeof _b == "function" ? _b() : eval(_b));
135
136   if (exception)
137     testFailed(_a + " should be " + stringify(_bv) + ". Threw exception " + exception);
138   else if (isResultCorrect(_av, _bv)) {
139     if (!quiet) {
140       testPassed(_a + " is " + (typeof _b == "function" ? _bv : _b));
141     }
142   } else if (typeof(_av) == typeof(_bv))
143     testFailed(_a + " should be " + stringify(_bv) + ". Was " + stringify(_av) + ".");
144   else
145     testFailed(_a + " should be " + stringify(_bv) + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
146 }
147
148 function dfgShouldBe(theFunction, _a, _b)
149 {
150   if (typeof theFunction != "function" || typeof _a != "string" || typeof _b != "string")
151     debug("WARN: dfgShouldBe() expects a function and two strings");
152   noInline(theFunction);
153   var exception;
154   var values = [];
155
156   // Defend against tests that muck with numeric properties on array.prototype.
157   values.__proto__ = null;
158   values.push = Array.prototype.push;
159   
160   try {
161     while (!dfgCompiled({f:theFunction}))
162       values.push(eval(_a));
163     values.push(eval(_a));
164   } catch (e) {
165     exception = e;
166   }
167
168   var _bv = eval(_b);
169   if (exception)
170     testFailed(_a + " should be " + stringify(_bv) + ". On iteration " + (values.length + 1) + ", threw exception " + exception);
171   else {
172     var allPassed = true;
173     for (var i = 0; i < values.length; ++i) {
174       var _av = values[i];
175       if (isResultCorrect(_av, _bv))
176         continue;
177       if (typeof(_av) == typeof(_bv))
178         testFailed(_a + " should be " + stringify(_bv) + ". On iteration " + (i + 1) + ", was " + stringify(_av) + ".");
179       else
180         testFailed(_a + " should be " + stringify(_bv) + " (of type " + typeof _bv + "). On iteration " + (i + 1) + ", was " + _av + " (of type " + typeof _av + ").");
181       allPassed = false;
182     }
183     if (allPassed)
184       testPassed(_a + " is " + _b + " on all iterations including after DFG tier-up.");
185   }
186   
187   return values.length;
188 }
189
190 function shouldBeType(_a, _type) {
191   var exception;
192   var _av;
193   try {
194     _av = eval(_a);
195   } catch (e) {
196     exception = e;
197   }
198
199   var _typev = eval(_type);
200   if (_av instanceof _typev) {
201     testPassed(_a + " is an instance of " + _type);
202   } else {
203     testFailed(_a + " is not an instance of " + _type);
204   }
205 }
206
207 function shouldBeTrue(_a) { shouldBe(_a, "true"); }
208 function shouldBeFalse(_a) { shouldBe(_a, "false"); }
209 function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
210 function shouldBeNull(_a) { shouldBe(_a, "null"); }
211
212 function shouldBeEqualToString(a, b)
213 {
214   if (typeof a !== "string" || typeof b !== "string")
215     debug("WARN: shouldBeEqualToString() expects string arguments");
216   var unevaledString = JSON.stringify(b);
217   shouldBe(a, unevaledString);
218 }
219
220 function shouldBeUndefined(_a)
221 {
222   var exception;
223   var _av;
224   try {
225      _av = eval(_a);
226   } catch (e) {
227      exception = e;
228   }
229
230   if (exception)
231     testFailed(_a + " should be undefined. Threw exception " + exception);
232   else if (typeof _av == "undefined")
233     testPassed(_a + " is undefined.");
234   else
235     testFailed(_a + " should be undefined. Was " + _av);
236 }
237
238 function shouldNotThrow(_a, _message) {
239     try {
240         typeof _a == "function" ? _a() : eval(_a);
241         testPassed((_message ? _message : _a) + " did not throw exception.");
242     } catch (e) {
243         testFailed((_message ? _message : _a) + " should not throw exception. Threw exception " + e + ".");
244     }
245 }
246
247 function shouldThrow(_a, _e, _message)
248 {
249     var _exception;
250     var _av;
251     try {
252         _av = typeof _a == "function" ? _a() : eval(_a);
253     } catch (e) {
254         _exception = e;
255     }
256
257     var _ev;
258     if (_e)
259         _ev =  eval(_e);
260
261     if (_exception) {
262         if (typeof _e == "undefined" || _exception == _ev)
263             testPassed((_message ? _message : _a) + " threw exception " + _exception + ".");
264         else
265             testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + _exception + ".");
266     } else if (typeof _av == "undefined")
267         testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
268     else
269         testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
270 }
271
272 function isSuccessfullyParsed()
273 {
274     // FIXME: Remove this and only report unexpected syntax errors.
275     if (!errorMessage)
276         successfullyParsed = true;
277     shouldBeTrue("successfullyParsed");
278     if (silentTestPass && didPassSomeTestsSilently)
279         debug("Passed some tests silently.");
280     if (silentTestPass && didFailSomeTests)
281         debug("Some tests failed.");
282     debug("\nTEST COMPLETE\n");
283 }
284
285
286 function dfgCompiled(argument)
287 {
288     var numberOfCompiles = "compiles" in argument ? argument.compiles : 1;
289     
290     if (!("f" in argument))
291         throw new Error("dfgCompiled called with invalid argument.");
292     
293     if (argument.f instanceof Array) {
294         for (var i = 0; i < argument.f.length; ++i) {
295             if (testRunner.numberOfDFGCompiles(argument.f[i]) < numberOfCompiles)
296                 return false;
297         }
298     } else {
299         if (testRunner.numberOfDFGCompiles(argument.f) < numberOfCompiles)
300             return false;
301     }
302     
303     return true;
304 }
305
306 function dfgIncrement(argument)
307 {
308     if (!self.testRunner)
309         return argument.i;
310     
311     if (argument.i < argument.n)
312         return argument.i;
313     
314     if (didFailSomeTests)
315         return argument.i;
316     
317     if (!dfgCompiled(argument))
318         return "start" in argument ? argument.start : 0;
319     
320     return argument.i;
321 }
322
323 function noInline(theFunction)
324 {
325     if (!self.testRunner)
326         return;
327     
328     testRunner.neverInlineFunction(theFunction);
329 }
330
331 function finishJSTest()
332 {
333     isSuccessfullyParsed();
334     if (didFailSomeTests)
335         throw new Error("Some Tests Failed");
336 }