test_util.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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
  3. // found in the LICENSE file.
  4. #ifndef GOOGLE_APIS_COMMON_TEST_UTIL_H_
  5. #define GOOGLE_APIS_COMMON_TEST_UTIL_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <memory>
  9. #include <string>
  10. #include <utility>
  11. #include <vector>
  12. #include "base/bind.h"
  13. #include "base/callback.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "google_apis/common/api_error_codes.h"
  16. #include "google_apis/common/base_requests.h"
  17. #include "google_apis/common/task_util.h"
  18. class GURL;
  19. namespace base {
  20. class FilePath;
  21. class RunLoop;
  22. class Value;
  23. } // namespace base
  24. namespace net {
  25. namespace test_server {
  26. class BasicHttpResponse;
  27. class HttpResponse;
  28. struct HttpRequest;
  29. } // namespace test_server
  30. } // namespace net
  31. namespace google_apis {
  32. namespace test_util {
  33. // Runs the closure, and then quits the |run_loop|.
  34. void RunAndQuit(base::RunLoop* run_loop, base::OnceClosure closure);
  35. // Returns callback which runs the given |callback| and then quits |run_loop|.
  36. template <typename CallbackType>
  37. CallbackType CreateQuitCallback(base::RunLoop* run_loop,
  38. CallbackType callback) {
  39. return CreateComposedCallback(base::BindOnce(&RunAndQuit, run_loop),
  40. std::move(callback));
  41. }
  42. // Removes |prefix| from |input| and stores the result in |output|. Returns
  43. // true if the prefix is removed.
  44. bool RemovePrefix(const std::string& input,
  45. const std::string& prefix,
  46. std::string* output);
  47. // Returns the absolute path for a test file stored under
  48. // chrome/test/data.
  49. base::FilePath GetTestFilePath(const std::string& relative_path);
  50. // Returns the base URL for communicating with the local test server for
  51. // testing, running at the specified port number.
  52. GURL GetBaseUrlForTesting(int port);
  53. // Writes the |content| to the file at |file_path|. Returns true on success,
  54. // otherwise false.
  55. bool WriteStringToFile(const base::FilePath& file_path,
  56. const std::string& content);
  57. // Creates a |size| byte file. The file is filled with random bytes so that
  58. // the test assertions can identify correct portion/position of the file is
  59. // used.
  60. // Returns true on success with the created file's |path| and |data|, otherwise
  61. // false.
  62. bool CreateFileOfSpecifiedSize(const base::FilePath& temp_dir,
  63. size_t size,
  64. base::FilePath* path,
  65. std::string* data);
  66. // Loads a test JSON file as a base::Value, from a test file stored under
  67. // chrome/test/data.
  68. std::unique_ptr<base::Value> LoadJSONFile(const std::string& relative_path);
  69. // Returns a HttpResponse created from the given file path.
  70. std::unique_ptr<net::test_server::BasicHttpResponse> CreateHttpResponseFromFile(
  71. const base::FilePath& file_path);
  72. // Handles a request for downloading a file. Reads a file from the test
  73. // directory and returns the content. Also, copies the |request| to the memory
  74. // pointed by |out_request|.
  75. // |base_url| must be set to the server's base url.
  76. std::unique_ptr<net::test_server::HttpResponse> HandleDownloadFileRequest(
  77. const GURL& base_url,
  78. net::test_server::HttpRequest* out_request,
  79. const net::test_server::HttpRequest& request);
  80. // Parses a value of Content-Range header, which looks like
  81. // "bytes <start_position>-<end_position>/<length>".
  82. // Returns true on success.
  83. bool ParseContentRangeHeader(const std::string& value,
  84. int64_t* start_position,
  85. int64_t* end_position,
  86. int64_t* length);
  87. // Google API related code work on asynchronous architecture and return the
  88. // results via callbacks. Following code implements a callback to copy such
  89. // results. Here is how to use:
  90. //
  91. // // Prepare result storage.
  92. // ResultType1 result1;
  93. // ResultType2 result2;
  94. // :
  95. //
  96. // PerformAsynchronousTask(
  97. // param1, param2, ...,
  98. // CreateCopyResultCallback(&result1, &result2, ...));
  99. // base::RunLoop().RunUntilIdle(); // Run message loop to complete
  100. // // the async task.
  101. //
  102. // // Hereafter, we can write expectation with results.
  103. // EXPECT_EQ(expected_result1, result1);
  104. // EXPECT_EQ(expected_result2, result2);
  105. // :
  106. //
  107. // Note: The max arity of the supported function is 4 based on the usage.
  108. namespace internal {
  109. // Following helper templates are to support Chrome's move semantics.
  110. // Their goal is defining helper methods which are similar to:
  111. // void CopyResultCallback1(T1* out1, T1&& in1)
  112. // void CopyResultCallback2(T1* out1, T2* out2, T1&& in1, T2&& in2)
  113. // :
  114. // in C++11.
  115. // Declare if the type is movable or not. Currently limited to scoped_ptr only.
  116. // We can add more types upon the usage.
  117. template <typename T>
  118. struct IsMovable : std::false_type {};
  119. template <typename T, typename D>
  120. struct IsMovable<std::unique_ptr<T, D>> : std::true_type {};
  121. // InType is const T& if |UseConstRef| is true, otherwise |T|.
  122. template <bool UseConstRef, typename T>
  123. struct InTypeHelper {
  124. typedef const T& InType;
  125. };
  126. template <typename T>
  127. struct InTypeHelper<false, T> {
  128. typedef T InType;
  129. };
  130. // Simulates the std::move function in C++11. We use pointer here for argument,
  131. // instead of rvalue reference.
  132. template <bool IsMovable, typename T>
  133. struct MoveHelper {
  134. static const T& Move(const T* in) { return *in; }
  135. };
  136. template <typename T>
  137. struct MoveHelper<true, T> {
  138. static T Move(T* in) { return std::move(*in); }
  139. };
  140. // Helper to handle Chrome's move semantics correctly.
  141. template <typename T>
  142. struct CopyResultCallbackHelper
  143. // It is necessary to calculate the exact signature of callbacks we want
  144. // to create here. In our case, as we use value-parameters for primitive
  145. // types and movable types in the callback declaration.
  146. // Thus the incoming type is as follows:
  147. // 1) If the argument type |T| is class type but doesn't movable,
  148. // |InType| is const T&.
  149. // 2) Otherwise, |T| as is.
  150. : InTypeHelper<std::is_class<T>::value &&
  151. !IsMovable<T>::value, // UseConstRef
  152. T>,
  153. MoveHelper<IsMovable<T>::value, T> {};
  154. // Copies the |in|'s value to |out|.
  155. template <typename T1>
  156. void CopyResultCallback(T1* out,
  157. typename CopyResultCallbackHelper<T1>::InType in) {
  158. *out = CopyResultCallbackHelper<T1>::Move(&in);
  159. }
  160. // Copies the |in1|'s value to |out1|, and |in2|'s to |out2|.
  161. template <typename T1, typename T2>
  162. void CopyResultCallback(T1* out1,
  163. T2* out2,
  164. typename CopyResultCallbackHelper<T1>::InType in1,
  165. typename CopyResultCallbackHelper<T2>::InType in2) {
  166. *out1 = CopyResultCallbackHelper<T1>::Move(&in1);
  167. *out2 = CopyResultCallbackHelper<T2>::Move(&in2);
  168. }
  169. // Copies the |in1|'s value to |out1|, |in2|'s to |out2|, and |in3|'s to |out3|.
  170. template <typename T1, typename T2, typename T3>
  171. void CopyResultCallback(T1* out1,
  172. T2* out2,
  173. T3* out3,
  174. typename CopyResultCallbackHelper<T1>::InType in1,
  175. typename CopyResultCallbackHelper<T2>::InType in2,
  176. typename CopyResultCallbackHelper<T3>::InType in3) {
  177. *out1 = CopyResultCallbackHelper<T1>::Move(&in1);
  178. *out2 = CopyResultCallbackHelper<T2>::Move(&in2);
  179. *out3 = CopyResultCallbackHelper<T3>::Move(&in3);
  180. }
  181. // Holds the pointers for output. This is introduced for the workaround of
  182. // the arity limitation of Callback.
  183. template <typename T1, typename T2, typename T3, typename T4>
  184. struct OutputParams {
  185. OutputParams(T1* out1, T2* out2, T3* out3, T4* out4)
  186. : out1(out1), out2(out2), out3(out3), out4(out4) {}
  187. raw_ptr<T1> out1;
  188. raw_ptr<T2> out2;
  189. raw_ptr<T3> out3;
  190. raw_ptr<T4> out4;
  191. };
  192. // Copies the |in1|'s value to |output->out1|, |in2|'s to |output->out2|,
  193. // and so on.
  194. template <typename T1, typename T2, typename T3, typename T4>
  195. void CopyResultCallback(const OutputParams<T1, T2, T3, T4>& output,
  196. typename CopyResultCallbackHelper<T1>::InType in1,
  197. typename CopyResultCallbackHelper<T2>::InType in2,
  198. typename CopyResultCallbackHelper<T3>::InType in3,
  199. typename CopyResultCallbackHelper<T4>::InType in4) {
  200. *output.out1 = CopyResultCallbackHelper<T1>::Move(&in1);
  201. *output.out2 = CopyResultCallbackHelper<T2>::Move(&in2);
  202. *output.out3 = CopyResultCallbackHelper<T3>::Move(&in3);
  203. *output.out4 = CopyResultCallbackHelper<T4>::Move(&in4);
  204. }
  205. } // namespace internal
  206. template <typename T1>
  207. base::OnceCallback<
  208. void(typename internal::CopyResultCallbackHelper<T1>::InType)>
  209. CreateCopyResultCallback(T1* out1) {
  210. return base::BindOnce(&internal::CopyResultCallback<T1>, out1);
  211. }
  212. template <typename T1, typename T2>
  213. base::OnceCallback<
  214. void(typename internal::CopyResultCallbackHelper<T1>::InType,
  215. typename internal::CopyResultCallbackHelper<T2>::InType)>
  216. CreateCopyResultCallback(T1* out1, T2* out2) {
  217. return base::BindOnce(&internal::CopyResultCallback<T1, T2>, out1, out2);
  218. }
  219. template <typename T1, typename T2, typename T3>
  220. base::OnceCallback<
  221. void(typename internal::CopyResultCallbackHelper<T1>::InType,
  222. typename internal::CopyResultCallbackHelper<T2>::InType,
  223. typename internal::CopyResultCallbackHelper<T3>::InType)>
  224. CreateCopyResultCallback(T1* out1, T2* out2, T3* out3) {
  225. return base::BindOnce(&internal::CopyResultCallback<T1, T2, T3>, out1, out2,
  226. out3);
  227. }
  228. template <typename T1, typename T2, typename T3, typename T4>
  229. base::OnceCallback<
  230. void(typename internal::CopyResultCallbackHelper<T1>::InType,
  231. typename internal::CopyResultCallbackHelper<T2>::InType,
  232. typename internal::CopyResultCallbackHelper<T3>::InType,
  233. typename internal::CopyResultCallbackHelper<T4>::InType)>
  234. CreateCopyResultCallback(T1* out1, T2* out2, T3* out3, T4* out4) {
  235. return base::BindOnce(
  236. &internal::CopyResultCallback<T1, T2, T3, T4>,
  237. internal::OutputParams<T1, T2, T3, T4>(out1, out2, out3, out4));
  238. }
  239. typedef std::pair<int64_t, int64_t> ProgressInfo;
  240. // Helper utility for recording the results via ProgressCallback.
  241. void AppendProgressCallbackResult(std::vector<ProgressInfo>* progress_values,
  242. int64_t progress,
  243. int64_t total);
  244. // Helper utility for recording the content via GetContentCallback.
  245. class TestGetContentCallback {
  246. public:
  247. TestGetContentCallback();
  248. TestGetContentCallback(const TestGetContentCallback&) = delete;
  249. TestGetContentCallback& operator=(const TestGetContentCallback&) = delete;
  250. ~TestGetContentCallback();
  251. const GetContentCallback& callback() const { return callback_; }
  252. const std::vector<std::unique_ptr<std::string>>& data() const {
  253. return data_;
  254. }
  255. std::vector<std::unique_ptr<std::string>>* mutable_data() { return &data_; }
  256. std::string GetConcatenatedData() const;
  257. private:
  258. void OnGetContent(google_apis::ApiErrorCode error,
  259. std::unique_ptr<std::string> data,
  260. bool first_chunk);
  261. const GetContentCallback callback_;
  262. std::vector<std::unique_ptr<std::string>> data_;
  263. };
  264. } // namespace test_util
  265. } // namespace google_apis
  266. #endif // GOOGLE_APIS_COMMON_TEST_UTIL_H_