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 |