Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / resources / google_now / common_test_util.js
blobfe5708234b67dfa7bcb38b8036e4f7bcd4ffc496
1 // Copyright 2013 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 // Common test utilities.
7 /**
8  * Allows console.log output.
9  */
10 var showConsoleLogOutput = false;
12 /**
13  * Conditionally allow console.log output based off of showConsoleLogOutput.
14  */
15 console.log = function() {
16   var originalConsoleLog = console.log;
17   return function() {
18     if (showConsoleLogOutput) {
19       originalConsoleLog.apply(console, arguments);
20     }
21   };
22 }();
24 function emptyMock() {}
26 // Container for event handlers added by mocked 'addListener' functions.
27 var mockEventHandlers = {};
29 /**
30  * Mocks 'addListener' function of an API event. The mocked function will keep
31  * track of handlers.
32  * @param {Object} topLevelContainer Top-level container of the original
33  *     function. Can be either 'chrome' or 'instrumented'.
34  * @param {string} eventIdentifier Event identifier, such as
35  *     'runtime.onSuspend'.
36  */
37 function mockChromeEvent(topLevelContainer, eventIdentifier) {
38   var eventIdentifierParts = eventIdentifier.split('.');
39   var eventName = eventIdentifierParts.pop();
40   var originalMethodContainer = topLevelContainer;
41   var mockEventContainer = mockEventHandlers;
42   eventIdentifierParts.forEach(function(fragment) {
43     originalMethodContainer =
44         originalMethodContainer[fragment] =
45         originalMethodContainer[fragment] || {};
46     mockEventContainer =
47         mockEventContainer[fragment] =
48         mockEventContainer[fragment] || {};
49   });
51   mockEventContainer[eventName] = [];
52   originalMethodContainer[eventName] = {
53     addListener: function(callback) {
54       mockEventContainer[eventName].push(callback);
55     }
56   };
59 /**
60  * Gets the array of event handlers added by a mocked 'addListener' function.
61  * @param {string} eventIdentifier Event identifier, such as
62  *     'runtime.onSuspend'.
63  * @return {Array<Function>} Array of handlers.
64  */
65 function getMockHandlerContainer(eventIdentifier) {
66   var eventIdentifierParts = eventIdentifier.split('.');
67   var mockEventContainer = mockEventHandlers;
68   eventIdentifierParts.forEach(function(fragment) {
69     mockEventContainer = mockEventContainer[fragment];
70   });
72   return mockEventContainer;
75 /**
76  * MockPromise
77  * The JS test harness expects all calls to complete synchronously.
78  * As a result, we can't use built-in JS promises since they run asynchronously.
79  * Instead of mocking all possible calls to promises, a skeleton
80  * implementation is provided to get the tests to pass.
81  *
82  * This functionality and logic originates from ECMAScript 6's spec of promises.
83  */
84 var Promise = function() {
85   function PromisePrototypeObject(asyncTask) {
86     function isThenable(value) {
87       return (typeof value === 'object') && isCallable(value.then);
88     }
90     function isCallable(value) {
91       return typeof value === 'function';
92     }
94     function callResolveRejectFunc(func) {
95       var funcResult;
96       var funcResolved = false;
97       func(
98           function(resolveResult) {
99             funcResult = resolveResult;
100             funcResolved = true;
101           },
102           function(rejectResult) {
103             funcResult = rejectResult;
104             funcResolved = false;
105           });
106       return { result: funcResult, resolved: funcResolved };
107     }
109     function then(onResolve, onReject) {
110       var resolutionHandler =
111           isCallable(onResolve) ? onResolve : function() { return result; };
112       var rejectionHandler =
113           isCallable(onReject) ? onReject : function() { return result; };
114       var handlerResult =
115           resolved ? resolutionHandler(result) : rejectionHandler(result);
116       var promiseResolved = resolved;
117       if (isThenable(handlerResult)) {
118         var resolveReject = callResolveRejectFunc(handlerResult.then);
119         handlerResult = resolveReject.result;
120         promiseResolved = resolveReject.resolved;
121       }
123       if (promiseResolved) {
124         return Promise.resolve(handlerResult);
125       } else {
126         return Promise.reject(handlerResult);
127       }
128     }
130     // Promises use the function name "catch" to call back error handlers.
131     // We can't use "catch" since function or variable names cannot use the word
132     // "catch".
133     function catchFunc(onRejected) {
134       return this.then(undefined, onRejected);
135     }
137     var resolveReject = callResolveRejectFunc(asyncTask);
138     var result = resolveReject.result;
139     var resolved = resolveReject.resolved;
141     if (isThenable(result)) {
142       var thenResolveReject = callResolveRejectFunc(result.then);
143       result = thenResolveReject.result;
144       resolved = thenResolveReject.resolved;
145     }
147     return {then: then, catch: catchFunc, isPromise: true};
148   }
150   function all(arrayOfPromises) {
151     var results = [];
152     for (i = 0; i < arrayOfPromises.length; i++) {
153       if (arrayOfPromises[i].isPromise) {
154         arrayOfPromises[i].then(function(result) {
155           results[i] = result;
156         });
157       } else {
158         results[i] = arrayOfPromises[i];
159       }
160     }
161     var promise = new PromisePrototypeObject(function(resolve) {
162       resolve(results);
163     });
164     return promise;
165   }
167   function resolve(value) {
168     var promise = new PromisePrototypeObject(function(resolve) {
169       resolve(value);
170     });
171     return promise;
172   }
174   function reject(value) {
175     var promise = new PromisePrototypeObject(function(resolve, reject) {
176       reject(value);
177     });
178     return promise;
179   }
181   PromisePrototypeObject.all = all;
182   PromisePrototypeObject.resolve = resolve;
183   PromisePrototypeObject.reject = reject;
184   return PromisePrototypeObject;
185 }();
188  * Sets up the test to expect a Chrome Local Storage call.
189  * @param {Object} fixture Mock JS Test Object.
190  * @param {Object} defaultObject Storage request default object.
191  * @param {Object} result Storage result.
192  * @param {boolean=} opt_AllowRejection Allow Promise Rejection
193  */
194 function expectChromeLocalStorageGet(
195     fixture, defaultObject, result, opt_AllowRejection) {
196   if (opt_AllowRejection === undefined) {
197     fixture.mockApis.expects(once()).
198       fillFromChromeLocalStorage(eqJSON(defaultObject)).
199       will(returnValue(Promise.resolve(result)));
200   } else {
201     fixture.mockApis.expects(once()).
202       fillFromChromeLocalStorage(eqJSON(defaultObject), opt_AllowRejection).
203       will(returnValue(Promise.resolve(result)));
204   }