summaryrefslogtreecommitdiff
path: root/mojo/common/common_custom_types_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/common/common_custom_types_unittest.cc')
-rw-r--r--mojo/common/common_custom_types_unittest.cc433
1 files changed, 433 insertions, 0 deletions
diff --git a/mojo/common/common_custom_types_unittest.cc b/mojo/common/common_custom_types_unittest.cc
new file mode 100644
index 0000000000..e3571d9d86
--- /dev/null
+++ b/mojo/common/common_custom_types_unittest.cc
@@ -0,0 +1,433 @@
+// Copyright 2016 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.
+
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/numerics/safe_math.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "mojo/common/test_common_custom_types.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace common {
+namespace test {
+namespace {
+
+template <typename T>
+struct BounceTestTraits {
+ static void ExpectEquality(const T& a, const T& b) {
+ EXPECT_EQ(a, b);
+ }
+};
+
+template <typename T>
+struct PassTraits {
+ using Type = const T&;
+};
+
+template <>
+struct PassTraits<base::Time> {
+ using Type = base::Time;
+};
+
+template <>
+struct PassTraits<base::TimeDelta> {
+ using Type = base::TimeDelta;
+};
+
+template <>
+struct PassTraits<base::TimeTicks> {
+ using Type = base::TimeTicks;
+};
+
+template <typename T>
+void DoExpectResponse(T* expected_value,
+ const base::Closure& closure,
+ typename PassTraits<T>::Type value) {
+ BounceTestTraits<T>::ExpectEquality(*expected_value, value);
+ closure.Run();
+}
+
+template <typename T>
+base::Callback<void(typename PassTraits<T>::Type)> ExpectResponse(
+ T* expected_value,
+ const base::Closure& closure) {
+ return base::Bind(&DoExpectResponse<T>, expected_value, closure);
+}
+
+class TestFilePathImpl : public TestFilePath {
+ public:
+ explicit TestFilePathImpl(TestFilePathRequest request)
+ : binding_(this, std::move(request)) {}
+
+ // TestFilePath implementation:
+ void BounceFilePath(const base::FilePath& in,
+ const BounceFilePathCallback& callback) override {
+ callback.Run(in);
+ }
+
+ private:
+ mojo::Binding<TestFilePath> binding_;
+};
+
+class TestUnguessableTokenImpl : public TestUnguessableToken {
+ public:
+ explicit TestUnguessableTokenImpl(TestUnguessableTokenRequest request)
+ : binding_(this, std::move(request)) {}
+
+ // TestUnguessableToken implementation:
+ void BounceNonce(const base::UnguessableToken& in,
+ const BounceNonceCallback& callback) override {
+ callback.Run(in);
+ }
+
+ private:
+ mojo::Binding<TestUnguessableToken> binding_;
+};
+
+class TestTimeImpl : public TestTime {
+ public:
+ explicit TestTimeImpl(TestTimeRequest request)
+ : binding_(this, std::move(request)) {}
+
+ // TestTime implementation:
+ void BounceTime(base::Time in, const BounceTimeCallback& callback) override {
+ callback.Run(in);
+ }
+
+ void BounceTimeDelta(base::TimeDelta in,
+ const BounceTimeDeltaCallback& callback) override {
+ callback.Run(in);
+ }
+
+ void BounceTimeTicks(base::TimeTicks in,
+ const BounceTimeTicksCallback& callback) override {
+ callback.Run(in);
+ }
+
+ private:
+ mojo::Binding<TestTime> binding_;
+};
+
+class TestValueImpl : public TestValue {
+ public:
+ explicit TestValueImpl(TestValueRequest request)
+ : binding_(this, std::move(request)) {}
+
+ // TestValue implementation:
+ void BounceDictionaryValue(
+ std::unique_ptr<base::DictionaryValue> in,
+ const BounceDictionaryValueCallback& callback) override {
+ callback.Run(std::move(in));
+ }
+
+ void BounceListValue(std::unique_ptr<base::ListValue> in,
+ const BounceListValueCallback& callback) override {
+ callback.Run(std::move(in));
+ }
+
+ void BounceValue(std::unique_ptr<base::Value> in,
+ const BounceValueCallback& callback) override {
+ callback.Run(std::move(in));
+ }
+
+ private:
+ mojo::Binding<TestValue> binding_;
+};
+
+class TestString16Impl : public TestString16 {
+ public:
+ explicit TestString16Impl(TestString16Request request)
+ : binding_(this, std::move(request)) {}
+
+ // TestString16 implementation:
+ void BounceString16(const base::string16& in,
+ const BounceString16Callback& callback) override {
+ callback.Run(in);
+ }
+
+ private:
+ mojo::Binding<TestString16> binding_;
+};
+
+class TestFileImpl : public TestFile {
+ public:
+ explicit TestFileImpl(TestFileRequest request)
+ : binding_(this, std::move(request)) {}
+
+ // TestFile implementation:
+ void BounceFile(base::File in, const BounceFileCallback& callback) override {
+ callback.Run(std::move(in));
+ }
+
+ private:
+ mojo::Binding<TestFile> binding_;
+};
+
+class TestTextDirectionImpl : public TestTextDirection {
+ public:
+ explicit TestTextDirectionImpl(TestTextDirectionRequest request)
+ : binding_(this, std::move(request)) {}
+
+ // TestTextDirection:
+ void BounceTextDirection(
+ base::i18n::TextDirection in,
+ const BounceTextDirectionCallback& callback) override {
+ callback.Run(in);
+ }
+
+ private:
+ mojo::Binding<TestTextDirection> binding_;
+};
+
+class CommonCustomTypesTest : public testing::Test {
+ protected:
+ CommonCustomTypesTest() {}
+ ~CommonCustomTypesTest() override {}
+
+ private:
+ base::MessageLoop message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(CommonCustomTypesTest);
+};
+
+} // namespace
+
+TEST_F(CommonCustomTypesTest, FilePath) {
+ base::RunLoop run_loop;
+
+ TestFilePathPtr ptr;
+ TestFilePathImpl impl(MakeRequest(&ptr));
+
+ base::FilePath dir(FILE_PATH_LITERAL("hello"));
+ base::FilePath file = dir.Append(FILE_PATH_LITERAL("world"));
+
+ ptr->BounceFilePath(file, ExpectResponse(&file, run_loop.QuitClosure()));
+
+ run_loop.Run();
+}
+
+TEST_F(CommonCustomTypesTest, UnguessableToken) {
+ base::RunLoop run_loop;
+
+ TestUnguessableTokenPtr ptr;
+ TestUnguessableTokenImpl impl(MakeRequest(&ptr));
+
+ base::UnguessableToken token = base::UnguessableToken::Create();
+
+ ptr->BounceNonce(token, ExpectResponse(&token, run_loop.QuitClosure()));
+
+ run_loop.Run();
+}
+
+TEST_F(CommonCustomTypesTest, Time) {
+ base::RunLoop run_loop;
+
+ TestTimePtr ptr;
+ TestTimeImpl impl(MakeRequest(&ptr));
+
+ base::Time t = base::Time::Now();
+
+ ptr->BounceTime(t, ExpectResponse(&t, run_loop.QuitClosure()));
+
+ run_loop.Run();
+}
+
+TEST_F(CommonCustomTypesTest, TimeDelta) {
+ base::RunLoop run_loop;
+
+ TestTimePtr ptr;
+ TestTimeImpl impl(MakeRequest(&ptr));
+
+ base::TimeDelta t = base::TimeDelta::FromDays(123);
+
+ ptr->BounceTimeDelta(t, ExpectResponse(&t, run_loop.QuitClosure()));
+
+ run_loop.Run();
+}
+
+TEST_F(CommonCustomTypesTest, TimeTicks) {
+ base::RunLoop run_loop;
+
+ TestTimePtr ptr;
+ TestTimeImpl impl(MakeRequest(&ptr));
+
+ base::TimeTicks t = base::TimeTicks::Now();
+
+ ptr->BounceTimeTicks(t, ExpectResponse(&t, run_loop.QuitClosure()));
+
+ run_loop.Run();
+}
+
+TEST_F(CommonCustomTypesTest, Value) {
+ TestValuePtr ptr;
+ TestValueImpl impl(MakeRequest(&ptr));
+
+ std::unique_ptr<base::Value> output;
+
+ ASSERT_TRUE(ptr->BounceValue(nullptr, &output));
+ EXPECT_FALSE(output);
+
+ std::unique_ptr<base::Value> input = base::Value::CreateNullValue();
+ ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
+ EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
+
+ input = base::MakeUnique<base::Value>(123);
+ ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
+ EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
+
+ input = base::MakeUnique<base::Value>(1.23);
+ ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
+ EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
+
+ input = base::MakeUnique<base::Value>(false);
+ ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
+ EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
+
+ input = base::MakeUnique<base::Value>("test string");
+ ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
+ EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
+
+ input = base::BinaryValue::CreateWithCopiedBuffer("mojo", 4);
+ ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
+ EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
+
+ auto dict = base::MakeUnique<base::DictionaryValue>();
+ dict->SetBoolean("bool", false);
+ dict->SetInteger("int", 2);
+ dict->SetString("string", "some string");
+ dict->SetBoolean("nested.bool", true);
+ dict->SetInteger("nested.int", 9);
+ dict->Set("some_binary",
+ base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
+ dict->Set("null_value", base::Value::CreateNullValue());
+ dict->SetIntegerWithoutPathExpansion("non_nested.int", 10);
+ {
+ std::unique_ptr<base::ListValue> dict_list(new base::ListValue());
+ dict_list->AppendString("string");
+ dict_list->AppendBoolean(true);
+ dict->Set("list", std::move(dict_list));
+ }
+
+ std::unique_ptr<base::DictionaryValue> dict_output;
+ ASSERT_TRUE(ptr->BounceDictionaryValue(dict->CreateDeepCopy(), &dict_output));
+ EXPECT_TRUE(base::Value::Equals(dict.get(), dict_output.get()));
+
+ input = std::move(dict);
+ ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
+ EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
+
+ auto list = base::MakeUnique<base::ListValue>();
+ list->AppendString("string");
+ list->AppendDouble(42.1);
+ list->AppendBoolean(true);
+ list->Append(base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
+ list->Append(base::Value::CreateNullValue());
+ {
+ std::unique_ptr<base::DictionaryValue> list_dict(
+ new base::DictionaryValue());
+ list_dict->SetString("string", "str");
+ list->Append(std::move(list_dict));
+ }
+ std::unique_ptr<base::ListValue> list_output;
+ ASSERT_TRUE(ptr->BounceListValue(list->CreateDeepCopy(), &list_output));
+ EXPECT_TRUE(base::Value::Equals(list.get(), list_output.get()));
+
+ input = std::move(list);
+ ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
+ ASSERT_TRUE(base::Value::Equals(input.get(), output.get()));
+}
+
+TEST_F(CommonCustomTypesTest, String16) {
+ base::RunLoop run_loop;
+
+ TestString16Ptr ptr;
+ TestString16Impl impl(MakeRequest(&ptr));
+
+ base::string16 str16 = base::ASCIIToUTF16("hello world");
+
+ ptr->BounceString16(str16, ExpectResponse(&str16, run_loop.QuitClosure()));
+
+ run_loop.Run();
+}
+
+TEST_F(CommonCustomTypesTest, EmptyString16) {
+ base::RunLoop run_loop;
+
+ TestString16Ptr ptr;
+ TestString16Impl impl(MakeRequest(&ptr));
+
+ base::string16 str16;
+
+ ptr->BounceString16(str16, ExpectResponse(&str16, run_loop.QuitClosure()));
+
+ run_loop.Run();
+}
+
+TEST_F(CommonCustomTypesTest, File) {
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+
+ TestFilePtr ptr;
+ TestFileImpl impl(MakeRequest(&ptr));
+
+ base::File file(
+ temp_dir.GetPath().AppendASCII("test_file.txt"),
+ base::File::FLAG_CREATE | base::File::FLAG_WRITE | base::File::FLAG_READ);
+ const base::StringPiece test_content =
+ "A test string to be stored in a test file";
+ file.WriteAtCurrentPos(
+ test_content.data(),
+ base::CheckedNumeric<int>(test_content.size()).ValueOrDie());
+
+ base::File file_out;
+ ASSERT_TRUE(ptr->BounceFile(std::move(file), &file_out));
+ std::vector<char> content(test_content.size());
+ ASSERT_TRUE(file_out.IsValid());
+ ASSERT_EQ(static_cast<int>(test_content.size()),
+ file_out.Read(
+ 0, content.data(),
+ base::CheckedNumeric<int>(test_content.size()).ValueOrDie()));
+ EXPECT_EQ(test_content,
+ base::StringPiece(content.data(), test_content.size()));
+}
+
+TEST_F(CommonCustomTypesTest, InvalidFile) {
+ TestFilePtr ptr;
+ TestFileImpl impl(MakeRequest(&ptr));
+
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ // Test that |file_out| is set to an invalid file.
+ base::File file_out(
+ temp_dir.GetPath().AppendASCII("test_file.txt"),
+ base::File::FLAG_CREATE | base::File::FLAG_WRITE | base::File::FLAG_READ);
+
+ ASSERT_TRUE(ptr->BounceFile(base::File(), &file_out));
+ EXPECT_FALSE(file_out.IsValid());
+}
+
+TEST_F(CommonCustomTypesTest, TextDirection) {
+ base::i18n::TextDirection kTestDirections[] = {base::i18n::LEFT_TO_RIGHT,
+ base::i18n::RIGHT_TO_LEFT,
+ base::i18n::UNKNOWN_DIRECTION};
+
+ TestTextDirectionPtr ptr;
+ TestTextDirectionImpl impl(MakeRequest(&ptr));
+
+ for (size_t i = 0; i < arraysize(kTestDirections); i++) {
+ base::i18n::TextDirection direction_out;
+ ASSERT_TRUE(ptr->BounceTextDirection(kTestDirections[i], &direction_out));
+ EXPECT_EQ(kTestDirections[i], direction_out);
+ }
+}
+
+} // namespace test
+} // namespace common
+} // namespace mojo