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 #ifndef CHROME_BROWSER_GOOGLE_APIS_TEST_UTIL_H_ | 5 #ifndef CHROME_BROWSER_GOOGLE_APIS_TEST_UTIL_H_ |
6 #define CHROME_BROWSER_GOOGLE_APIS_TEST_UTIL_H_ | 6 #define CHROME_BROWSER_GOOGLE_APIS_TEST_UTIL_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | |
11 #include "base/callback.h" | |
10 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/template_util.h" | |
11 #include "chrome/browser/google_apis/gdata_errorcode.h" | 14 #include "chrome/browser/google_apis/gdata_errorcode.h" |
12 | 15 |
13 class GURL; | 16 class GURL; |
14 | 17 |
15 namespace base { | 18 namespace base { |
16 class FilePath; | 19 class FilePath; |
17 class Value; | 20 class Value; |
18 } | 21 } |
19 | 22 |
20 namespace google_apis { | 23 namespace google_apis { |
(...skipping 15 matching lines...) Expand all Loading... | |
36 | 39 |
37 // Runs a task posted to the blocking pool, including subsequent tasks posted | 40 // Runs a task posted to the blocking pool, including subsequent tasks posted |
38 // to the UI message loop and the blocking pool. | 41 // to the UI message loop and the blocking pool. |
39 // | 42 // |
40 // A task is often posted to the blocking pool with PostTaskAndReply(). In | 43 // A task is often posted to the blocking pool with PostTaskAndReply(). In |
41 // that case, a task is posted back to the UI message loop, which can again | 44 // that case, a task is posted back to the UI message loop, which can again |
42 // post a task to the blocking pool. This function processes these tasks | 45 // post a task to the blocking pool. This function processes these tasks |
43 // repeatedly. | 46 // repeatedly. |
44 void RunBlockingPoolTask(); | 47 void RunBlockingPoolTask(); |
45 | 48 |
49 // Runs the closure, and then quits the current MessageLoop. | |
50 void RunAndQuit(const base::Closure& closure); | |
51 | |
46 // Removes |prefix| from |input| and stores the result in |output|. Returns | 52 // Removes |prefix| from |input| and stores the result in |output|. Returns |
47 // true if the prefix is removed. | 53 // true if the prefix is removed. |
48 bool RemovePrefix(const std::string& input, | 54 bool RemovePrefix(const std::string& input, |
49 const std::string& prefix, | 55 const std::string& prefix, |
50 std::string* output); | 56 std::string* output); |
51 | 57 |
52 // Returns the absolute path for a test file stored under | 58 // Returns the absolute path for a test file stored under |
53 // chrome/test/data. | 59 // chrome/test/data. |
54 base::FilePath GetTestFilePath(const std::string& relative_path); | 60 base::FilePath GetTestFilePath(const std::string& relative_path); |
55 | 61 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 const base::Value* json_data); | 184 const base::Value* json_data); |
179 | 185 |
180 // Parses a value of Content-Range header, which looks like | 186 // Parses a value of Content-Range header, which looks like |
181 // "bytes <start_position>-<end_position>/<length>". | 187 // "bytes <start_position>-<end_position>/<length>". |
182 // Returns true on success. | 188 // Returns true on success. |
183 bool ParseContentRangeHeader(const std::string& value, | 189 bool ParseContentRangeHeader(const std::string& value, |
184 int64* start_position, | 190 int64* start_position, |
185 int64* end_position, | 191 int64* end_position, |
186 int64* length); | 192 int64* length); |
187 | 193 |
194 // Google API related code and Drive File System code works on asynchronous | |
195 // architecture, so we defined lots of callback to receive results of | |
hashimoto
2013/03/13 03:34:00
"so we defined lots of callback" and the "callback
hidehiko
2013/03/13 05:42:10
Refined. How about this?
| |
196 // such asynchronous operations. | |
197 // Following code implements a callback to copy such results from asynchronous | |
198 // operation. Here is its usage: | |
199 // | |
200 // class Operation; // Testee Operation class. | |
hashimoto
2013/03/13 03:34:00
This comment seems a bit verbose.
Can't we simplif
hidehiko
2013/03/13 05:42:10
Done.
| |
201 // | |
202 // // Prepare result storage. | |
203 // ResultType1 result1; | |
204 // ResultType2 result2; | |
205 // | |
206 // // Create an operation. | |
207 // Operation operation( | |
208 // ...(some arguments)..., | |
209 // CreateCopyResultCallback(&result1, &result2)); | |
210 // operation.StartOperation(); // And start to run it. | |
211 // ... // Run message loop to complete the asynchronous task. | |
212 // | |
213 // // Hereafter, we can write expectation with result1 and result2. | |
214 // EXPECT_EQ(expected_result1, result1); | |
215 // EXPECT_EQ(expected_result2, result2); | |
216 // | |
217 // Note: The max arity of the supported function is 3. The limitation comes | |
218 // from the max arity of base::Callback, which is 7. A created callback | |
219 // consumes two arguments for each input type. | |
220 // TODO(hidehiko): Use replace CopyResultFromXxxCallback method defined above | |
221 // by this one. (crbug.com/180569). | |
222 namespace internal { | |
223 // Following helper templates are to support Chrome's move semantics. | |
224 // Their goal is defining helper methods which are similar to: | |
225 // void CopyResultCallback1(T1* out1, T1&& in1) | |
226 // void CopyResultCallback2(T1* out1, T2* out2, T1&& in1, T2&& in2) | |
227 // : | |
228 // in C++11. | |
229 | |
230 // Declare if the type is movable or not. Currently limited to scoped_ptr only. | |
231 // We can add more types upon the usage. | |
232 template<typename T> struct IsMovable : base::false_type {}; | |
233 template<typename T, typename D> | |
234 struct IsMovable<scoped_ptr<T, D> > : base::true_type {}; | |
235 | |
236 // The incoming type is as follows: | |
237 // 1) If argument type |T| is non-class type or supporting Chrome's Move | |
kinaba
2013/03/13 06:34:06
In offline chat I was convinced why it cannot be c
hidehiko
2013/03/13 08:49:19
Done.
| |
238 // concept, |InType| is |T| as is. | |
239 // 2) Otherwise, const T&. | |
240 template<bool IsNonMovableClass, typename T> struct InTypeHelper { | |
hashimoto
2013/03/13 03:34:00
All other parts are dealing with IsMovable, only t
hidehiko
2013/03/13 05:42:10
Done.
| |
241 typedef T InType; | |
242 }; | |
243 template<typename T> struct InTypeHelper<true, T> { | |
244 typedef const T& InType; | |
245 }; | |
246 | |
247 // Simulate the move operation. To avoid value copy in argument, the method | |
hashimoto
2013/03/13 03:34:00
s/Simulate/Simulates/?
"To avoid value copy" does
hidehiko
2013/03/13 05:42:10
OK. Refined the comment, but please let me keep me
| |
248 // takes pointer. | |
249 template<bool IsMovable, typename T> struct MoveHelper { | |
250 static const T& Move(const T* in) { return *in; } | |
251 }; | |
252 template<typename T> struct MoveHelper<true, T> { | |
253 static T Move(T* in) { return in->Pass(); } | |
254 }; | |
255 | |
256 // Helper to handle Chrome's move semantics correctly. | |
257 template<typename T> struct CopyResultCallbackHelper { | |
258 // The input type. See also comments of InTypeHelper. | |
259 typedef typename InTypeHelper< | |
260 base::is_class<T>::value && !IsMovable<T>::value, T>::InType InType; | |
kinaba
2013/03/13 04:07:44
I don't feel it worth caring whether is_class<T> o
kinaba
2013/03/13 04:18:13
Or even,
template<typename T>
struct CopyResultCa
hidehiko
2013/03/13 05:42:10
There are three kinds of types here.
- non-class t
| |
261 | |
262 // The implementation of move like operation. | |
263 typedef MoveHelper<IsMovable<T>::value, T> MoveHelperType; | |
264 }; | |
265 | |
266 // Copies the |in|'s value to |out|. | |
267 template<typename T1> | |
268 void CopyResultCallback1( | |
hashimoto
2013/03/13 03:34:00
Naming functions in Name1, Name2, ... looks worse
hidehiko
2013/03/13 05:42:10
Hmm, I thought we need to static_cast to resolve f
| |
269 T1* out, | |
270 typename CopyResultCallbackHelper<T1>::InType in) { | |
271 *out = CopyResultCallbackHelper<T1>::MoveHelperType::Move(&in); | |
hashimoto
2013/03/13 03:34:00
How about adding a static method Move to CopyResul
hidehiko
2013/03/13 05:42:10
Inherited by MoveHelper.
| |
272 } | |
273 | |
274 // Copies the |in1|'s value to |out1|, and |in2|'s to |out2|. | |
275 template<typename T1, typename T2> | |
276 void CopyResultCallback2( | |
277 T1* out1, | |
278 T2* out2, | |
279 typename CopyResultCallbackHelper<T1>::InType in1, | |
280 typename CopyResultCallbackHelper<T2>::InType in2) { | |
281 *out1 = CopyResultCallbackHelper<T1>::MoveHelperType::Move(&in1); | |
282 *out2 = CopyResultCallbackHelper<T2>::MoveHelperType::Move(&in2); | |
283 } | |
284 | |
285 // Copies the |in1|'s value to |out1|, |in2|'s to |out2|, and |in3|'s to |out3|. | |
286 template<typename T1, typename T2, typename T3> | |
287 void CopyResultCallback3( | |
288 T1* out1, | |
289 T2* out2, | |
290 T3* out3, | |
291 typename CopyResultCallbackHelper<T1>::InType in1, | |
292 typename CopyResultCallbackHelper<T2>::InType in2, | |
293 typename CopyResultCallbackHelper<T3>::InType in3) { | |
294 *out1 = CopyResultCallbackHelper<T1>::MoveHelperType::Move(&in1); | |
295 *out2 = CopyResultCallbackHelper<T2>::MoveHelperType::Move(&in2); | |
296 *out3 = CopyResultCallbackHelper<T3>::MoveHelperType::Move(&in3); | |
297 } | |
298 | |
299 } // namespace internal | |
300 | |
301 template<typename T1> | |
302 base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType)> | |
303 CreateCopyResultCallback(T1* out1) { | |
304 return base::Bind(&internal::CopyResultCallback1<T1>, out1); | |
305 } | |
306 | |
307 template<typename T1, typename T2> | |
308 base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType, | |
309 typename internal::CopyResultCallbackHelper<T2>::InType)> | |
310 CreateCopyResultCallback(T1* out1, T2* out2) { | |
311 return base::Bind(&internal::CopyResultCallback2<T1, T2>, out1, out2); | |
312 } | |
313 | |
314 template<typename T1, typename T2, typename T3> | |
315 base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType, | |
316 typename internal::CopyResultCallbackHelper<T2>::InType, | |
317 typename internal::CopyResultCallbackHelper<T3>::InType)> | |
318 CreateCopyResultCallback(T1* out1, T2* out2, T3* out3) { | |
319 return base::Bind( | |
320 &internal::CopyResultCallback3<T1, T2, T3>, out1, out2, out3); | |
321 } | |
322 | |
188 } // namespace test_util | 323 } // namespace test_util |
189 } // namespace google_apis | 324 } // namespace google_apis |
190 | 325 |
191 #endif // CHROME_BROWSER_GOOGLE_APIS_TEST_UTIL_H_ | 326 #endif // CHROME_BROWSER_GOOGLE_APIS_TEST_UTIL_H_ |
OLD | NEW |