1 // svg/dynamic-updates tests set enablePixelTesting=true, as we want to dump text + pixel results
3 if (self.enablePixelTesting)
4 testRunner.dumpAsTextWithPixelResults();
6 testRunner.dumpAsText();
11 var description, debug, successfullyParsed;
13 var expectingError; // set by shouldHaveError()
14 var expectedErrorMessage; // set by onerror when expectingError is true
15 var unexpectedErrorMessage; // set by onerror when expectingError is not true
19 function getOrCreate(id, tagName)
21 var element = document.getElementById(id);
25 element = document.createElement(tagName);
28 var parent = document.body || document.documentElement;
29 if (id == "description")
30 refNode = getOrCreate("console", "div");
32 refNode = parent.firstChild;
34 parent.insertBefore(element, refNode);
38 description = function description(msg, quiet)
40 // For MSIE 6 compatibility
41 var span = document.createElement("span");
43 span.innerHTML = '<p>' + msg + '</p><p>On success, you will see no "<span class="fail">FAIL</span>" messages, followed by "<span class="pass">TEST COMPLETE</span>".</p>';
45 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>';
47 var description = getOrCreate("description", "p");
48 if (description.firstChild)
49 description.replaceChild(span, description.firstChild);
51 description.appendChild(span);
54 debug = function debug(msg)
56 var span = document.createElement("span");
57 getOrCreate("console", "div").appendChild(span); // insert it first so XHTML knows the namespace
58 span.innerHTML = msg + '<br />';
63 "font-weight: bold;" +
67 "font-weight: bold;" +
71 "white-space: pre-wrap;" +
72 "font-family: monospace;" +
75 function insertStyleSheet()
77 var styleElement = document.createElement("style");
78 styleElement.textContent = css;
79 (document.head || document.documentElement).appendChild(styleElement);
82 function handleTestFinished()
84 // FIXME: Get rid of this boolean.
85 wasPostTestScriptParsed = true;
86 if (window.jsTestIsAsync) {
87 if (window.testRunner)
88 testRunner.waitUntilDone();
89 if (window.wasFinishJSTestCalled)
96 window.addEventListener('DOMContentLoaded', handleTestFinished, false);
100 if (!self.isOnErrorTest) {
101 self.onerror = function(message)
103 if (self.expectingError) {
104 self.expectedErrorMessage = message;
105 self.expectingError = false;
108 self.unexpectedErrorMessage = message;
109 if (self.jsTestIsAsync) {
110 self.testFailed("Unexpected error: " + message);
119 // It's conceivable that someone would stub out 'document' in a worker so
120 // also check for childNodes, an arbitrary DOM-related object that is
121 // meaningless in a WorkerContext.
122 return (typeof document === 'undefined' || typeof document.childNodes === 'undefined') && !!self.importScripts;
125 function descriptionQuiet(msg) { description(msg, true); }
127 function escapeHTML(text)
129 return text.replace(/&/g, "&").replace(/</g, "<").replace(/\0/g, "\\0");
132 function testPassed(msg)
134 debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
137 function testFailed(msg)
139 debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
142 function areArraysEqual(a, b)
145 if (a.length !== b.length)
147 for (var i = 0; i < a.length; i++)
156 function isMinusZero(n)
158 // the only way to tell 0 from -0 in JS is the fact that 1/-0 is
159 // -Infinity instead of Infinity
160 return n === 0 && 1/n < 0;
163 function isNewSVGTearOffType(v)
165 return ['[object SVGLength]', '[object SVGLengthList]', '[object SVGPoint]', '[object SVGPointList]', '[object SVGNumber]', '[object SVGTransform]', '[object SVGTransformList]'].indexOf(""+v) != -1;
168 function isResultCorrect(actual, expected)
171 return actual === expected && (1/actual) === (1/expected);
172 if (actual === expected)
174 // http://crbug.com/308818 : The new implementation of SVGListProperties do not necessary return the same wrapper object, so === operator would not work. We compare for their string representation instead.
175 if (isNewSVGTearOffType(expected) && typeof(expected) == typeof(actual) && actual.valueAsString == expected.valueAsString)
177 if (typeof(expected) == "number" && isNaN(expected))
178 return typeof(actual) == "number" && isNaN(actual);
179 if (expected && (Object.prototype.toString.call(expected) == Object.prototype.toString.call([])))
180 return areArraysEqual(actual, expected);
184 function stringify(v)
186 if (isNewSVGTearOffType(v))
187 return v.valueAsString;
188 if (v === 0 && 1/v < 0)
193 function evalAndLog(_a, _quiet)
195 if (typeof _a != "string")
196 debug("WARN: tryAndLog() expects a string argument");
198 // Log first in case things go horribly wrong or this causes a sync event.
206 testFailed(_a + " threw exception " + e);
211 function shouldBe(_a, _b, quiet, opt_tolerance)
213 if (typeof _a != "string" || typeof _b != "string")
214 debug("WARN: shouldBe() expects string arguments");
225 testFailed(_a + " should be " + _bv + ". Threw exception " + _exception);
226 else if (isResultCorrect(_av, _bv) || (typeof opt_tolerance == 'number' && typeof _av == 'number' && Math.abs(_av - _bv) <= opt_tolerance)) {
228 testPassed(_a + " is " + _b);
230 } else if (typeof(_av) == typeof(_bv))
231 testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
233 testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
236 // Execute condition every 5 milliseconds until it succeed or failureTime is reached.
237 // completionHandler is executed on success, failureHandler is executed on timeout.
238 function _waitForCondition(condition, failureTime, completionHandler, failureHandler)
242 } else if (Date.now() > failureTime) {
245 setTimeout(_waitForCondition, 5, condition, failureTime, completionHandler, failureHandler);
249 function shouldBecomeEqual(_a, _b, _completionHandler, _timeout)
251 if (typeof _a != "string" || typeof _b != "string")
252 debug("WARN: shouldBecomeEqual() expects string arguments");
254 if (_timeout === undefined)
258 var _condition = function() {
268 testFailed(_a + " should become " + _bv + ". Threw exception " + _exception);
269 if (isResultCorrect(_av, _bv)) {
270 testPassed(_a + " became " + _b);
275 var _failureTime = Date.now() + _timeout;
276 var _failureHandler = function () {
277 testFailed(_a + " failed to change to " + _bv + " in " + (_timeout / 1000) + " seconds.");
278 _completionHandler();
280 _waitForCondition(_condition, _failureTime, _completionHandler, _failureHandler);
283 function shouldBecomeEqualToString(value, reference, completionHandler, timeout)
285 if (typeof value !== "string" || typeof reference !== "string")
286 debug("WARN: shouldBecomeEqualToString() expects string arguments");
287 var unevaledString = JSON.stringify(reference);
288 shouldBecomeEqual(value, unevaledString, completionHandler, timeout);
291 function shouldBeType(_a, _type) {
300 var _typev = eval(_type);
301 if (_av instanceof _typev) {
302 testPassed(_a + " is an instance of " + _type);
304 testFailed(_a + " is not an instance of " + _type);
308 // Variant of shouldBe()--confirms that result of eval(_to_eval) is within
309 // numeric _tolerance of numeric _target.
310 function shouldBeCloseTo(_to_eval, _target, _tolerance, _quiet)
312 if (typeof _to_eval != "string") {
313 testFailed("shouldBeCloseTo() requires string argument _to_eval. was type " + typeof _to_eval);
316 if (typeof _target != "number") {
317 testFailed("shouldBeCloseTo() requires numeric argument _target. was type " + typeof _target);
320 if (typeof _tolerance != "number") {
321 testFailed("shouldBeCloseTo() requires numeric argument _tolerance. was type " + typeof _tolerance);
327 _result = eval(_to_eval);
329 testFailed(_to_eval + " should be within " + _tolerance + " of "
330 + _target + ". Threw exception " + e);
334 if (typeof(_result) != typeof(_target)) {
335 testFailed(_to_eval + " should be of type " + typeof _target
336 + " but was of type " + typeof _result);
337 } else if (Math.abs(_result - _target) <= _tolerance) {
339 testPassed(_to_eval + " is within " + _tolerance + " of " + _target);
342 testFailed(_to_eval + " should be within " + _tolerance + " of " + _target
343 + ". Was " + _result + ".");
347 function shouldNotBe(_a, _b, _quiet)
349 if (typeof _a != "string" || typeof _b != "string")
350 debug("WARN: shouldNotBe() expects string arguments");
361 testFailed(_a + " should not be " + _bv + ". Threw exception " + _exception);
362 else if (!isResultCorrect(_av, _bv)) {
364 testPassed(_a + " is not " + _b);
367 testFailed(_a + " should not be " + _bv + ".");
370 function shouldBecomeDifferent(_a, _b, _completionHandler, _timeout)
372 if (typeof _a != "string" || typeof _b != "string")
373 debug("WARN: shouldBecomeDifferent() expects string arguments");
374 if (_timeout === undefined)
378 var _condition = function() {
388 testFailed(_a + " should became not equal to " + _bv + ". Threw exception " + _exception);
389 if (!isResultCorrect(_av, _bv)) {
390 testPassed(_a + " became different from " + _b);
395 var _failureTime = Date.now() + _timeout;
396 var _failureHandler = function () {
397 testFailed(_a + " did not become different from " + _bv + " in " + (_timeout / 1000) + " seconds.");
398 _completionHandler();
400 _waitForCondition(_condition, _failureTime, _completionHandler, _failureHandler);
403 function shouldBeTrue(a, quiet) { shouldBe(a, "true", quiet); }
404 function shouldBeTrueQuiet(a) { shouldBe(a, "true", true); }
405 function shouldBeFalse(a, quiet) { shouldBe(a, "false", quiet); }
406 function shouldBeNaN(a, quiet) { shouldBe(a, "NaN", quiet); }
407 function shouldBeNull(a, quiet) { shouldBe(a, "null", quiet); }
408 function shouldBeZero(a, quiet) { shouldBe(a, "0", quiet); }
410 function shouldBeEqualToString(a, b)
412 if (typeof a !== "string" || typeof b !== "string")
413 debug("WARN: shouldBeEqualToString() expects string arguments");
414 var unevaledString = JSON.stringify(b);
415 shouldBe(a, unevaledString);
418 function shouldBeEqualToNumber(a, b)
420 if (typeof a !== "string" || typeof b !== "number")
421 debug("WARN: shouldBeEqualToNumber() expects a string and a number arguments");
422 var unevaledString = JSON.stringify(b);
423 shouldBe(a, unevaledString);
426 function shouldBeEmptyString(a) { shouldBeEqualToString(a, ""); }
428 function shouldEvaluateTo(actual, expected, opt_tolerance) {
429 // A general-purpose comparator. 'actual' should be a string to be
430 // evaluated, as for shouldBe(). 'expected' may be any type and will be
431 // used without being eval'ed.
432 if (expected == null) {
433 // Do this before the object test, since null is of type 'object'.
434 shouldBeNull(actual);
435 } else if (typeof expected == "undefined") {
436 shouldBeUndefined(actual);
437 } else if (typeof expected == "function") {
438 // All this fuss is to avoid the string-arg warning from shouldBe().
440 var actualValue = eval(actual);
442 testFailed("Evaluating " + actual + ": Threw exception " + e);
445 shouldBe("'" + actualValue.toString().replace(/\n/g, "") + "'",
446 "'" + expected.toString().replace(/\n/g, "") + "'");
447 } else if (typeof expected == "object") {
448 shouldBeTrue(actual + " == '" + expected + "'");
449 } else if (typeof expected == "string") {
450 shouldBe(actual, expected, undefined, opt_tolerance);
451 } else if (typeof expected == "boolean") {
452 shouldBe("typeof " + actual, "'boolean'");
454 shouldBeTrue(actual);
456 shouldBeFalse(actual);
457 } else if (typeof expected == "number") {
459 shouldBeCloseTo(actual, expected, opt_tolerance);
461 shouldBe(actual, stringify(expected));
463 debug(expected + " is unknown type " + typeof expected);
464 shouldBeTrue(actual, "'" +expected.toString() + "'");
468 function shouldBeNonZero(_a)
479 testFailed(_a + " should be non-zero. Threw exception " + _exception);
481 testPassed(_a + " is non-zero.");
483 testFailed(_a + " should be non-zero. Was " + _av);
486 function shouldBeNonNull(_a)
497 testFailed(_a + " should be non-null. Threw exception " + _exception);
498 else if (_av != null)
499 testPassed(_a + " is non-null.");
501 testFailed(_a + " should be non-null. Was " + _av);
504 function shouldBeUndefined(_a)
515 testFailed(_a + " should be undefined. Threw exception " + _exception);
516 else if (typeof _av == "undefined")
517 testPassed(_a + " is undefined.");
519 testFailed(_a + " should be undefined. Was " + _av);
522 function shouldBeDefined(_a)
533 testFailed(_a + " should be defined. Threw exception " + _exception);
534 else if (_av !== undefined)
535 testPassed(_a + " is defined.");
537 testFailed(_a + " should be defined. Was " + _av);
540 function shouldBeGreaterThan(_a, _b) {
541 if (typeof _a != "string" || typeof _b != "string")
542 debug("WARN: shouldBeGreaterThan expects string arguments");
554 testFailed(_a + " should be > " + _b + ". Threw exception " + _exception);
555 else if (typeof _av == "undefined" || _av <= _bv)
556 testFailed(_a + " should be > " + _b + ". Was " + _av + " (of type " + typeof _av + ").");
558 testPassed(_a + " is > " + _b);
561 function shouldBeGreaterThanOrEqual(_a, _b) {
562 if (typeof _a != "string" || typeof _b != "string")
563 debug("WARN: shouldBeGreaterThanOrEqual expects string arguments");
575 testFailed(_a + " should be >= " + _b + ". Threw exception " + _exception);
576 else if (typeof _av == "undefined" || _av < _bv)
577 testFailed(_a + " should be >= " + _b + ". Was " + _av + " (of type " + typeof _av + ").");
579 testPassed(_a + " is >= " + _b);
582 function shouldNotThrow(_a) {
585 testPassed(_a + " did not throw exception.");
587 testFailed(_a + " should not throw exception. Threw exception " + e + ".");
591 function shouldThrow(_a, _e)
606 if (typeof _e == "undefined" || _exception == _ev)
607 testPassed(_a + " threw exception " + _exception + ".");
609 testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + _exception + ".");
610 } else if (typeof _av == "undefined")
611 testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
613 testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
616 function shouldBeNow(a, delta)
618 // Right now, V8 and Chromium / Blink use two different clock
619 // implementations. On Windows, the implementations are non-trivial and can
620 // be slightly out of sync. The delta is intended to compensate for that.
622 // FIXME: reconsider this when the V8 and Blink clocks get unified, see http://crbug.com/324110
623 if (delta === undefined)
626 for (var i = 0; i < 1000; ++i) {
627 var startDate = Date.now();
629 var date = av.valueOf();
630 var endDate = Date.now();
632 // On some occasions such as NTP updates, the current time can go
633 // backwards. This should only happen rarely, so we can get away with
634 // retrying the test a few times if we detect the time going backwards.
635 if (startDate > endDate)
638 if (typeof date !== "number") {
639 testFailed(a + " is not a number or a Date. Got " + av);
642 if (date < startDate - delta) {
643 testFailed(a + " is not the curent time. Got " + av + " which is " + (startDate - date) / 1000 + " seconds in the past.");
646 if (date > endDate + delta) {
647 testFailed(a + " is not the current time. Got " + av + " which is " + (date - endDate) / 1000 + " seconds in the future.");
651 testPassed(a + " is equivalent to Date.now().");
654 testFailed(a + " cannot be tested against the current time. The clock is going backwards too often.");
657 function expectError()
659 if (expectingError) {
660 testFailed("shouldHaveError() called twice before an error occurred!");
662 expectingError = true;
665 function shouldHaveHadError(message)
667 if (expectingError) {
668 testFailed("No error thrown between expectError() and shouldHaveHadError()");
672 if (expectedErrorMessage) {
674 testPassed("Got expected error");
675 else if (expectedErrorMessage.indexOf(message) !== -1)
676 testPassed("Got expected error: '" + message + "'");
678 testFailed("Unexpected error '" + message + "'");
679 expectedErrorMessage = undefined;
683 testFailed("expectError() not called before shouldHaveHadError()");
686 // With Oilpan tests that rely on garbage collection need to go through
687 // the event loop in order to get precise garbage collections. Oilpan
688 // uses conservative stack scanning when not at the event loop and that
689 // can artificially keep objects alive. Therefore, tests that need to check
690 // that something is dead need to use this asynchronous collectGarbage
692 function asyncGC(callback) {
693 GCController.collectAll();
694 setTimeout(callback, 0);
698 if (typeof GCController !== "undefined")
699 GCController.collectAll();
701 var gcRec = function (n) {
704 var temp = {i: "ab" + i + (i / 100000)};
708 for (var i = 0; i < 1000; i++)
713 function asyncMinorGC(callback) {
714 if (typeof GCController !== "undefined")
715 GCController.minorCollect();
717 testFailed("Minor GC is available only when you enable the --expose-gc option in V8.");
718 setTimeout(callback, 0);
721 function isSuccessfullyParsed()
723 // FIXME: Remove this and only report unexpected syntax errors.
724 successfullyParsed = !unexpectedErrorMessage;
725 shouldBeTrue("successfullyParsed");
726 debug('<br /><span class="pass">TEST COMPLETE</span>');
729 var wasPostTestScriptParsed, wasFinishJSTestCalled, jsTestIsAsync;
731 // It's possible for an async test to call finishJSTest() before js-test-post.js
733 function finishJSTest()
735 wasFinishJSTestCalled = true;
736 if (!self.wasPostTestScriptParsed)
738 isSuccessfullyParsed();
739 if (self.jsTestIsAsync && self.testRunner)
740 testRunner.notifyDone();
743 function startWorker(testScriptURL, shared)
745 self.jsTestIsAsync = true;
746 debug('Starting worker: ' + testScriptURL);
747 var worker = shared ? new SharedWorker(testScriptURL, "Shared Worker") : new Worker(testScriptURL);
748 worker.onmessage = function(event)
750 var workerPrefix = "[Worker] ";
751 if (event.data.length < 5 || event.data.charAt(4) != ':') {
752 debug(workerPrefix + event.data);
755 var code = event.data.substring(0, 4);
756 var payload = workerPrefix + event.data.substring(5);
759 else if (code == "FAIL")
761 else if (code == "DESC")
762 description(payload);
763 else if (code == "DONE")
766 debug(workerPrefix + event.data);
769 worker.onerror = function(event)
771 debug('Got error from worker: ' + event.message);
776 worker.port.onmessage = function(event) { worker.onmessage(event); };
783 var workerPort = self;
784 if (self.name == "Shared Worker") {
785 self.onconnect = function(e) {
786 workerPort = e.ports[0];
787 workerPort.onmessage = function(event)
789 var colon = event.data.indexOf(":");
791 testFailed("Unrecognized message to shared worker: " + event.data);
794 var code = event.data.substring(0, colon);
795 var payload = event.data.substring(colon + 1);
797 if (code == "IMPORT")
798 importScripts(payload);
800 testFailed("Unrecognized message to shared worker: " + event.data);
802 testFailed("Caught exception in shared worker onmessage: " + ex);
807 description = function(msg, quiet) {
808 workerPort.postMessage('DESC:' + msg);
810 testFailed = function(msg) {
811 workerPort.postMessage('FAIL:' + msg);
813 testPassed = function(msg) {
814 workerPort.postMessage('PASS:' + msg);
816 finishJSTest = function() {
817 workerPort.postMessage('DONE:');
819 debug = function(msg) {
820 workerPort.postMessage(msg);