diff options
Diffstat (limited to 'mojo/common/common_custom_types_unittest.cc')
-rw-r--r-- | mojo/common/common_custom_types_unittest.cc | 433 |
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 |