Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 // Common test utilities. | 5 // Common test utilities. |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Allows console.log output. | 8 * Allows console.log output. |
| 9 */ | 9 */ |
| 10 var showConsoleLogOutput = false; | 10 var showConsoleLogOutput = false; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 | 74 |
| 75 /** | 75 /** |
| 76 * MockPromise | 76 * MockPromise |
| 77 * The JS test harness expects all calls to complete synchronously. | 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. | 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 | 79 * Instead of mocking all possible calls to promises, a skeleton |
| 80 * implementation is provided to get the tests to pass. | 80 * implementation is provided to get the tests to pass. |
| 81 */ | 81 */ |
| 82 var Promise = function() { | 82 var Promise = function() { |
| 83 function PromisePrototypeObject(asyncTask) { | 83 function PromisePrototypeObject(asyncTask) { |
| 84 var result; | 84 function isThenable(value) { |
| 85 var resolved = false; | 85 return (typeof value === 'object') && isCallable(value.then); |
| 86 asyncTask( | 86 } |
| 87 function(asyncResult) { | |
| 88 result = asyncResult; | |
| 89 resolved = true; | |
| 90 }, | |
| 91 function(asyncFailureResult) { | |
| 92 result = asyncFailureResult; | |
| 93 resolved = false; | |
| 94 }); | |
| 95 | 87 |
| 96 function then(callback) { | 88 function isCallable(value) { |
| 97 if (resolved) { | 89 return typeof value === 'function'; |
| 98 callback.call(null, result); | 90 } |
| 91 | |
| 92 function callResolveRejectFunc(func) { | |
| 93 var funcResult; | |
| 94 var funcResolved = false; | |
| 95 func( | |
| 96 function(resolveResult) { | |
| 97 funcResult = resolveResult; | |
| 98 funcResolved = true; | |
| 99 }, | |
| 100 function(rejectResult) { | |
| 101 funcResult = rejectResult; | |
| 102 funcResolved = false; | |
| 103 }); | |
| 104 return { result: funcResult, resolved: funcResolved }; | |
| 105 } | |
| 106 | |
| 107 function then(onResolve, onReject) { | |
| 108 var resolutionHandler = | |
| 109 isCallable(onResolve) ? onResolve : function() { return result; }; | |
| 110 var rejectionHandler = | |
| 111 isCallable(onReject) ? onReject : function() { return result; }; | |
| 112 var handlerResult = | |
| 113 resolved ? resolutionHandler(result) : rejectionHandler(result); | |
| 114 var promiseResolved = resolved; | |
| 115 if (isThenable(handlerResult)) { | |
| 116 var resolveReject = callResolveRejectFunc(handlerResult.then); | |
| 117 handlerResult = resolveReject.result; | |
| 118 promiseResolved = resolveReject.resolved; | |
| 99 } | 119 } |
| 100 return this; | 120 |
| 121 if (promiseResolved) { | |
| 122 return Promise.resolve(handlerResult); | |
| 123 } else { | |
| 124 return Promise.reject(handlerResult); | |
| 125 } | |
| 101 } | 126 } |
| 102 | 127 |
| 103 // Promises use the function name "catch" to call back error handlers. | 128 // Promises use the function name "catch" to call back error handlers. |
| 104 // We can't use "catch" since function or variable names cannot use the word | 129 // We can't use "catch" since function or variable names cannot use the word |
| 105 // "catch". | 130 // "catch". |
| 106 function catchFunc(callback) { | 131 function catchFunc(onRejected) { |
| 107 if (!resolved) { | 132 return this.then(undefined, onRejected); |
| 108 callback.call(null, result); | 133 } |
| 109 } | 134 |
| 110 return this; | 135 var resolveReject = callResolveRejectFunc(asyncTask); |
| 136 var result = resolveReject.result; | |
| 137 var resolved = resolveReject.resolved; | |
| 138 | |
| 139 if (isThenable(result)) { | |
|
rgustafson
2014/03/19 00:24:31
I don't quite understand why this is here (and abo
robliao
2014/03/19 00:43:39
This code is indeed crazy. This implementation is
rgustafson
2014/03/19 23:02:25
I'll take your word on this since that's just taki
robliao
2014/03/19 23:34:39
Links will change, so I've added a comment about t
| |
| 140 var thenResolveReject = callResolveRejectFunc(result.then); | |
| 141 result = thenResolveReject.result; | |
| 142 resolved = thenResolveReject.resolved; | |
| 111 } | 143 } |
| 112 | 144 |
| 113 return {then: then, catch: catchFunc, isPromise: true}; | 145 return {then: then, catch: catchFunc, isPromise: true}; |
| 114 } | 146 } |
| 115 | 147 |
| 116 function all(arrayOfPromises) { | 148 function all(arrayOfPromises) { |
| 117 var results = []; | 149 var results = []; |
| 118 for (i = 0; i < arrayOfPromises.length; i++) { | 150 for (i = 0; i < arrayOfPromises.length; i++) { |
| 119 if (arrayOfPromises[i].isPromise) { | 151 if (arrayOfPromises[i].isPromise) { |
| 120 arrayOfPromises[i].then(function(result) { | 152 arrayOfPromises[i].then(function(result) { |
| 121 results[i] = result; | 153 results[i] = result; |
| 122 }); | 154 }); |
| 123 } else { | 155 } else { |
| 124 results[i] = arrayOfPromises[i]; | 156 results[i] = arrayOfPromises[i]; |
| 125 } | 157 } |
| 126 } | 158 } |
| 127 var promise = new PromisePrototypeObject(function(resolve) { | 159 var promise = new PromisePrototypeObject(function(resolve) { |
| 128 resolve(results); | 160 resolve(results); |
| 129 }); | 161 }); |
| 130 return promise; | 162 return promise; |
| 131 } | 163 } |
| 132 | 164 |
| 133 function resolve(value) { | 165 function resolve(value) { |
| 134 var promise = new PromisePrototypeObject(function(resolve) { | 166 var promise = new PromisePrototypeObject(function(resolve) { |
| 135 resolve(value); | 167 resolve(value); |
| 136 }); | 168 }); |
| 137 return promise; | 169 return promise; |
| 138 } | 170 } |
| 139 | 171 |
| 172 function reject(value) { | |
| 173 var promise = new PromisePrototypeObject(function(resolve, reject) { | |
| 174 reject(value); | |
| 175 }); | |
| 176 return promise; | |
| 177 } | |
| 178 | |
| 140 PromisePrototypeObject.all = all; | 179 PromisePrototypeObject.all = all; |
| 141 PromisePrototypeObject.resolve = resolve; | 180 PromisePrototypeObject.resolve = resolve; |
|
skare_
2014/03/19 23:20:23
this is in the scope of a prior cl, so maybe I/we
robliao
2014/03/19 23:34:39
What do you mean?
Are you asking for direct decla
skare_
2014/03/20 00:27:27
moving all the callable functions/'api' to one pla
robliao
2014/03/20 00:31:55
Ah. That wouldn't work. We actually need a constru
robliao
2014/03/20 00:32:49
s/do not exist/exist/
On 2014/03/20 00:31:55, robl
| |
| 181 PromisePrototypeObject.reject = reject; | |
| 142 return PromisePrototypeObject; | 182 return PromisePrototypeObject; |
| 143 }(); | 183 }(); |
| 144 | 184 |
| 145 | |
| 146 /** | 185 /** |
| 147 * Sets up the test to expect a Chrome Local Storage call. | 186 * Sets up the test to expect a Chrome Local Storage call. |
| 148 * @param {Object} fixture Mock JS Test Object. | 187 * @param {Object} fixture Mock JS Test Object. |
| 149 * @param {Object} defaultObject Storage request default object. | 188 * @param {Object} defaultObject Storage request default object. |
| 150 * @param {Object} result Storage result. | 189 * @param {Object} result Storage result. |
| 151 * @param {boolean=} opt_AllowRejection Allow Promise Rejection | 190 * @param {boolean=} opt_AllowRejection Allow Promise Rejection |
| 152 */ | 191 */ |
| 153 function expectChromeLocalStorageGet( | 192 function expectChromeLocalStorageGet( |
| 154 fixture, defaultObject, result, opt_AllowRejection) { | 193 fixture, defaultObject, result, opt_AllowRejection) { |
| 155 if (opt_AllowRejection === undefined) { | 194 if (opt_AllowRejection === undefined) { |
| 156 fixture.mockApis.expects(once()). | 195 fixture.mockApis.expects(once()). |
| 157 fillFromChromeLocalStorage(eqJSON(defaultObject)). | 196 fillFromChromeLocalStorage(eqJSON(defaultObject)). |
| 158 will(returnValue(Promise.resolve(result))); | 197 will(returnValue(Promise.resolve(result))); |
| 159 } else { | 198 } else { |
| 160 fixture.mockApis.expects(once()). | 199 fixture.mockApis.expects(once()). |
| 161 fillFromChromeLocalStorage(eqJSON(defaultObject), opt_AllowRejection). | 200 fillFromChromeLocalStorage(eqJSON(defaultObject), opt_AllowRejection). |
| 162 will(returnValue(Promise.resolve(result))); | 201 will(returnValue(Promise.resolve(result))); |
| 163 } | 202 } |
| 164 } | 203 } |
| OLD | NEW |