[Android] Added UMA for search by image context menu.
[chromium-blink-merge.git] / chrome / renderer / resources / extensions / test_custom_bindings.js
blobfe330d37f8f7a5ce1a74334b9baf0d721405a5f6
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
3 // found in the LICENSE file.
5 // test_custom_bindings.js
6 // mini-framework for ExtensionApiTest browser tests
8 var binding = require('binding').Binding.create('test');
10 var chrome = requireNative('chrome').GetChrome();
11 var GetExtensionAPIDefinitionsForTest =
12 requireNative('apiDefinitions').GetExtensionAPIDefinitionsForTest;
13 var GetAvailability = requireNative('v8_context').GetAvailability;
14 var GetAPIFeatures = requireNative('test_features').GetAPIFeatures;
16 binding.registerCustomHook(function(api) {
17 var chromeTest = api.compiledApi;
18 var apiFunctions = api.apiFunctions;
20 chromeTest.tests = chromeTest.tests || [];
22 var currentTest = null;
23 var lastTest = null;
24 var testsFailed = 0;
25 var testCount = 1;
26 var failureException = 'chrome.test.failure';
28 // Helper function to get around the fact that function names in javascript
29 // are read-only, and you can't assign one to anonymous functions.
30 function testName(test) {
31 return test ? (test.name || test.generatedName) : "(no test)";
34 function testDone() {
35 // Use setTimeout here to allow previous test contexts to be
36 // eligible for garbage collection.
37 setTimeout(chromeTest.runNextTest, 0);
40 function allTestsDone() {
41 if (testsFailed == 0) {
42 chromeTest.notifyPass();
43 } else {
44 chromeTest.notifyFail('Failed ' + testsFailed + ' of ' +
45 testCount + ' tests');
48 // Try to get the script to stop running immediately.
49 // This isn't an error, just an attempt at saying "done".
50 throw "completed";
53 var pendingCallbacks = 0;
55 apiFunctions.setHandleRequest('callbackAdded', function() {
56 pendingCallbacks++;
58 var called = null;
59 return function() {
60 if (called != null) {
61 var redundantPrefix = 'Error\n';
62 chrome.test.fail(
63 'Callback has already been run. ' +
64 'First call:\n' +
65 $String.slice(called, redundantPrefix.length) + '\n' +
66 'Second call:\n' +
67 $String.slice(new Error().stack, redundantPrefix.length));
69 called = new Error().stack;
71 pendingCallbacks--;
72 if (pendingCallbacks == 0) {
73 chromeTest.succeed();
76 });
78 apiFunctions.setHandleRequest('runNextTest', function() {
79 // There may have been callbacks which were interrupted by failure
80 // exceptions.
81 pendingCallbacks = 0;
83 lastTest = currentTest;
84 currentTest = chromeTest.tests.shift();
86 if (!currentTest) {
87 allTestsDone();
88 return;
91 try {
92 chromeTest.log("( RUN ) " + testName(currentTest));
93 currentTest.call();
94 } catch (e) {
95 if (e !== failureException)
96 chromeTest.fail('uncaught exception: ' + e);
98 });
100 apiFunctions.setHandleRequest('fail', function(message) {
101 chromeTest.log("( FAILED ) " + testName(currentTest));
103 var stack = {};
104 Error.captureStackTrace(stack, chromeTest.fail);
106 if (!message)
107 message = "FAIL (no message)";
109 message += "\n" + stack.stack;
110 console.log("[FAIL] " + testName(currentTest) + ": " + message);
111 testsFailed++;
112 testDone();
114 // Interrupt the rest of the test.
115 throw failureException;
118 apiFunctions.setHandleRequest('succeed', function() {
119 console.log("[SUCCESS] " + testName(currentTest));
120 chromeTest.log("( SUCCESS )");
121 testDone();
124 apiFunctions.setHandleRequest('assertTrue', function(test, message) {
125 chromeTest.assertBool(test, true, message);
128 apiFunctions.setHandleRequest('assertFalse', function(test, message) {
129 chromeTest.assertBool(test, false, message);
132 apiFunctions.setHandleRequest('assertBool',
133 function(test, expected, message) {
134 if (test !== expected) {
135 if (typeof(test) == "string") {
136 if (message)
137 message = test + "\n" + message;
138 else
139 message = test;
141 chromeTest.fail(message);
145 apiFunctions.setHandleRequest('checkDeepEq', function(expected, actual) {
146 if ((expected === null) != (actual === null))
147 return false;
149 if (expected === actual)
150 return true;
152 if (typeof(expected) !== typeof(actual))
153 return false;
155 for (var p in actual) {
156 if ($Object.hasOwnProperty(actual, p) &&
157 !$Object.hasOwnProperty(expected, p)) {
158 return false;
161 for (var p in expected) {
162 if ($Object.hasOwnProperty(expected, p) &&
163 !$Object.hasOwnProperty(actual, p)) {
164 return false;
168 for (var p in expected) {
169 var eq = true;
170 switch (typeof(expected[p])) {
171 case 'object':
172 eq = chromeTest.checkDeepEq(expected[p], actual[p]);
173 break;
174 case 'function':
175 eq = (typeof(actual[p]) != 'undefined' &&
176 expected[p].toString() == actual[p].toString());
177 break;
178 default:
179 eq = (expected[p] == actual[p] &&
180 typeof(expected[p]) == typeof(actual[p]));
181 break;
183 if (!eq)
184 return false;
186 return true;
189 apiFunctions.setHandleRequest('assertEq',
190 function(expected, actual, message) {
191 var error_msg = "API Test Error in " + testName(currentTest);
192 if (message)
193 error_msg += ": " + message;
194 if (typeof(expected) == 'object') {
195 if (!chromeTest.checkDeepEq(expected, actual)) {
196 // Note: these JSON.stringify calls may fail in tests that explicitly
197 // override JSON.stringfy, so surround in try-catch.
198 try {
199 error_msg += "\nActual: " + JSON.stringify(actual) +
200 "\nExpected: " + JSON.stringify(expected);
201 } catch (e) {}
202 chromeTest.fail(error_msg);
204 return;
206 if (expected != actual) {
207 chromeTest.fail(error_msg +
208 "\nActual: " + actual + "\nExpected: " + expected);
210 if (typeof(expected) != typeof(actual)) {
211 chromeTest.fail(error_msg +
212 " (type mismatch)\nActual Type: " + typeof(actual) +
213 "\nExpected Type:" + typeof(expected));
217 apiFunctions.setHandleRequest('assertNoLastError', function() {
218 if (chrome.runtime.lastError != undefined) {
219 chromeTest.fail("lastError.message == " +
220 chrome.runtime.lastError.message);
224 apiFunctions.setHandleRequest('assertLastError', function(expectedError) {
225 chromeTest.assertEq(typeof(expectedError), 'string');
226 chromeTest.assertTrue(chrome.runtime.lastError != undefined,
227 "No lastError, but expected " + expectedError);
228 chromeTest.assertEq(expectedError, chrome.runtime.lastError.message);
231 apiFunctions.setHandleRequest('assertThrows',
232 function(fn, self, args, message) {
233 assertTrue(typeof fn == 'function');
234 try {
235 fn.apply(self, args);
236 chromeTest.fail('Did not throw error: ' + fn);
237 } catch (e) {
238 if (message !== undefined)
239 chromeTest.assertEq(message, e.message);
243 function safeFunctionApply(func, args) {
244 try {
245 if (func)
246 $Function.apply(func, null, args);
247 } catch (e) {
248 var msg = "uncaught exception " + e;
249 chromeTest.fail(msg);
253 // Wrapper for generating test functions, that takes care of calling
254 // assertNoLastError() and (optionally) succeed() for you.
255 apiFunctions.setHandleRequest('callback', function(func, expectedError) {
256 if (func) {
257 chromeTest.assertEq(typeof(func), 'function');
259 var callbackCompleted = chromeTest.callbackAdded();
261 return function() {
262 if (expectedError == null) {
263 chromeTest.assertNoLastError();
264 } else {
265 chromeTest.assertLastError(expectedError);
268 if (func) {
269 safeFunctionApply(func, arguments);
272 callbackCompleted();
276 apiFunctions.setHandleRequest('listenOnce', function(event, func) {
277 var callbackCompleted = chromeTest.callbackAdded();
278 var listener = function() {
279 event.removeListener(listener);
280 safeFunctionApply(func, arguments);
281 callbackCompleted();
283 event.addListener(listener);
286 apiFunctions.setHandleRequest('listenForever', function(event, func) {
287 var callbackCompleted = chromeTest.callbackAdded();
289 var listener = function() {
290 safeFunctionApply(func, arguments);
293 var done = function() {
294 event.removeListener(listener);
295 callbackCompleted();
298 event.addListener(listener);
299 return done;
302 apiFunctions.setHandleRequest('callbackPass', function(func) {
303 return chromeTest.callback(func);
306 apiFunctions.setHandleRequest('callbackFail', function(expectedError, func) {
307 return chromeTest.callback(func, expectedError);
310 apiFunctions.setHandleRequest('runTests', function(tests) {
311 chromeTest.tests = tests;
312 testCount = chromeTest.tests.length;
313 chromeTest.runNextTest();
316 apiFunctions.setHandleRequest('getApiDefinitions', function() {
317 return GetExtensionAPIDefinitionsForTest();
320 apiFunctions.setHandleRequest('getApiFeatures', function() {
321 return GetAPIFeatures();
325 exports.binding = binding.generate();