[jslint] Enable js lint and fix the errors.
[platform/framework/web/tizen-extensions-crosswalk.git] / examples / js / js-test-pre.js
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  * Copyright (C) 2013 Intel Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 // svg/dynamic-updates tests set enablePixelTesting=true, as we want to dump text + pixel results
28 var description, debug, successfullyParsed, errorMessage;
29
30 (function() {
31
32   function getOrCreate(id, tagName)
33   {
34     var element = document.getElementById(id);
35     if (element)
36       return element;
37
38     element = document.createElement(tagName);
39     element.id = id;
40     var refNode;
41     var parent = document.body || document.documentElement;
42     if (id == 'description')
43       refNode = getOrCreate('console', 'div');
44     else
45       refNode = parent.firstChild;
46
47     parent.insertBefore(element, refNode);
48     return element;
49   }
50
51   description = function description(msg, quiet)
52       {
53     // For MSIE 6 compatibility
54     var span = document.createElement('span');
55     if (quiet)
56       span.innerHTML = '<p>' + msg +
57           '</p><p>' +
58           'On success, you will see no "<span class="fail">FAIL</span>" messages, ' +
59           'followed by "<span class="pass">TEST COMPLETE</span>".' +
60           '</p>';
61     else
62       span.innerHTML = '<p>' + msg +
63           '</p><p>' +
64           'On success, you will see a series of "<span class="pass">PASS</span>" messages, ' +
65           'followed by "<span class="pass">TEST COMPLETE</span>".' +
66           '</p>';
67
68     var description = getOrCreate('description', 'p');
69     if (description.firstChild)
70       description.replaceChild(span, description.firstChild);
71     else
72       description.appendChild(span);
73   };
74
75   debug = function debug(msg)
76       {
77     var span = document.createElement('span');
78     getOrCreate('console', 'div').appendChild(span); // insert it first so XHTML knows the namespace
79     span.innerHTML = msg + '<br />';
80   };
81
82   var css =
83       '.pass {' +
84             'font-weight: bold;' +
85             'color: green;' +
86       '}' +
87       '.fail {' +
88             'font-weight: bold;' +
89             'color: red;' +
90       '}' +
91       '#console {' +
92             'white-space: pre-wrap;' +
93             'font-family: monospace;' +
94       '}';
95
96   function insertStyleSheet()
97   {
98     var styleElement = document.createElement('style');
99     styleElement.textContent = css;
100     (document.head || document.documentElement).appendChild(styleElement);
101   }
102
103   insertStyleSheet();
104
105   if (!self.isOnErrorTest) {
106     self.onerror = function(message)
107         {
108       errorMessage = message;
109     };
110   }
111
112 })();
113
114 function descriptionQuiet(msg) { description(msg, true); }
115
116 function escapeHTML(text)
117 {
118   return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\0/g, '\\0');
119 }
120
121 function testPassed(msg)
122 {
123   debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
124 }
125
126 function testFailed(msg)
127 {
128   debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
129 }
130
131 function areArraysEqual(_a, _b)
132 {
133   try {
134     if (_a.length !== _b.length)
135       return false;
136     for (var i = 0; i < _a.length; i++)
137       if (_a[i] !== _b[i])
138         return false;
139   } catch (ex) {
140     return false;
141   }
142   return true;
143 }
144
145 function isMinusZero(n)
146 {
147   // the only way to tell 0 from -0 in JS is the fact that 1/-0 is
148   // -Infinity instead of Infinity
149   return n === 0 && 1 / n < 0;
150 }
151
152 function isResultCorrect(_actual, _expected)
153 {
154   if (_expected === 0)
155     return _actual === _expected && (1 / _actual) === (1 / _expected);
156   if (_actual === _expected)
157     return true;
158   if (typeof(_expected) == 'number' && isNaN(_expected))
159     return typeof(_actual) == 'number' && isNaN(_actual);
160   if (_expected &&
161       (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([])))
162     return areArraysEqual(_actual, _expected);
163   return false;
164 }
165
166 function stringify(v)
167 {
168   if (v === 0 && 1 / v < 0)
169     return '-0';
170   else return '' + v;
171 }
172
173 function evalAndLog(_a, _quiet)
174 {
175   if (typeof _a != 'string')
176     debug('WARN: tryAndLog() expects a string argument');
177
178   // Log first in case things go horribly wrong or this causes a sync event.
179   if (!_quiet)
180     debug(_a);
181
182   var _av;
183   try {
184     _av = eval(_a);
185   } catch (e) {
186     testFailed(_a + ' threw exception ' + e);
187   }
188   return _av;
189 }
190
191 function shouldBe(_a, _b, quiet)
192 {
193   if (typeof _a != 'string' || typeof _b != 'string')
194     debug('WARN: shouldBe() expects string arguments');
195   var exception;
196   var _av;
197   try {
198     _av = eval(_a);
199   } catch (e) {
200     exception = e;
201   }
202   var _bv = eval(_b);
203
204   if (exception)
205     testFailed(_a + ' should be ' + _bv + '. Threw exception ' + exception);
206   else if (isResultCorrect(_av, _bv)) {
207     if (!quiet) {
208       testPassed(_a + ' is ' + _b);
209     }
210   } else if (typeof(_av) == typeof(_bv))
211     testFailed(_a + ' should be ' + _bv + '. Was ' + stringify(_av) + '.');
212   else
213     testFailed(_a + ' should be ' + _bv + ' (of type ' + typeof _bv + '). Was ' +
214                _av + ' (of type ' + typeof _av + ').');
215 }
216
217 // Execute condition every 5 milliseconds until it succeed or failureTime is reached.
218 // completionHandler is executed on success, failureHandler is executed on timeout.
219 function _waitForCondition(condition, failureTime, completionHandler, failureHandler)
220 {
221   if (condition()) {
222     completionHandler();
223   } else if (Date.now() > failureTime) {
224     failureHandler();
225   } else {
226     setTimeout(_waitForCondition, 5, condition, failureTime, completionHandler, failureHandler);
227   }
228 }
229
230 function shouldBecomeEqual(_a, _b, completionHandler, timeout)
231 {
232   if (typeof _a != 'string' || typeof _b != 'string')
233     debug('WARN: shouldBecomeEqual() expects string arguments');
234
235   if (timeout === undefined)
236     timeout = 500;
237
238   var condition = function() {
239     var exception;
240     var _av;
241     try {
242       _av = eval(_a);
243     } catch (e) {
244       exception = e;
245     }
246     var _bv = eval(_b);
247     if (exception)
248       testFailed(_a + ' should become ' + _bv + '. Threw exception ' + exception);
249     if (isResultCorrect(_av, _bv)) {
250       testPassed(_a + ' became ' + _b);
251       return true;
252     }
253     return false;
254   };
255   var failureTime = Date.now() + timeout;
256   var failureHandler = function() {
257     testFailed(_a + ' failed to change to ' + _b + ' in ' + (timeout / 1000) + ' seconds.');
258     completionHandler();
259   };
260   _waitForCondition(condition, failureTime, completionHandler, failureHandler);
261 }
262
263 function shouldBecomeEqualToString(value, reference, completionHandler, timeout)
264 {
265   if (typeof value !== 'string' || typeof reference !== 'string')
266     debug('WARN: shouldBecomeEqualToString() expects string arguments');
267   var unevaledString = JSON.stringify(reference);
268   shouldBecomeEqual(value, unevaledString, completionHandler, timeout);
269 }
270
271 function shouldBeType(_a, _type) {
272   var exception;
273   var _av;
274   try {
275     _av = eval(_a);
276   } catch (e) {
277     exception = e;
278   }
279
280   var _typev = eval(_type);
281   if (_av instanceof _typev) {
282     testPassed(_a + ' is an instance of ' + _type);
283   } else {
284     testFailed(_a + ' is not an instance of ' + _type);
285   }
286 }
287
288 // Variant of shouldBe()--confirms that result of eval(_to_eval) is within
289 // numeric _tolerance of numeric _target.
290 function shouldBeCloseTo(_to_eval, _target, _tolerance, quiet)
291 {
292   if (typeof _to_eval != 'string') {
293     testFailed('shouldBeCloseTo() requires string argument _to_eval. was type ' + typeof _to_eval);
294     return;
295   }
296   if (typeof _target != 'number') {
297     testFailed('shouldBeCloseTo() requires numeric argument _target. was type ' + typeof _target);
298     return;
299   }
300   if (typeof _tolerance != 'number') {
301     testFailed('shouldBeCloseTo() requires numeric argument _tolerance. was type ' +
302                typeof _tolerance);
303     return;
304   }
305
306   var _result;
307   try {
308     _result = eval(_to_eval);
309   } catch (e) {
310     testFailed(_to_eval + ' should be within ' + _tolerance + ' of ' +
311                _target + '. Threw exception ' + e);
312     return;
313   }
314
315   if (typeof(_result) != typeof(_target)) {
316     testFailed(_to_eval + ' should be of type ' + typeof _target +
317                ' but was of type ' + typeof _result);
318   } else if (Math.abs(_result - _target) <= _tolerance) {
319     if (!quiet) {
320       testPassed(_to_eval + ' is within ' + _tolerance + ' of ' + _target);
321     }
322   } else {
323     testFailed(_to_eval + ' should be within ' + _tolerance + ' of ' + _target +
324                '. Was ' + _result + '.');
325   }
326 }
327
328 function shouldNotBe(_a, _b, quiet)
329 {
330   if (typeof _a != 'string' || typeof _b != 'string')
331     debug('WARN: shouldNotBe() expects string arguments');
332   var exception;
333   var _av;
334   try {
335     _av = eval(_a);
336   } catch (e) {
337     exception = e;
338   }
339   var _bv = eval(_b);
340
341   if (exception)
342     testFailed(_a + ' should not be ' + _bv + '. Threw exception ' + exception);
343   else if (!isResultCorrect(_av, _bv)) {
344     if (!quiet) {
345       testPassed(_a + ' is not ' + _b);
346     }
347   } else
348     testFailed(_a + ' should not be ' + _bv + '.');
349 }
350
351 function shouldBecomeDifferent(_a, _b, completionHandler, timeout)
352 {
353   if (typeof _a != 'string' || typeof _b != 'string')
354     debug('WARN: shouldBecomeDifferent() expects string arguments');
355   if (timeout === undefined)
356     timeout = 500;
357
358   var condition = function() {
359     var exception;
360     var _av;
361     try {
362       _av = eval(_a);
363     } catch (e) {
364       exception = e;
365     }
366     var _bv = eval(_b);
367     if (exception)
368       testFailed(_a + ' should became not equal to ' + _bv + '. Threw exception ' + exception);
369     if (!isResultCorrect(_av, _bv)) {
370       testPassed(_a + ' became different from ' + _b);
371       return true;
372     }
373     return false;
374   };
375   var failureTime = Date.now() + timeout;
376   var failureHandler = function() {
377     testFailed(_a + ' did not become different from ' +
378                _b + ' in ' + (timeout / 1000) + ' seconds.');
379     completionHandler();
380   };
381   _waitForCondition(condition, failureTime, completionHandler, failureHandler);
382 }
383
384 function shouldBeTrue(_a) { shouldBe(_a, 'true'); }
385 function shouldBeTrueQuiet(_a) { shouldBe(_a, 'true', true); }
386 function shouldBeFalse(_a) { shouldBe(_a, 'false'); }
387 function shouldBeNaN(_a) { shouldBe(_a, 'NaN'); }
388 function shouldBeNull(_a) { shouldBe(_a, 'null'); }
389 function shouldBeZero(_a) { shouldBe(_a, '0'); }
390
391 function shouldBeEqualToString(a, b)
392 {
393   if (typeof a !== 'string' || typeof b !== 'string')
394     debug('WARN: shouldBeEqualToString() expects string arguments');
395   var unevaledString = JSON.stringify(b);
396   shouldBe(a, unevaledString);
397 }
398
399 function shouldBeEmptyString(_a) { shouldBeEqualToString(_a, ''); }
400
401 function shouldEvaluateTo(actual, expected) {
402   // A general-purpose comparator.  'actual' should be a string to be
403   // evaluated, as for shouldBe(). 'expected' may be any type and will be
404   // used without being eval'ed.
405   if (expected == null) {
406     // Do this before the object test, since null is of type 'object'.
407     shouldBeNull(actual);
408   } else if (typeof expected == 'undefined') {
409     shouldBeUndefined(actual);
410   } else if (typeof expected == 'function') {
411     // All this fuss is to avoid the string-arg warning from shouldBe().
412     try {
413       actualValue = eval(actual);
414     } catch (e) {
415       testFailed('Evaluating ' + actual + ': Threw exception ' + e);
416       return;
417     }
418     shouldBe("'" + actualValue.toString().replace(/\n/g, '') + "'",
419              "'" + expected.toString().replace(/\n/g, '') + "'");
420   } else if (typeof expected == 'object') {
421     shouldBeTrue(actual + " == '" + expected + "'");
422   } else if (typeof expected == 'string') {
423     shouldBe(actual, expected);
424   } else if (typeof expected == 'boolean') {
425     shouldBe('typeof ' + actual, "'boolean'");
426     if (expected)
427       shouldBeTrue(actual);
428     else
429       shouldBeFalse(actual);
430   } else if (typeof expected == 'number') {
431     shouldBe(actual, stringify(expected));
432   } else {
433     debug(expected + ' is unknown type ' + typeof expected);
434     shouldBeTrue(actual, "'" + expected.toString() + "'");
435   }
436 }
437
438 function shouldBeNonZero(_a)
439 {
440   var exception;
441   var _av;
442   try {
443     _av = eval(_a);
444   } catch (e) {
445     exception = e;
446   }
447
448   if (exception)
449     testFailed(_a + ' should be non-zero. Threw exception ' + exception);
450   else if (_av != 0)
451     testPassed(_a + ' is non-zero.');
452   else
453     testFailed(_a + ' should be non-zero. Was ' + _av);
454 }
455
456 function shouldBeNonNull(_a)
457 {
458   var exception;
459   var _av;
460   try {
461     _av = eval(_a);
462   } catch (e) {
463     exception = e;
464   }
465
466   if (exception)
467     testFailed(_a + ' should be non-null. Threw exception ' + exception);
468   else if (_av != null)
469     testPassed(_a + ' is non-null.');
470   else
471     testFailed(_a + ' should be non-null. Was ' + _av);
472 }
473
474 function shouldBeUndefined(_a)
475 {
476   var exception;
477   var _av;
478   try {
479     _av = eval(_a);
480   } catch (e) {
481     exception = e;
482   }
483
484   if (exception)
485     testFailed(_a + ' should be undefined. Threw exception ' + exception);
486   else if (typeof _av == 'undefined')
487     testPassed(_a + ' is undefined.');
488   else
489     testFailed(_a + ' should be undefined. Was ' + _av);
490 }
491
492 function shouldBeDefined(_a)
493 {
494   var exception;
495   var _av;
496   try {
497     _av = eval(_a);
498   } catch (e) {
499     exception = e;
500   }
501
502   if (exception)
503     testFailed(_a + ' should be defined. Threw exception ' + exception);
504   else if (_av !== undefined)
505     testPassed(_a + ' is defined.');
506   else
507     testFailed(_a + ' should be defined. Was ' + _av);
508 }
509
510 function shouldBeGreaterThanOrEqual(_a, _b) {
511   if (typeof _a != 'string' || typeof _b != 'string')
512     debug('WARN: shouldBeGreaterThanOrEqual expects string arguments');
513
514   var exception;
515   var _av;
516   try {
517     _av = eval(_a);
518   } catch (e) {
519     exception = e;
520   }
521   var _bv = eval(_b);
522
523   if (exception)
524     testFailed(_a + ' should be >= ' + _b + '. Threw exception ' + exception);
525   else if (typeof _av == 'undefined' || _av < _bv)
526     testFailed(_a + ' should be >= ' + _b + '. Was ' + _av + ' (of type ' + typeof _av + ').');
527   else
528     testPassed(_a + ' is >= ' + _b);
529 }
530
531 function shouldNotThrow(_a) {
532   try {
533     eval(_a);
534     testPassed(_a + ' did not throw exception.');
535   } catch (e) {
536     testFailed(_a + ' should not throw exception. Threw exception ' + e + '.');
537   }
538 }
539
540 function shouldThrow(_a, _e)
541 {
542   var exception;
543   var _av;
544   try {
545     _av = eval(_a);
546   } catch (e) {
547     exception = e;
548   }
549
550   var _ev;
551   if (_e)
552     _ev = eval(_e);
553
554   if (exception) {
555     // Handle WebAPIException and WebAPIError.
556     if (exception instanceof tizen.WebAPIException || exception instanceof tizen.WebAPIError) {
557       exception = exception.name;
558       _ev = _ev.name;
559     }
560
561     if (typeof _e == 'undefined' || exception == _ev)
562       testPassed(_a + ' threw exception ' + exception + '.');
563     else
564       testFailed(_a + ' should throw ' + (typeof _e == 'undefined' ? 'an exception' : _ev) +
565                  '. Threw exception ' + exception + '.');
566   } else if (typeof _av == 'undefined') {
567     testFailed(_a + ' should throw ' + (typeof _e == 'undefined' ? 'an exception' : _ev) +
568                '. Was undefined.');
569   } else {
570     testFailed(_a + ' should throw ' + (typeof _e == 'undefined' ? 'an exception' : _ev) +
571                '. Was ' + _av + '.');
572   }
573 }
574
575 function shouldHaveHadError(message)
576 {
577   if (errorMessage) {
578     if (!message)
579       testPassed('Got expected error');
580     else if (errorMessage.indexOf(message) !== -1)
581       testPassed("Got expected error: '" + message + "'");
582     else
583       testFailed("Unexpexted error '" + message + "'");
584   } else
585     testFailed('Missing expexted error');
586   errorMessage = undefined;
587 }
588
589 function isSuccessfullyParsed()
590 {
591   // FIXME: Remove this and only report unexpected syntax errors.
592   if (!errorMessage)
593     successfullyParsed = true;
594   shouldBeTrue('successfullyParsed');
595   debug('<br /><span class="pass">TEST COMPLETE</span>');
596 }
597
598 function finishJSTest()
599 {
600   wasFinishJSTestCalled = true;
601   if (!self.wasPostTestScriptParsed)
602     return;
603   isSuccessfullyParsed();
604 }