blob: ba9af3598c691cfc03ca1d6f36193ffae2a4b969 [file] [log] [blame]
// 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/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/numerics/safe_math.h"
#include "base/run_loop.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 TestValueImpl : public TestValue {
public:
explicit TestValueImpl(TestValueRequest request)
: binding_(this, std::move(request)) {}
// TestValue implementation:
void BounceDictionaryValue(std::unique_ptr<base::DictionaryValue> in,
BounceDictionaryValueCallback callback) override {
std::move(callback).Run(std::move(in));
}
void BounceListValue(std::unique_ptr<base::ListValue> in,
BounceListValueCallback callback) override {
std::move(callback).Run(std::move(in));
}
void BounceValue(std::unique_ptr<base::Value> in,
BounceValueCallback callback) override {
std::move(callback).Run(std::move(in));
}
private:
mojo::Binding<TestValue> binding_;
};
class CommonCustomTypesTest : public testing::Test {
protected:
CommonCustomTypesTest() {}
~CommonCustomTypesTest() override {}
private:
base::MessageLoop message_loop_;
DISALLOW_COPY_AND_ASSIGN(CommonCustomTypesTest);
};
} // namespace
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);
auto input = std::make_unique<base::Value>();
ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
EXPECT_EQ(*input, *output);
input = std::make_unique<base::Value>(123);
ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
EXPECT_EQ(*input, *output);
input = std::make_unique<base::Value>(1.23);
ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
EXPECT_EQ(*input, *output);
input = std::make_unique<base::Value>(false);
ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
EXPECT_EQ(*input, *output);
input = std::make_unique<base::Value>("test string");
ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
EXPECT_EQ(*input, *output);
input = base::Value::CreateWithCopiedBuffer("mojo", 4);
ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
EXPECT_EQ(*input, *output);
auto dict = std::make_unique<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::Value::CreateWithCopiedBuffer("mojo", 4));
dict->Set("null_value", std::make_unique<base::Value>());
dict->SetKey("non_nested.int", base::Value(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_EQ(*dict, *dict_output);
input = std::move(dict);
ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
EXPECT_EQ(*input, *output);
auto list = std::make_unique<base::ListValue>();
list->AppendString("string");
list->AppendDouble(42.1);
list->AppendBoolean(true);
list->Append(base::Value::CreateWithCopiedBuffer("mojo", 4));
list->Append(std::make_unique<base::Value>());
{
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_EQ(*list, *list_output);
input = std::move(list);
ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
ASSERT_EQ(*input, *output);
}
} // namespace test
} // namespace common
} // namespace mojo