diff options
Diffstat (limited to 'chromium/google_apis/drive/test_util.h')
-rw-r--r-- | chromium/google_apis/drive/test_util.h | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/chromium/google_apis/drive/test_util.h b/chromium/google_apis/drive/test_util.h new file mode 100644 index 00000000000..2cd85b62dd3 --- /dev/null +++ b/chromium/google_apis/drive/test_util.h @@ -0,0 +1,299 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GOOGLE_APIS_DRIVE_TEST_UTIL_H_ +#define GOOGLE_APIS_DRIVE_TEST_UTIL_H_ + +#include <string> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "base/template_util.h" +#include "google_apis/drive/base_requests.h" +#include "google_apis/drive/gdata_errorcode.h" +#include "google_apis/drive/task_util.h" + +class GURL; + +namespace base { +class FilePath; +class RunLoop; +class Value; +} + +namespace net { +namespace test_server { +class BasicHttpResponse; +class HttpResponse; +struct HttpRequest; +} +} + +namespace google_apis { +namespace test_util { + +// Runs the closure, and then quits the |run_loop|. +void RunAndQuit(base::RunLoop* run_loop, const base::Closure& closure); + +// Returns callback which runs the given |callback| and then quits |run_loop|. +template<typename CallbackType> +CallbackType CreateQuitCallback(base::RunLoop* run_loop, + const CallbackType& callback) { + return CreateComposedCallback(base::Bind(&RunAndQuit, run_loop), callback); +} + +// Removes |prefix| from |input| and stores the result in |output|. Returns +// true if the prefix is removed. +bool RemovePrefix(const std::string& input, + const std::string& prefix, + std::string* output); + +// Returns the absolute path for a test file stored under +// chrome/test/data. +base::FilePath GetTestFilePath(const std::string& relative_path); + +// Returns the base URL for communicating with the local test server for +// testing, running at the specified port number. +GURL GetBaseUrlForTesting(int port); + +// Writes the |content| to the file at |file_path|. Returns true on success, +// otherwise false. +bool WriteStringToFile(const base::FilePath& file_path, + const std::string& content); + +// Creates a |size| byte file. The file is filled with random bytes so that +// the test assertions can identify correct portion/position of the file is +// used. +// Returns true on success with the created file's |path| and |data|, otherwise +// false. +bool CreateFileOfSpecifiedSize(const base::FilePath& temp_dir, + size_t size, + base::FilePath* path, + std::string* data); + +// Loads a test JSON file as a base::Value, from a test file stored under +// chrome/test/data. +scoped_ptr<base::Value> LoadJSONFile(const std::string& relative_path); + +// Returns a HttpResponse created from the given file path. +scoped_ptr<net::test_server::BasicHttpResponse> CreateHttpResponseFromFile( + const base::FilePath& file_path); + +// Handles a request for downloading a file. Reads a file from the test +// directory and returns the content. Also, copies the |request| to the memory +// pointed by |out_request|. +// |base_url| must be set to the server's base url. +scoped_ptr<net::test_server::HttpResponse> HandleDownloadFileRequest( + const GURL& base_url, + net::test_server::HttpRequest* out_request, + const net::test_server::HttpRequest& request); + +// Parses a value of Content-Range header, which looks like +// "bytes <start_position>-<end_position>/<length>". +// Returns true on success. +bool ParseContentRangeHeader(const std::string& value, + int64* start_position, + 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, ...)); +// base::RunLoop().RunUntilIdle(); // 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 4 based on the usage. +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 function 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); +} + +// Holds the pointers for output. This is introduced for the workaround of +// the arity limitation of Callback. +template<typename T1, typename T2, typename T3, typename T4> +struct OutputParams { + OutputParams(T1* out1, T2* out2, T3* out3, T4* out4) + : out1(out1), out2(out2), out3(out3), out4(out4) {} + T1* out1; + T2* out2; + T3* out3; + T4* out4; +}; + +// Copies the |in1|'s value to |output->out1|, |in2|'s to |output->out2|, +// and so on. +template<typename T1, typename T2, typename T3, typename T4> +void CopyResultCallback( + const OutputParams<T1, T2, T3, T4>& output, + typename CopyResultCallbackHelper<T1>::InType in1, + typename CopyResultCallbackHelper<T2>::InType in2, + typename CopyResultCallbackHelper<T3>::InType in3, + typename CopyResultCallbackHelper<T4>::InType in4) { + *output.out1 = CopyResultCallbackHelper<T1>::Move(&in1); + *output.out2 = CopyResultCallbackHelper<T2>::Move(&in2); + *output.out3 = CopyResultCallbackHelper<T3>::Move(&in3); + *output.out4 = CopyResultCallbackHelper<T4>::Move(&in4); +} + +} // 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); +} + +template<typename T1, typename T2, typename T3, typename T4> +base::Callback<void(typename internal::CopyResultCallbackHelper<T1>::InType, + typename internal::CopyResultCallbackHelper<T2>::InType, + typename internal::CopyResultCallbackHelper<T3>::InType, + typename internal::CopyResultCallbackHelper<T4>::InType)> +CreateCopyResultCallback(T1* out1, T2* out2, T3* out3, T4* out4) { + return base::Bind( + &internal::CopyResultCallback<T1, T2, T3, T4>, + internal::OutputParams<T1, T2, T3, T4>(out1, out2, out3, out4)); +} + +typedef std::pair<int64, int64> ProgressInfo; + +// Helper utility for recording the results via ProgressCallback. +void AppendProgressCallbackResult(std::vector<ProgressInfo>* progress_values, + int64 progress, + int64 total); + +// Helper utility for recording the content via GetContentCallback. +class TestGetContentCallback { + public: + TestGetContentCallback(); + ~TestGetContentCallback(); + + const GetContentCallback& callback() const { return callback_; } + const ScopedVector<std::string>& data() const { return data_; } + ScopedVector<std::string>* mutable_data() { return &data_; } + std::string GetConcatenatedData() const; + + private: + void OnGetContent(google_apis::GDataErrorCode error, + scoped_ptr<std::string> data); + + const GetContentCallback callback_; + ScopedVector<std::string> data_; + + DISALLOW_COPY_AND_ASSIGN(TestGetContentCallback); +}; + +} // namespace test_util +} // namespace google_apis + +#endif // GOOGLE_APIS_DRIVE_TEST_UTIL_H_ |