OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 goog.require('goog.DevTools.Connection'); |
| 6 goog.provide('goog.DevTools.TestHarness'); |
| 7 |
| 8 goog.scope(function() { |
| 9 |
| 10 /** |
| 11 * The DevTools connection |
| 12 * |
| 13 * @private {!goog.DevTools.Connection} |
| 14 */ |
| 15 goog.DevTools.TestHarness.connection_ = |
| 16 new goog.DevTools.Connection(window.TabSocket); |
| 17 |
| 18 /** |
| 19 * Asks the C++ test harness to quit. |
| 20 * |
| 21 * @private |
| 22 */ |
| 23 goog.DevTools.TestHarness.QuitTest_ = function() { |
| 24 goog.DevTools.TestHarness.connection_.sendDevToolsMessage('__QuitTest', {}); |
| 25 }; |
| 26 |
| 27 /** |
| 28 * Used to report a test failure. |
| 29 * |
| 30 * @param {string} error The error message to report. |
| 31 */ |
| 32 goog.DevTools.TestHarness.FailTest = function(error) { |
| 33 goog.DevTools.TestHarness.connection_.sendDevToolsMessage('__FailTest', |
| 34 {"error": error}); |
| 35 }; |
| 36 |
| 37 /** |
| 38 * Asks the C++ test harness to log a message. |
| 39 * |
| 40 * @param {string} message The message to report. |
| 41 */ |
| 42 goog.DevTools.TestHarness.Log = function(message) { |
| 43 goog.DevTools.TestHarness.connection_.sendDevToolsMessage( |
| 44 '__Log', {"message": message}); |
| 45 }; |
| 46 |
| 47 /** |
| 48 * @class A simple asynchronous test class. |
| 49 * @param {!goog.DevTools.Connection} connection The DevTools connection. |
| 50 * @param {string} testName The name of the test to run. |
| 51 * @param {!function(!goog.DevTools.Test)} testFunction The test function |
| 52 * @constructor |
| 53 */ |
| 54 goog.DevTools.Test = function(connection, testName, testFunction) { |
| 55 /** |
| 56 * @type {!goog.DevTools.Connection} |
| 57 */ |
| 58 this.connection_ = connection; |
| 59 |
| 60 /** |
| 61 * @type {string} |
| 62 */ |
| 63 this.testName_ = testName; |
| 64 |
| 65 /** |
| 66 * @type {!function(!goog.DevTools.Test)} |
| 67 */ |
| 68 this.testFunction_ = testFunction; |
| 69 |
| 70 /** |
| 71 * @private {boolean} |
| 72 */ |
| 73 this.testPassed_ = true; |
| 74 }; |
| 75 |
| 76 /** |
| 77 * Used to report a test failure. |
| 78 * |
| 79 * @param {string} error The error message to report. |
| 80 */ |
| 81 goog.DevTools.Test.prototype.Fail = function(error) { |
| 82 this.testPassed_ = false; |
| 83 goog.DevTools.TestHarness.Log(error); |
| 84 }; |
| 85 |
| 86 |
| 87 /** |
| 88 * Compares two JavaScript values for type and value equality. |
| 89 * It checks internals of arrays and objects. |
| 90 */ |
| 91 function deepEquals(a, b) { |
| 92 if (a === b) { |
| 93 // Check for -0. |
| 94 if (a === 0) return (1 / a) === (1 / b); |
| 95 return true; |
| 96 } |
| 97 if (typeof a != typeof b) return false; |
| 98 if (typeof a == 'number') return isNaN(a) && isNaN(b); |
| 99 if (typeof a !== 'object' && typeof a !== 'function') return false; |
| 100 // Neither a nor b is primitive. |
| 101 var objectClass = classOf(a); |
| 102 if (objectClass !== classOf(b)) return false; |
| 103 if (objectClass === 'RegExp') { |
| 104 // For RegExp, just compare pattern and flags using its toString. |
| 105 return (a.toString() === b.toString()); |
| 106 } |
| 107 // Functions are only identical to themselves. |
| 108 if (objectClass === 'Function') return false; |
| 109 if (objectClass === 'Array') { |
| 110 var elementCount = 0; |
| 111 if (a.length != b.length) { |
| 112 return false; |
| 113 } |
| 114 for (var i = 0; i < a.length; i++) { |
| 115 if (!deepEquals(a[i], b[i])) return false; |
| 116 } |
| 117 return true; |
| 118 } |
| 119 if (objectClass == 'String' || objectClass == 'Number' || |
| 120 objectClass == 'Boolean' || objectClass == 'Date') { |
| 121 if (a.valueOf() !== b.valueOf()) return false; |
| 122 } |
| 123 return deepObjectEquals(a, b); |
| 124 } |
| 125 |
| 126 |
| 127 /** |
| 128 * @param {*} expected The expected result. |
| 129 * @param {*} found The value found. |
| 130 * @param {string=} opt_message Optional message. |
| 131 */ |
| 132 goog.DevTools.Test.prototype.AssertEq = function(expected, found, opt_message) { |
| 133 if (!deepEquals(expected, found)) { |
| 134 this.Fail('Expected \'' + JSON.stringify(expected) +'\' but found \'' + |
| 135 JSON.stringify(found) + '\' ' + (opt_message ? opt_message : '')); |
| 136 } |
| 137 }; |
| 138 |
| 139 |
| 140 /** |
| 141 * Used to report the end of the test. |
| 142 */ |
| 143 goog.DevTools.Test.prototype.Finish = function() { |
| 144 if (this.testPassed_) { |
| 145 goog.DevTools.TestHarness.Log('[ OK ] ' + this.testName_); |
| 146 goog.DevTools.TestHarness.RunTests(); |
| 147 } else { |
| 148 goog.DevTools.TestHarness.FailTest('[ FAIL ] ' + this.testName_); |
| 149 } |
| 150 }; |
| 151 |
| 152 |
| 153 /** |
| 154 * The tests to run. |
| 155 * |
| 156 * @private {!Array.<!goog.DevTools.Test>} |
| 157 */ |
| 158 goog.DevTools.TestHarness.tests_ = []; |
| 159 |
| 160 /** |
| 161 * Asks the C++ test harness to quit and report an error. |
| 162 * |
| 163 * @param {string} testName The name of the test to run. |
| 164 * @param {!function(!goog.DevTools.Test)} testFunction A test to run. |
| 165 */ |
| 166 goog.DevTools.TestHarness.AddTest = function(testName, testFunction) { |
| 167 goog.DevTools.TestHarness.tests_.push( |
| 168 new goog.DevTools.Test(goog.DevTools.TestHarness.connection_, testName, |
| 169 testFunction)); |
| 170 }; |
| 171 |
| 172 /** |
| 173 * Runs the next test in the list. |
| 174 */ |
| 175 goog.DevTools.TestHarness.RunTests = function() { |
| 176 let test = goog.DevTools.TestHarness.tests_.shift(); |
| 177 if (test === undefined) { |
| 178 goog.DevTools.TestHarness.QuitTest_(); |
| 179 } else { |
| 180 goog.DevTools.TestHarness.Log('[ RUN ] ' + test.testName_); |
| 181 test.testFunction_(test); |
| 182 } |
| 183 }; |
| 184 |
| 185 }); // goog.scope |
OLD | NEW |