Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5442)

Unified Diff: chrome/browser/google_apis/test_util.h

Issue 12785003: Implement generic CreateCopyResultCallback and RunAndQuit. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Update comments. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/google_apis/test_util.h
diff --git a/chrome/browser/google_apis/test_util.h b/chrome/browser/google_apis/test_util.h
index d76f360114ee36f398b5e28d052c56381f5815bc..8127dad9b43950652010acb423a753e0b211afb2 100644
--- a/chrome/browser/google_apis/test_util.h
+++ b/chrome/browser/google_apis/test_util.h
@@ -7,7 +7,10 @@
#include <string>
+#include "base/bind.h"
+#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
+#include "base/template_util.h"
#include "chrome/browser/google_apis/gdata_errorcode.h"
class GURL;
@@ -43,6 +46,9 @@ namespace test_util {
// repeatedly.
void RunBlockingPoolTask();
+// Runs the closure, and then quits the current MessageLoop.
+void RunAndQuit(const base::Closure& closure);
+
// Removes |prefix| from |input| and stores the result in |output|. Returns
// true if the prefix is removed.
bool RemovePrefix(const std::string& input,
@@ -185,6 +191,135 @@ bool ParseContentRangeHeader(const std::string& value,
int64* end_position,
int64* length);
+// Google API related code and Drive File System code work on asynchronous
+// architecture and return the results via callbacks.
+// Following code implements a callback to copy such results.
+// Here is how to use:
+//
+// // Prepare result storage.
+// ResultType1 result1;
+// ResultType2 result2;
+// :
+//
+// PerformAsynchronousTask(
+// param1, param2, ...,
+// CreateCopyResultCallback(&result1, &result2, ...));
+// RunBlockingPoolTask(); // Run message loop to complete the async task.
+//
+// // Hereafter, we can write expectation with results.
+// EXPECT_EQ(expected_result1, result1);
+// EXPECT_EQ(expected_result2, result2);
+// :
+//
+// Note: The max arity of the supported function is 3. The limitation comes
+// from the max arity of base::Callback, which is 7. A created callback
+// consumes two arguments for each input type.
+// TODO(hidehiko): Use replace CopyResultFromXxxCallback method defined above
+// by this one. (crbug.com/180569).
+namespace internal {
+// Following helper templates are to support Chrome's move semantics.
+// Their goal is defining helper methods which are similar to:
+// void CopyResultCallback1(T1* out1, T1&& in1)
+// void CopyResultCallback2(T1* out1, T2* out2, T1&& in1, T2&& in2)
+// :
+// in C++11.
+
+// Declare if the type is movable or not. Currently limited to scoped_ptr only.
+// We can add more types upon the usage.
+template<typename T> struct IsMovable : base::false_type {};
+template<typename T, typename D>
+struct IsMovable<scoped_ptr<T, D> > : base::true_type {};
+
+// InType is const T& if |UseConstRef| is true, otherwise |T|.
+template<bool UseConstRef, typename T> struct InTypeHelper {
+ typedef const T& InType;
+};
+template<typename T> struct InTypeHelper<false, T> {
+ typedef T InType;
+};
+
+// Simulates the std::move operation in C++11. We use pointer here for argument,
+// instead of rvalue reference.
+template<bool IsMovable, typename T> struct MoveHelper {
+ static const T& Move(const T* in) { return *in; }
+};
+template<typename T> struct MoveHelper<true, T> {
+ static T Move(T* in) { return in->Pass(); }
+};
+
+// Helper to handle Chrome's move semantics correctly.
+template<typename T>
+struct CopyResultCallbackHelper
+ // It is necessary to calculate the exact signature of callbacks we want
+ // to create here. In our case, as we use value-parameters for primitive
+ // types and movable types in the callback declaration.
+ // Thus the incoming type is as follows:
+ // 1) If the argument type |T| is class type but doesn't movable,
+ // |InType| is const T&.
+ // 2) Otherwise, |T| as is.
+ : InTypeHelper<
+ base::is_class<T>::value && !IsMovable<T>::value, // UseConstRef
+ T>,
+ MoveHelper<IsMovable<T>::value, T> {
+};
+
+// Copies the |in|'s value to |out|.
+template<typename T1>
+void CopyResultCallback(
+ T1* out,
+ typename CopyResultCallbackHelper<T1>::InType in) {
+ *out = CopyResultCallbackHelper<T1>::Move(&in);
+}
+
+// Copies the |in1|'s value to |out1|, and |in2|'s to |out2|.
+template<typename T1, typename T2>
+void CopyResultCallback(
+ T1* out1,
+ T2* out2,
+ typename CopyResultCallbackHelper<T1>::InType in1,
+ typename CopyResultCallbackHelper<T2>::InType in2) {
+ *out1 = CopyResultCallbackHelper<T1>::Move(&in1);
+ *out2 = CopyResultCallbackHelper<T2>::Move(&in2);
+}
+
+// Copies the |in1|'s value to |out1|, |in2|'s to |out2|, and |in3|'s to |out3|.
+template<typename T1, typename T2, typename T3>
+void CopyResultCallback(
+ T1* out1,
+ T2* out2,
+ T3* out3,
+ typename CopyResultCallbackHelper<T1>::InType in1,
+ typename CopyResultCallbackHelper<T2>::InType in2,
+ typename CopyResultCallbackHelper<T3>::InType in3) {
+ *out1 = CopyResultCallbackHelper<T1>::Move(&in1);
+ *out2 = CopyResultCallbackHelper<T2>::Move(&in2);
+ *out3 = CopyResultCallbackHelper<T3>::Move(&in3);
+}
+
+} // namespace internal
+
+template<typename T1>
+base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType)>
+CreateCopyResultCallback(T1* out1) {
+ return base::Bind(&internal::CopyResultCallback<T1>, out1);
+}
+
+template<typename T1, typename T2>
+base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType,
+ typename internal::CopyResultCallbackHelper<T2>::InType)>
+CreateCopyResultCallback(T1* out1, T2* out2) {
+ return base::Bind(&internal::CopyResultCallback<T1, T2>, out1, out2);
+}
+
+template<typename T1, typename T2, typename T3>
+base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType,
+ typename internal::CopyResultCallbackHelper<T2>::InType,
+ typename internal::CopyResultCallbackHelper<T3>::InType)>
+CreateCopyResultCallback(T1* out1, T2* out2, T3* out3) {
+ return base::Bind(
+ &internal::CopyResultCallback<T1, T2, T3>, out1, out2, out3);
+}
+
} // namespace test_util
} // namespace google_apis
« no previous file with comments | « chrome/browser/google_apis/drive_api_operations_unittest.cc ('k') | chrome/browser/google_apis/test_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698