Index: tools/cc-frame-viewer/src/base/unittest.js |
diff --git a/tools/cc-frame-viewer/src/base/unittest.js b/tools/cc-frame-viewer/src/base/unittest.js |
deleted file mode 100644 |
index 7d134b65acac4f15344d20144503034f80b639d9..0000000000000000000000000000000000000000 |
--- a/tools/cc-frame-viewer/src/base/unittest.js |
+++ /dev/null |
@@ -1,557 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-'use strict'; |
- |
-/** |
- * @fileoverview A test harness loosely based on Python unittest, but that |
- * installs global assert methods during the test for backward compatibility |
- * with Closure tests. |
- */ |
-base.requireStylesheet('base.unittest'); |
-base.exportTo('base.unittest', function() { |
- |
- var NOCATCH_MODE = false; |
- |
- // Uncomment the line below to make unit test failures throw exceptions. |
- NOCATCH_MODE = true; |
- |
- function createTestCaseDiv(testName, opt_href, opt_alwaysShowErrorLink) { |
- var el = document.createElement('test-case'); |
- |
- var titleBlockEl = document.createElement('title'); |
- titleBlockEl.style.display = 'inline'; |
- el.appendChild(titleBlockEl); |
- |
- var titleEl = document.createElement('span'); |
- titleEl.style.marginRight = '20px'; |
- titleBlockEl.appendChild(titleEl); |
- |
- var errorLink = document.createElement('a'); |
- errorLink.textContent = 'Run individually...'; |
- if (opt_href) |
- errorLink.href = opt_href; |
- else |
- errorLink.href = '#' + testName; |
- errorLink.style.display = 'none'; |
- titleBlockEl.appendChild(errorLink); |
- |
- el.__defineSetter__('status', function(status) { |
- titleEl.textContent = testName + ': ' + status; |
- updateClassListGivenStatus(titleEl, status); |
- if (status == 'FAILED' || opt_alwaysShowErrorLink) |
- errorLink.style.display = ''; |
- else |
- errorLink.style.display = 'none'; |
- }); |
- |
- el.addError = function(test, e) { |
- var errorEl = createErrorDiv(test, e); |
- el.appendChild(errorEl); |
- return errorEl; |
- }; |
- |
- el.addHTMLOutput = function(opt_title, opt_element) { |
- var outputEl = createOutputDiv(opt_title, opt_element); |
- el.appendChild(outputEl); |
- return outputEl.contents; |
- }; |
- |
- el.status = 'READY'; |
- return el; |
- } |
- |
- function createErrorDiv(test, e) { |
- var el = document.createElement('test-case-error'); |
- el.className = 'unittest-error'; |
- |
- var stackEl = document.createElement('test-case-stack'); |
- if (typeof e == 'string') { |
- stackEl.textContent = e; |
- } else if (e.stack) { |
- var i = document.location.pathname.lastIndexOf('/'); |
- var path = document.location.origin + |
- document.location.pathname.substring(0, i); |
- var pathEscaped = path.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); |
- var cleanStack = e.stack.replace(new RegExp(pathEscaped, 'g'), '.'); |
- stackEl.textContent = cleanStack; |
- } else { |
- stackEl.textContent = e; |
- } |
- el.appendChild(stackEl); |
- return el; |
- } |
- |
- function createOutputDiv(opt_title, opt_element) { |
- var el = document.createElement('test-case-output'); |
- if (opt_title) { |
- var titleEl = document.createElement('div'); |
- titleEl.textContent = opt_title; |
- el.appendChild(titleEl); |
- } |
- var contentEl = opt_element || document.createElement('div'); |
- el.appendChild(contentEl); |
- |
- el.__defineGetter__('contents', function() { |
- return contentEl; |
- }); |
- return el; |
- } |
- |
- function statusToClassName(status) { |
- if (status == 'PASSED') |
- return 'unittest-green'; |
- else if (status == 'RUNNING' || status == 'READY') |
- return 'unittest-yellow'; |
- else |
- return 'unittest-red'; |
- } |
- |
- function updateClassListGivenStatus(el, status) { |
- var newClass = statusToClassName(status); |
- if (newClass != 'unittest-green') |
- el.classList.remove('unittest-green'); |
- if (newClass != 'unittest-yellow') |
- el.classList.remove('unittest-yellow'); |
- if (newClass != 'unittest-red') |
- el.classList.remove('unittest-red'); |
- |
- el.classList.add(newClass); |
- } |
- |
- function HTMLTestRunner(opt_title, opt_curHash) { |
- // This constructs a HTMLDivElement and then adds our own runner methods to |
- // it. This is usually done via ui.js' define system, but we dont want our |
- // test runner to be dependent on the UI lib. :) |
- var outputEl = document.createElement('unittest-test-runner'); |
- outputEl.__proto__ = HTMLTestRunner.prototype; |
- this.decorate.call(outputEl, opt_title, opt_curHash); |
- return outputEl; |
- } |
- |
- HTMLTestRunner.prototype = { |
- __proto__: HTMLDivElement.prototype, |
- |
- decorate: function(opt_title, opt_curHash) { |
- this.running = false; |
- |
- this.currentTest_ = undefined; |
- this.results = undefined; |
- if (opt_curHash) { |
- var trimmedHash = opt_curHash.substring(1); |
- this.filterFunc_ = function(testName) { |
- return testName.indexOf(trimmedHash) == 0; |
- }; |
- } else |
- this.filterFunc_ = function(testName) { return true; }; |
- |
- this.statusEl_ = document.createElement('title'); |
- this.appendChild(this.statusEl_); |
- |
- this.resultsEl_ = document.createElement('div'); |
- this.appendChild(this.resultsEl_); |
- |
- this.title_ = opt_title || document.title; |
- |
- this.updateStatus(); |
- }, |
- |
- computeResultStats: function() { |
- var numTestsRun = 0; |
- var numTestsPassed = 0; |
- var numTestsWithErrors = 0; |
- if (this.results) { |
- for (var i = 0; i < this.results.length; i++) { |
- numTestsRun++; |
- if (this.results[i].errors.length) |
- numTestsWithErrors++; |
- else |
- numTestsPassed++; |
- } |
- } |
- return { |
- numTestsRun: numTestsRun, |
- numTestsPassed: numTestsPassed, |
- numTestsWithErrors: numTestsWithErrors |
- }; |
- }, |
- |
- updateStatus: function() { |
- var stats = this.computeResultStats(); |
- var status; |
- if (!this.results) { |
- status = 'READY'; |
- } else if (this.running) { |
- status = 'RUNNING'; |
- } else { |
- if (stats.numTestsRun && stats.numTestsWithErrors == 0) |
- status = 'PASSED'; |
- else |
- status = 'FAILED'; |
- } |
- |
- updateClassListGivenStatus(this.statusEl_, status); |
- this.statusEl_.textContent = this.title_ + ' [' + status + ']'; |
- }, |
- |
- get done() { |
- return this.results && this.running == false; |
- }, |
- |
- run: function(tests) { |
- this.results = []; |
- this.running = true; |
- this.updateStatus(); |
- for (var i = 0; i < tests.length; i++) { |
- if (!this.filterFunc_(tests[i].testName)) |
- continue; |
- tests[i].run(this); |
- this.updateStatus(); |
- } |
- this.running = false; |
- this.updateStatus(); |
- }, |
- |
- willRunTest: function(test) { |
- this.currentTest_ = test; |
- this.currentResults_ = {testName: test.testName, |
- errors: []}; |
- this.results.push(this.currentResults_); |
- |
- this.currentTestCaseEl_ = createTestCaseDiv(test.testName); |
- this.currentTestCaseEl_.status = 'RUNNING'; |
- this.resultsEl_.appendChild(this.currentTestCaseEl_); |
- }, |
- |
- /** |
- * Adds some html content to the currently running test |
- * @param {String} opt_title The title for the output. |
- * @param {HTMLElement} opt_element The element to add. If not added, then. |
- * @return {HTMLElement} The element added, or if !opt_element, the element |
- * created. |
- */ |
- addHTMLOutput: function(opt_title, opt_element) { |
- return this.currentTestCaseEl_.addHTMLOutput(opt_title, opt_element); |
- }, |
- |
- addError: function(e) { |
- this.currentResults_.errors.push(e); |
- return this.currentTestCaseEl_.addError(this.currentTest_, e); |
- }, |
- |
- didRunTest: function(test) { |
- if (!this.currentResults_.errors.length) |
- this.currentTestCaseEl_.status = 'PASSED'; |
- else |
- this.currentTestCaseEl_.status = 'FAILED'; |
- |
- this.currentResults_ = undefined; |
- this.currentTest_ = undefined; |
- } |
- }; |
- |
- function TestError(opt_message) { |
- var that = new Error(opt_message); |
- Error.captureStackTrace(that, TestError); |
- that.__proto__ = TestError.prototype; |
- return that; |
- } |
- |
- TestError.prototype = { |
- __proto__: Error.prototype |
- }; |
- |
- /* |
- * @constructor TestCase |
- */ |
- function TestCase(testMethod, opt_testMethodName) { |
- if (!testMethod) |
- throw new Error('testMethod must be provided'); |
- if (testMethod.name == '' && !opt_testMethodName) |
- throw new Error('testMethod must have a name, ' + |
- 'or opt_testMethodName must be provided.'); |
- |
- this.testMethod_ = testMethod; |
- this.testMethodName_ = opt_testMethodName || testMethod.name; |
- this.results_ = undefined; |
- }; |
- |
- function forAllAssertAndEnsureMethodsIn_(prototype, fn) { |
- for (var fieldName in prototype) { |
- if (fieldName.indexOf('assert') != 0 && |
- fieldName.indexOf('ensure') != 0) |
- continue; |
- var fieldValue = prototype[fieldName]; |
- if (typeof fieldValue != 'function') |
- continue; |
- fn(fieldName, fieldValue); |
- } |
- } |
- |
- TestCase.prototype = { |
- __proto__: Object.prototype, |
- |
- get testName() { |
- return this.testMethodName_; |
- }, |
- |
- bindGlobals_: function() { |
- forAllAssertAndEnsureMethodsIn_(TestCase.prototype, |
- function(fieldName, fieldValue) { |
- global[fieldName] = fieldValue.bind(this); |
- }); |
- }, |
- |
- unbindGlobals_: function() { |
- forAllAssertAndEnsureMethodsIn_(TestCase.prototype, |
- function(fieldName, fieldValue) { |
- delete global[fieldName]; |
- }); |
- }, |
- |
- /** |
- * Adds some html content to the currently running test |
- * @param {String} opt_title The title for the output. |
- * @param {HTMLElement} opt_element The element to add. If not added, then. |
- * @return {HTMLElement} The element added, or if !opt_element, the element |
- * created. |
- */ |
- addHTMLOutput: function(opt_title, opt_element) { |
- return this.results_.addHTMLOutput(opt_title, opt_element); |
- }, |
- |
- assertTrue: function(a, opt_message) { |
- if (a) |
- return; |
- var message = opt_message || 'Expected true, got ' + a; |
- throw new TestError(message); |
- }, |
- |
- assertFalse: function(a, opt_message) { |
- if (!a) |
- return; |
- var message = opt_message || 'Expected false, got ' + a; |
- throw new TestError(message); |
- }, |
- |
- assertUndefined: function(a, opt_message) { |
- if (a === undefined) |
- return; |
- var message = opt_message || 'Expected undefined, got ' + a; |
- throw new TestError(message); |
- }, |
- |
- assertNotUndefined: function(a, opt_message) { |
- if (a !== undefined) |
- return; |
- var message = opt_message || 'Expected not undefined, got ' + a; |
- throw new TestError(message); |
- }, |
- |
- assertNull: function(a, opt_message) { |
- if (a === null) |
- return; |
- var message = opt_message || 'Expected null, got ' + a; |
- throw new TestError(message); |
- }, |
- |
- assertNotNull: function(a, opt_message) { |
- if (a !== null) |
- return; |
- var message = opt_message || 'Expected non-null, got ' + a; |
- throw new TestError(message); |
- }, |
- |
- assertEquals: function(a, b, opt_message) { |
- if (a == b) |
- return; |
- var message = opt_message || 'Expected ' + a + ', got ' + b; |
- throw new TestError(message); |
- }, |
- |
- assertNotEquals: function(a, b, opt_message) { |
- if (a != b) |
- return; |
- var message = opt_message || 'Expected something not equal to ' + b; |
- throw new TestError(message); |
- }, |
- |
- assertArrayEquals: function(a, b, opt_message) { |
- if (a.length == b.length) { |
- var ok = true; |
- for (var i = 0; i < a.length; i++) { |
- ok &= a[i] === b[i]; |
- } |
- if (ok) |
- return; |
- } |
- |
- var message = opt_message || 'Expected array ' + a + ', got array ' + b; |
- throw new TestError(message); |
- }, |
- |
- assertArrayShallowEquals: function(a, b, opt_message) { |
- if (a.length == b.length) { |
- var ok = true; |
- for (var i = 0; i < a.length; i++) { |
- ok &= a[i] === b[i]; |
- } |
- if (ok) |
- return; |
- } |
- |
- var message = opt_message || 'Expected array ' + b + ', got array ' + a; |
- throw new TestError(message); |
- }, |
- |
- assertAlmostEquals: function(a, b, opt_message) { |
- if (Math.abs(a - b) < 0.00001) |
- return; |
- var message = opt_message || 'Expected almost ' + a + ', got ' + b; |
- throw new TestError(message); |
- }, |
- |
- assertThrows: function(fn, opt_message) { |
- try { |
- fn(); |
- } catch (e) { |
- return; |
- } |
- var message = opt_message || 'Expected throw from ' + fn; |
- throw new TestError(message); |
- }, |
- |
- setUp: function() { |
- }, |
- |
- run: function(results) { |
- this.bindGlobals_(); |
- try { |
- this.results_ = results; |
- results.willRunTest(this); |
- |
- if (NOCATCH_MODE) { |
- this.setUp(); |
- this.testMethod_(); |
- this.tearDown(); |
- } else { |
- // Set up. |
- try { |
- this.setUp(); |
- } catch (e) { |
- results.addError(e); |
- return; |
- } |
- |
- // Run. |
- try { |
- this.testMethod_(); |
- } catch (e) { |
- results.addError(e); |
- } |
- |
- // Tear down. |
- try { |
- this.tearDown(); |
- } catch (e) { |
- if (typeof e == 'string') |
- e = new TestError(e); |
- results.addError(e); |
- } |
- } |
- } finally { |
- this.unbindGlobals_(); |
- results.didRunTest(this); |
- this.results_ = undefined; |
- } |
- }, |
- |
- tearDown: function() { |
- } |
- |
- }; |
- |
- /** |
- * Returns an array of TestCase objects correpsonding to the tests |
- * found in the given object. This considers any functions beginning with test |
- * as a potential test. |
- * |
- * @param {object} opt_objectToEnumerate The object to enumerate, or global if |
- * not specified. |
- * @param {RegExp} opt_filter Return only tests that match this regexp. |
- */ |
- function discoverTests(opt_objectToEnumerate, opt_filter) { |
- var objectToEnumerate = opt_objectToEnumerate || global; |
- |
- var tests = []; |
- for (var testMethodName in objectToEnumerate) { |
- if (testMethodName.search(/^test.+/) != 0) |
- continue; |
- |
- if (opt_filter && testMethodName.search(opt_filter) == -1) |
- continue; |
- |
- var testMethod = objectToEnumerate[testMethodName]; |
- if (typeof testMethod != 'function') |
- continue; |
- var testCase = new TestCase(testMethod, testMethodName); |
- tests.push(testCase); |
- } |
- tests.sort(function(a, b) { |
- return a.testName < b.testName; |
- }); |
- return tests; |
- } |
- |
- /** |
- * Runs all unit tests. |
- */ |
- function runAllTests(opt_objectToEnumerate) { |
- var runner; |
- function init() { |
- if (runner) |
- runner.parentElement.removeChild(runner); |
- runner = new HTMLTestRunner(document.title, document.location.hash); |
- // Stash the runner on global so that the global test runner |
- // can get to it. |
- global.G_testRunner = runner; |
- } |
- |
- function append() { |
- document.body.appendChild(runner); |
- } |
- |
- function run() { |
- var objectToEnumerate = opt_objectToEnumerate || global; |
- var tests = discoverTests(objectToEnumerate); |
- runner.run(tests); |
- } |
- |
- global.addEventListener('hashchange', function() { |
- init(); |
- append(); |
- run(); |
- }); |
- |
- init(); |
- if (document.body) |
- append(); |
- else |
- document.addEventListener('DOMContentLoaded', append); |
- global.addEventListener('load', run); |
- } |
- |
- if (/_test.html$/.test(document.location.pathname)) |
- runAllTests(); |
- |
- return { |
- HTMLTestRunner: HTMLTestRunner, |
- TestError: TestError, |
- TestCase: TestCase, |
- discoverTests: discoverTests, |
- runAllTests: runAllTests, |
- createErrorDiv_: createErrorDiv, |
- createTestCaseDiv_: createTestCaseDiv |
- }; |
-}); |