OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // extension_apitest.js | 5 // extension_apitest.js |
6 // mini-framework for ExtensionApiTest browser tests | 6 // mini-framework for ExtensionApiTest browser tests |
7 | 7 |
8 chrome.test = chrome.test || {}; | 8 chrome.test = chrome.test || {}; |
9 | 9 |
10 chrome.test.tests = chrome.test.tests || []; | 10 chrome.test.tests = chrome.test.tests || []; |
11 | 11 |
12 var completed = false; | |
13 var currentTest = null; | 12 var currentTest = null; |
14 var lastTest = null; | 13 var lastTest = null; |
15 | 14 var testsFailed = 0; |
16 function complete() { | 15 var testCount = 1; |
17 completed = true; | 16 var failureException = 'chrome.test.failure'; |
18 | |
19 // Try to get the script to stop running immediately. | |
20 // This isn't an error, just an attempt at saying "done". | |
21 throw "completed"; | |
22 } | |
23 | 17 |
24 // Helper function to get around the fact that function names in javascript | 18 // Helper function to get around the fact that function names in javascript |
25 // are read-only, and you can't assign one to anonymous functions. | 19 // are read-only, and you can't assign one to anonymous functions. |
26 function testName(test) { | 20 function testName(test) { |
27 return test ? (test.name || test.generatedName) : "(no test)"; | 21 return test ? (test.name || test.generatedName) : "(no test)"; |
28 } | 22 } |
29 | 23 |
30 chrome.test.fail = function(message) { | 24 function testDone() { |
31 if (completed) throw "completed"; | 25 // Use setTimeout here to allow previous test contexts to be |
32 chrome.test.log("( FAILED ) " + testName(currentTest)); | 26 // eligible for garbage collection. |
| 27 setTimeout(chrome.test.runNextTest, 0); |
| 28 } |
33 | 29 |
34 var stack = "(no stack available)"; | 30 function allTestsDone() { |
35 try { | 31 if (testsFailed == 0) { |
36 crash.me += 0; // An intentional exception to get the stack trace. | 32 chrome.test.notifyPass(); |
37 } catch (e) { | 33 } else { |
38 if (typeof(e.stack) != undefined) { | 34 chrome.test.notifyFail('Failed ' + testsFailed + ' of ' + |
39 stack = e.stack.split("\n"); | 35 testCount + ' tests'); |
40 stack = stack.slice(2); // Remove title and fail() lines. | |
41 stack = stack.join("\n"); | |
42 } | |
43 } | 36 } |
44 | 37 |
45 if (!message) { | 38 // Try to get the script to stop running immediately. |
46 message = "FAIL (no message)"; | 39 // This isn't an error, just an attempt at saying "done". |
47 } | 40 throw "completed"; |
48 message += "\n" + stack; | |
49 console.log("[FAIL] " + testName(currentTest) + ": " + message); | |
50 chrome.test.notifyFail(message); | |
51 complete(); | |
52 }; | |
53 | |
54 function allTestsSucceeded() { | |
55 console.log("All tests succeeded"); | |
56 if (completed) throw "completed"; | |
57 | |
58 chrome.test.notifyPass(); | |
59 complete(); | |
60 } | 41 } |
61 | 42 |
62 var pendingCallbacks = 0; | 43 var pendingCallbacks = 0; |
63 | 44 |
64 chrome.test.callbackAdded = function() { | 45 chrome.test.callbackAdded = function() { |
65 pendingCallbacks++; | 46 pendingCallbacks++; |
66 | 47 |
67 return function() { | 48 return function() { |
68 pendingCallbacks--; | 49 pendingCallbacks--; |
69 if (pendingCallbacks == 0) { | 50 if (pendingCallbacks == 0) { |
70 chrome.test.succeed(); | 51 chrome.test.succeed(); |
71 } | 52 } |
72 }; | 53 }; |
73 }; | 54 }; |
74 | 55 |
75 chrome.test.runNextTest = function() { | 56 chrome.test.runNextTest = function() { |
76 chrome.test.assertEq(0, pendingCallbacks); | 57 // There may have been callbacks which were interrupted by failure |
| 58 // exceptions. |
| 59 pendingCallbacks = 0; |
| 60 |
77 lastTest = currentTest; | 61 lastTest = currentTest; |
78 currentTest = chrome.test.tests.shift(); | 62 currentTest = chrome.test.tests.shift(); |
| 63 |
79 if (!currentTest) { | 64 if (!currentTest) { |
80 allTestsSucceeded(); | 65 allTestsDone(); |
81 return; | 66 return; |
82 } | 67 } |
| 68 |
83 try { | 69 try { |
84 chrome.test.log("( RUN ) " + testName(currentTest)); | 70 chrome.test.log("( RUN ) " + testName(currentTest)); |
| 71 // If the test doesn't return 'true' for wait, and there are no pending |
| 72 // callbacks, go ahead and declare success. |
85 currentTest.call(); | 73 currentTest.call(); |
86 } catch (e) { | 74 } catch (e) { |
87 var message = e.stack || "(no stack available)"; | 75 if (e !== failureException) |
88 console.log("[FAIL] " + testName(currentTest) + ": " + message); | 76 chrome.test.fail('uncaught exception: ' + e); |
89 chrome.test.notifyFail(message); | |
90 complete(); | |
91 } | 77 } |
92 }; | 78 }; |
93 | 79 |
| 80 chrome.test.fail = function(message) { |
| 81 chrome.test.log("( FAILED ) " + testName(currentTest)); |
| 82 |
| 83 var stack = {}; |
| 84 Error.captureStackTrace(stack, chrome.test.fail); |
| 85 |
| 86 if (!message) |
| 87 message = "FAIL (no message)"; |
| 88 |
| 89 message += "\n" + stack.stack; |
| 90 console.log("[FAIL] " + testName(currentTest) + ": " + message); |
| 91 testsFailed++; |
| 92 testDone(); |
| 93 |
| 94 // Interrupt the rest of the test. |
| 95 throw failureException; |
| 96 }; |
| 97 |
94 chrome.test.succeed = function() { | 98 chrome.test.succeed = function() { |
95 console.log("[SUCCESS] " + testName(currentTest)); | 99 console.log("[SUCCESS] " + testName(currentTest)); |
96 chrome.test.log("( SUCCESS )"); | 100 chrome.test.log("( SUCCESS )"); |
97 // Use setTimeout here to allow previous test contexts to be | 101 testDone(); |
98 // eligible for garbage collection. | |
99 setTimeout(chrome.test.runNextTest, 0); | |
100 }; | 102 }; |
101 | 103 |
102 chrome.test.assertTrue = function(test, message) { | 104 chrome.test.assertTrue = function(test, message) { |
103 chrome.test.assertBool(test, true, message); | 105 chrome.test.assertBool(test, true, message); |
104 }; | 106 }; |
105 | 107 |
106 chrome.test.assertFalse = function(test, message) { | 108 chrome.test.assertFalse = function(test, message) { |
107 chrome.test.assertBool(test, false, message); | 109 chrome.test.assertBool(test, false, message); |
108 }; | 110 }; |
109 | 111 |
110 chrome.test.assertBool = function(test, expected, message) { | 112 chrome.test.assertBool = function(test, expected, message) { |
111 if (test !== expected) { | 113 if (test !== expected) { |
112 if (typeof(test) == "string") { | 114 if (typeof(test) == "string") { |
113 if (message) { | 115 if (message) |
114 message = test + "\n" + message; | 116 message = test + "\n" + message; |
115 } else { | 117 else |
116 message = test; | 118 message = test; |
117 } | |
118 } | 119 } |
119 chrome.test.fail(message); | 120 chrome.test.fail(message); |
120 } | 121 } |
121 }; | 122 }; |
122 | 123 |
123 chrome.test.checkDeepEq = function (expected, actual) { | 124 chrome.test.checkDeepEq = function (expected, actual) { |
124 if ((expected === null) != (actual === null)) | 125 if ((expected === null) != (actual === null)) |
125 return false; | 126 return false; |
126 | 127 |
127 if (expected === actual) | 128 if (expected === actual) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 | 186 |
186 chrome.test.assertNoLastError = function() { | 187 chrome.test.assertNoLastError = function() { |
187 if (chrome.extension.lastError != undefined) { | 188 if (chrome.extension.lastError != undefined) { |
188 chrome.test.fail("lastError.message == " + | 189 chrome.test.fail("lastError.message == " + |
189 chrome.extension.lastError.message); | 190 chrome.extension.lastError.message); |
190 } | 191 } |
191 }; | 192 }; |
192 | 193 |
193 function safeFunctionApply(func, arguments) { | 194 function safeFunctionApply(func, arguments) { |
194 try { | 195 try { |
195 if (func) { | 196 if (func) |
196 func.apply(null, arguments); | 197 func.apply(null, arguments); |
197 } | |
198 } catch (e) { | 198 } catch (e) { |
199 var stack = "(no stack available)"; | 199 var msg = "uncaught exception " + e; |
200 if (typeof(e.stack) != "undefined") { | 200 chrome.test.fail(msg); |
201 stack = e.stack.toString(); | |
202 } | |
203 var msg = "Exception during execution of callback in " + | |
204 testName(currentTest); | |
205 msg += "\n" + stack; | |
206 console.log("[FAIL] " + testName(currentTest) + ": " + msg); | |
207 chrome.test.notifyFail(msg); | |
208 complete(); | |
209 } | 201 } |
210 }; | 202 }; |
211 | 203 |
212 // Wrapper for generating test functions, that takes care of calling | 204 // Wrapper for generating test functions, that takes care of calling |
213 // assertNoLastError() and (optionally) succeed() for you. | 205 // assertNoLastError() and (optionally) succeed() for you. |
214 chrome.test.callback = function(func, expectedError) { | 206 chrome.test.callback = function(func, expectedError) { |
215 if (func) { | 207 if (func) { |
216 chrome.test.assertEq(typeof(func), 'function'); | 208 chrome.test.assertEq(typeof(func), 'function'); |
217 } | 209 } |
218 var callbackCompleted = chrome.test.callbackAdded(); | 210 var callbackCompleted = chrome.test.callbackAdded(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 chrome.test.callbackPass = function(func) { | 256 chrome.test.callbackPass = function(func) { |
265 return chrome.test.callback(func); | 257 return chrome.test.callback(func); |
266 }; | 258 }; |
267 | 259 |
268 chrome.test.callbackFail = function(expectedError, func) { | 260 chrome.test.callbackFail = function(expectedError, func) { |
269 return chrome.test.callback(func, expectedError); | 261 return chrome.test.callback(func, expectedError); |
270 }; | 262 }; |
271 | 263 |
272 chrome.test.runTests = function(tests) { | 264 chrome.test.runTests = function(tests) { |
273 chrome.test.tests = tests; | 265 chrome.test.tests = tests; |
| 266 testCount = chrome.test.tests.length; |
274 chrome.test.runNextTest(); | 267 chrome.test.runNextTest(); |
275 }; | 268 }; |
OLD | NEW |