Chromium Code Reviews| 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 work on asynchronous | |
| 195 // architecture and return the results via callbacks. | |
| 196 // Following code implements a callback to copy such results. | |
| 197 // Here is how to use: | |
| 198 // | |
| 199 // // Prepare result storage. | |
| 200 // ResultType1 result1; | |
| 201 // ResultType2 result2; | |
| 202 // : | |
| 203 // | |
| 204 // PerformAsynchronousTask( | |
| 205 // param1, param2, ..., | |
| 206 // CreateCopyResultCallback(&result1, &result2, ...)); | |
| 207 // RunBlockingPoolTask(); // Run message loop to complete the async task. | |
| 208 // | |
| 209 // // Hereafter, we can write expectation with results. | |
| 210 // EXPECT_EQ(expected_result1, result1); | |
| 211 // EXPECT_EQ(expected_result2, result2); | |
| 212 // : | |
| 213 // | |
| 214 // Note: The max arity of the supported function is 3. The limitation comes | |
| 215 // from the max arity of base::Callback, which is 7. A created callback | |
| 216 // consumes two arguments for each input type. | |
| 217 // TODO(hidehiko): Use replace CopyResultFromXxxCallback method defined above | |
| 218 // by this one. (crbug.com/180569). | |
| 219 namespace internal { | |
| 220 // Following helper templates are to support Chrome's move semantics. | |
| 221 // Their goal is defining helper methods which are similar to: | |
| 222 // void CopyResultCallback1(T1* out1, T1&& in1) | |
| 223 // void CopyResultCallback2(T1* out1, T2* out2, T1&& in1, T2&& in2) | |
| 224 // : | |
| 225 // in C++11. | |
| 226 | |
| 227 // Declare if the type is movable or not. Currently limited to scoped_ptr only. | |
| 228 // We can add more types upon the usage. | |
| 229 template<typename T> struct IsMovable : base::false_type {}; | |
| 230 template<typename T, typename D> | |
| 231 struct IsMovable<scoped_ptr<T, D> > : base::true_type {}; | |
| 232 | |
| 233 // InType is const T& if |UseConstRef| is true, otherwise |T|. | |
| 234 template<bool UseConstRef, typename T> struct InTypeHelper { | |
| 235 typedef const T& InType; | |
| 236 }; | |
| 237 template<typename T> struct InTypeHelper<false, T> { | |
| 238 typedef T InType; | |
| 239 }; | |
| 240 | |
| 241 // Simulates the std::move operation in C++11. We use pointer here for argument, | |
| 242 // instead of rvalue reference. | |
| 243 template<bool IsMovable, typename T> struct MoveHelper { | |
| 244 static const T& Move(const T* in) { return *in; } | |
| 245 }; | |
| 246 template<typename T> struct MoveHelper<true, T> { | |
| 247 static T Move(T* in) { return in->Pass(); } | |
| 248 }; | |
| 249 | |
| 250 // Helper to handle Chrome's move semantics correctly. | |
| 251 template<typename T> | |
| 252 struct CopyResultCallbackHelper | |
| 253 // The incoming type is as follows: | |
| 254 // 1) If argument type |T| is non-class type or supporting Chrome's Move | |
| 255 // concept, |InType| is |T| as is. | |
| 256 // 2) Otherwise, const T&. | |
| 257 : InTypeHelper<base::is_class<T>::value && !IsMovable<T>::value, T>, | |
|
hashimoto
2013/03/13 06:27:52
nit: Please add a comment about that this boolean
hidehiko
2013/03/13 08:49:19
Done. Also, swapped the condition in the comment t
| |
| 258 MoveHelper<IsMovable<T>::value, T> { | |
| 259 }; | |
| 260 | |
| 261 // Copies the |in|'s value to |out|. | |
| 262 template<typename T1> | |
| 263 void CopyResultCallback( | |
| 264 T1* out, | |
| 265 typename CopyResultCallbackHelper<T1>::InType in) { | |
| 266 *out = CopyResultCallbackHelper<T1>::Move(&in); | |
| 267 } | |
| 268 | |
| 269 // Copies the |in1|'s value to |out1|, and |in2|'s to |out2|. | |
| 270 template<typename T1, typename T2> | |
| 271 void CopyResultCallback( | |
| 272 T1* out1, | |
| 273 T2* out2, | |
| 274 typename CopyResultCallbackHelper<T1>::InType in1, | |
| 275 typename CopyResultCallbackHelper<T2>::InType in2) { | |
| 276 *out1 = CopyResultCallbackHelper<T1>::Move(&in1); | |
| 277 *out2 = CopyResultCallbackHelper<T2>::Move(&in2); | |
| 278 } | |
| 279 | |
| 280 // Copies the |in1|'s value to |out1|, |in2|'s to |out2|, and |in3|'s to |out3|. | |
| 281 template<typename T1, typename T2, typename T3> | |
| 282 void CopyResultCallback( | |
| 283 T1* out1, | |
| 284 T2* out2, | |
| 285 T3* out3, | |
| 286 typename CopyResultCallbackHelper<T1>::InType in1, | |
| 287 typename CopyResultCallbackHelper<T2>::InType in2, | |
| 288 typename CopyResultCallbackHelper<T3>::InType in3) { | |
| 289 *out1 = CopyResultCallbackHelper<T1>::Move(&in1); | |
| 290 *out2 = CopyResultCallbackHelper<T2>::Move(&in2); | |
| 291 *out3 = CopyResultCallbackHelper<T3>::Move(&in3); | |
| 292 } | |
| 293 | |
| 294 } // namespace internal | |
| 295 | |
| 296 template<typename T1> | |
| 297 base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType)> | |
| 298 CreateCopyResultCallback(T1* out1) { | |
| 299 return base::Bind(&internal::CopyResultCallback<T1>, out1); | |
| 300 } | |
| 301 | |
| 302 template<typename T1, typename T2> | |
| 303 base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType, | |
| 304 typename internal::CopyResultCallbackHelper<T2>::InType)> | |
| 305 CreateCopyResultCallback(T1* out1, T2* out2) { | |
| 306 return base::Bind(&internal::CopyResultCallback<T1, T2>, out1, out2); | |
| 307 } | |
| 308 | |
| 309 template<typename T1, typename T2, typename T3> | |
| 310 base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType, | |
| 311 typename internal::CopyResultCallbackHelper<T2>::InType, | |
| 312 typename internal::CopyResultCallbackHelper<T3>::InType)> | |
| 313 CreateCopyResultCallback(T1* out1, T2* out2, T3* out3) { | |
| 314 return base::Bind( | |
| 315 &internal::CopyResultCallback<T1, T2, T3>, out1, out2, out3); | |
| 316 } | |
| 317 | |
| 188 } // namespace test_util | 318 } // namespace test_util |
| 189 } // namespace google_apis | 319 } // namespace google_apis |
| 190 | 320 |
| 191 #endif // CHROME_BROWSER_GOOGLE_APIS_TEST_UTIL_H_ | 321 #endif // CHROME_BROWSER_GOOGLE_APIS_TEST_UTIL_H_ |
| OLD | NEW |