Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Library providing basic test framework functionality. | 5 // Library providing basic test framework functionality. |
| 6 | 6 |
| 7 (function() { | 7 (function() { |
| 8 // Asserts. | |
| 9 // Use the following assertions to verify a condition within a test. | |
| 10 // If assertion fails, the C++ backend will be immediately notified. | |
| 11 // If assertion passes, no notification will be sent to the C++ backend. | |
| 12 function assertBool(test, expected, message) { | |
| 13 if (test !== expected) { | |
| 14 if (message) | |
| 15 message = test + '\n' + message; | |
| 16 else | |
| 17 message = test; | |
| 18 throw new Error(message); | |
| 19 } | |
| 20 } | |
| 21 | |
| 22 var old_chrome = chrome; | 8 var old_chrome = chrome; |
| 23 var send_callbacks = {}; | 9 var send_callbacks = {}; |
| 24 | 10 |
| 25 function registerMessageCallback(name, object, callback) { | 11 function registerMessageCallback(name, object, callback) { |
| 26 send_callbacks[name] = [object, callback]; | 12 send_callbacks[name] = [object, callback]; |
| 27 } | 13 } |
| 28 | 14 |
| 29 function send(messageName) { | 15 function send(messageName) { |
| 30 var callback = send_callbacks[messageName]; | 16 var callback = send_callbacks[messageName]; |
| 31 var args = Array.prototype.slice.call(arguments, 1); | 17 var args = Array.prototype.slice.call(arguments, 1); |
| 32 if (callback != undefined) | 18 if (callback != undefined) |
| 33 callback[1].apply(callback[0], args); | 19 callback[1].apply(callback[0], args); |
| 34 else | 20 else |
| 35 old_chrome.send.apply(old_chrome, args); | 21 old_chrome.send.apply(old_chrome, args); |
| 36 } | 22 } |
| 37 | 23 |
| 24 function CallHelper() { | |
| 25 this.__proto__ = CallHelper.prototype; | |
| 26 } | |
| 27 | |
| 28 CallHelper.prototype = { | |
| 29 'counts_': {}, | |
| 30 'registerCall': function() { | |
| 31 var caller = arguments.callee.caller; | |
| 32 var caller_name = caller.name; | |
| 33 var caller_caller = caller.caller; | |
| 34 if (caller_caller['isExpect']) { | |
| 35 caller_name = caller_caller.expectName; | |
| 36 caller_caller = caller_caller.caller; | |
| 37 } | |
| 38 var caller_caller_string = caller_caller.toString(); | |
| 39 if (!(caller_caller_string in this.counts_)) | |
| 40 this.counts_[caller_caller_string] = {}; | |
| 41 if (!(caller_name in this.counts_[caller_caller_string])) | |
| 42 this.counts_[caller_caller_string][caller_name] = 0; | |
| 43 ++this.counts_[caller_caller_string][caller_name]; | |
| 44 }, | |
| 45 'matchedParamsIndex': function(string, index) { | |
| 46 var args = []; | |
| 47 var parencount = 1; | |
|
David Tseng
2011/07/08 23:45:11
why not 0?
Sheridan Rawlins
2011/07/14 23:32:31
Because you found the first paren, hence 1.
On 20
| |
| 48 var arg_start = index + 1; | |
| 49 for(index = arg_start; | |
| 50 parencount && index < string.length; | |
|
David Tseng
2011/07/08 23:45:11
parenCount
Sheridan Rawlins
2011/07/14 23:32:31
Done.
| |
| 51 ++index) { | |
| 52 if (string[index] == '(') { | |
| 53 ++parencount; | |
| 54 } else if (string[index] == ')') { | |
| 55 --parencount; | |
| 56 } else if (string[index] == ',' && parencount == 1) { | |
| 57 args.push(string.substring(arg_start, index)); | |
| 58 arg_start = index + 1; | |
| 59 } | |
| 60 } | |
| 61 args.push(string.substring(arg_start, index - 1)); | |
|
David Tseng
2011/07/08 23:45:11
confused...this is outside of the loop?
Sheridan Rawlins
2011/07/14 23:32:31
Moved inside the loop.
| |
| 62 return [index, args]; | |
| 63 }, | |
| 64 'getParams': function(caller_, count_) { | |
| 65 var caller = (caller_ == undefined) ? | |
| 66 arguments.callee.caller : caller_; | |
| 67 var caller_name = caller.name; | |
| 68 var caller_caller = caller.caller; | |
| 69 if (caller_caller['isExpect']) { | |
|
David Tseng
2011/07/08 23:45:11
Would prefer if we didn't special case this (see b
| |
| 70 caller_name = caller_caller.expectName; | |
| 71 caller_caller = caller_caller.caller; | |
|
David Tseng
2011/07/08 23:45:11
Would prefer if we just printed the whole stack tr
Sheridan Rawlins
2011/07/14 23:32:31
We're trying to single out the text of the call. W
| |
| 72 } | |
| 73 var caller_caller_string = caller_caller.toString(); | |
| 74 var count = (count_ == undefined) ? | |
| 75 this.counts_[caller_caller_string][caller_name] : count_; | |
| 76 var search_start = 0; | |
| 77 var args; | |
| 78 for(var i = 0; | |
| 79 i < count && search_start < caller_caller_string.length; | |
| 80 ++i) { | |
| 81 search_start = caller_caller_string.indexOf( | |
| 82 caller_name, search_start); | |
| 83 if (search_start == -1) { | |
| 84 if (i && count_ == undefined) { | |
| 85 return this.getParams(caller, ((count - 1) % i) + 1); | |
| 86 } else { | |
| 87 console.error('bad count ' + count); | |
| 88 return undefined; | |
| 89 } | |
| 90 } | |
| 91 search_start += caller_name.length; | |
|
David Tseng
2011/07/08 23:45:11
searchStart
Sheridan Rawlins
2011/07/14 23:32:31
Done.
| |
| 92 var matched = this.matchedParamsIndex(caller_caller_string, | |
| 93 search_start); | |
| 94 args = matched[1]; | |
| 95 search_start = matched[0]; | |
| 96 } | |
| 97 return args; | |
| 98 }, | |
| 99 'getCall': function() { | |
|
David Tseng
2011/07/08 23:45:11
Why don't we just generate the whole stack trace?
Sheridan Rawlins
2011/07/14 23:32:31
we do (it's in the Error and returned to C++)
On
| |
| 100 var caller = arguments.callee.caller; | |
| 101 var caller_name = caller.name; | |
| 102 var caller_caller = caller.caller; | |
| 103 if (caller_caller['isExpect']) { | |
| 104 caller_name = caller_caller.expectName; | |
| 105 caller_caller = caller_caller.caller; | |
| 106 } | |
| 107 return caller_name + '(' + this.getParams(caller) + ')'; | |
| 108 }, | |
| 109 }; | |
| 110 | |
| 111 var helper = new CallHelper(); | |
| 112 | |
| 113 // Asserts. | |
| 114 // Use the following assertions to verify a condition within a test. | |
| 115 // If assertion fails, the C++ backend will be immediately notified. | |
| 116 // If assertion passes, no notification will be sent to the C++ backend. | |
| 117 function assertBool(test, expected, message) { | |
| 118 helper.registerCall(); | |
| 119 if (test !== expected) { | |
| 120 throw new Error('Test Error ' + helper.getCall() + ': ' + test); | |
| 121 } | |
| 122 } | |
| 123 | |
| 38 function assertTrue(test, message) { | 124 function assertTrue(test, message) { |
| 39 assertBool(test, true, message); | 125 helper.registerCall(); |
| 126 if (test !== true) { | |
| 127 throw new Error('Test Error ' + helper.getCall() + ': ' + test); | |
| 128 } | |
| 40 } | 129 } |
| 41 | 130 |
| 42 function assertFalse(test, message) { | 131 function assertFalse(test, message) { |
| 43 assertBool(test, false, message); | 132 helper.registerCall(); |
| 133 if (test !== false) { | |
| 134 throw new Error('Test Error ' + helper.getCall() + ': ' + test); | |
| 135 } | |
| 44 } | 136 } |
| 45 | 137 |
| 46 function assertEquals(expected, actual, message) { | 138 function assertEquals(expected, actual, message) { |
| 139 helper.registerCall(); | |
| 47 if (expected != actual) { | 140 if (expected != actual) { |
| 48 throw new Error('Test Error. Actual: ' + actual + '\nExpected: ' + | 141 throw new Error( |
| 49 expected + '\n' + message); | 142 'Test Error ' + helper.getCall() + '\nActual: ' + actual + |
| 143 '; Expected: ' + expected); | |
| 50 } | 144 } |
| 51 if (typeof expected != typeof actual) { | 145 if (typeof expected != typeof actual) { |
| 52 throw new Error('Test Error' + | 146 throw new Error( |
| 53 ' (type mismatch)\nActual Type: ' + typeof actual + | 147 'Test Error (type mismatch) ' + helper.GetCall() + |
| 54 '\nExpected Type:' + typeof expected + '\n' + message); | 148 '\nActual Type: ' + typeof actual + |
| 149 '\nExpected Type:' + typeof expected); | |
| 55 } | 150 } |
| 56 } | 151 } |
| 57 | 152 |
| 58 function assertNotReached(message) { | 153 function assertNotReached(message) { |
| 154 helper.registerCall(); | |
| 59 throw new Error(message); | 155 throw new Error(message); |
| 60 } | 156 } |
| 61 | 157 |
| 62 var errors = []; | 158 var errors = []; |
| 63 | 159 |
| 64 function createExpect(assertFunc) { | 160 function createExpect(assertFunc) { |
| 65 return function() { | 161 var expect_func = function() { |
| 66 try { | 162 try { |
| 67 assertFunc.apply(null, arguments); | 163 assertFunc.apply(null, arguments); |
| 68 } catch (e) { | 164 } catch (e) { |
| 69 console.log('Failed: ' + currentTest.name + '\n' + e.stack); | 165 console.log('Failed: ' + currentTest.name + '\n' + e.stack); |
| 70 errors.push(e); | 166 errors.push(e); |
| 71 } | 167 } |
| 72 }; | 168 }; |
| 169 expect_func.__proto__ = Function.prototype; | |
|
David Tseng
2011/07/08 23:45:11
expectFunc (or expectHelper).
Sheridan Rawlins
2011/07/14 23:32:31
Done.
| |
| 170 expect_func.expectName = assertFunc.name.replace(/^assert/, 'expect'); | |
| 171 expect_func.isExpect = true; | |
|
David Tseng
2011/07/08 23:45:11
Why don't we just subclass TOString to print out t
Sheridan Rawlins
2011/07/14 23:32:31
We would still need to do the replace somewhere -
| |
| 172 return expect_func; | |
| 73 } | 173 } |
| 74 | 174 |
| 75 function runTest(testFunction, testArguments) { | 175 function runTest(testFunction, testArguments) { |
| 76 errors = []; | 176 errors = []; |
| 77 // Avoid eval() if at all possible, since it will not work on pages | 177 // Avoid eval() if at all possible, since it will not work on pages |
| 78 // that have enabled content-security-policy. | 178 // that have enabled content-security-policy. |
| 79 currentTest = this[testFunction]; // global object -- not a method. | 179 currentTest = this[testFunction]; // global object -- not a method. |
| 80 if (typeof currentTest === "undefined") { | 180 if (typeof currentTest === "undefined") { |
| 81 currentTest = eval(testFunction); | 181 currentTest = eval(testFunction); |
| 82 } | 182 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 101 window.assertEquals = assertEquals; | 201 window.assertEquals = assertEquals; |
| 102 window.assertNotReached = assertNotReached; | 202 window.assertNotReached = assertNotReached; |
| 103 window.expectTrue = createExpect(assertTrue); | 203 window.expectTrue = createExpect(assertTrue); |
| 104 window.expectFalse = createExpect(assertFalse); | 204 window.expectFalse = createExpect(assertFalse); |
| 105 window.expectEquals = createExpect(assertEquals); | 205 window.expectEquals = createExpect(assertEquals); |
| 106 window.expectNotReached = createExpect(assertNotReached); | 206 window.expectNotReached = createExpect(assertNotReached); |
| 107 window.registerMessageCallback = registerMessageCallback; | 207 window.registerMessageCallback = registerMessageCallback; |
| 108 window.runTest = runTest; | 208 window.runTest = runTest; |
| 109 window.preloadJavascriptLibraries = preloadJavascriptLibraries; | 209 window.preloadJavascriptLibraries = preloadJavascriptLibraries; |
| 110 })(); | 210 })(); |
| OLD | NEW |