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 |