blob: 2de12d793ad45e7de75bbee835af1d3405c57099 [file] [log] [blame]
// 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.
#include "dbus/values_util.h"
#include <vector>
#include "base/float_util.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "dbus/message.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace dbus {
TEST(ValuesUtilTest, PopBasicTypes) {
scoped_ptr<Response> response(Response::CreateEmpty());
// Append basic type values.
MessageWriter writer(response.get());
const uint8 kByteValue = 42;
writer.AppendByte(kByteValue);
const bool kBoolValue = true;
writer.AppendBool(kBoolValue);
const int16 kInt16Value = -43;
writer.AppendInt16(kInt16Value);
const uint16 kUint16Value = 44;
writer.AppendUint16(kUint16Value);
const int32 kInt32Value = -45;
writer.AppendInt32(kInt32Value);
const uint32 kUint32Value = 46;
writer.AppendUint32(kUint32Value);
const int64 kInt64Value = -47;
writer.AppendInt64(kInt64Value);
const uint64 kUint64Value = 48;
writer.AppendUint64(kUint64Value);
const double kDoubleValue = 4.9;
writer.AppendDouble(kDoubleValue);
const std::string kStringValue = "fifty";
writer.AppendString(kStringValue);
const std::string kEmptyStringValue;
writer.AppendString(kEmptyStringValue);
const ObjectPath kObjectPathValue("/ObjectPath");
writer.AppendObjectPath(kObjectPathValue);
MessageReader reader(response.get());
scoped_ptr<base::Value> value;
scoped_ptr<base::Value> expected_value;
// Pop a byte.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kByteValue));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop a bool.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kBoolValue));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop an int16.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kInt16Value));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop a uint16.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kUint16Value));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop an int32.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kInt32Value));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop a uint32.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(
new base::FundamentalValue(static_cast<double>(kUint32Value)));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop an int64.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(
new base::FundamentalValue(static_cast<double>(kInt64Value)));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop a uint64.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(
new base::FundamentalValue(static_cast<double>(kUint64Value)));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop a double.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kDoubleValue));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop a string.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::StringValue(kStringValue));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop an empty string.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::StringValue(kEmptyStringValue));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop an object path.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::StringValue(kObjectPathValue.value()));
EXPECT_TRUE(value->Equals(expected_value.get()));
}
TEST(ValuesUtilTest, PopVariant) {
scoped_ptr<Response> response(Response::CreateEmpty());
// Append variant values.
MessageWriter writer(response.get());
const bool kBoolValue = true;
writer.AppendVariantOfBool(kBoolValue);
const int32 kInt32Value = -45;
writer.AppendVariantOfInt32(kInt32Value);
const double kDoubleValue = 4.9;
writer.AppendVariantOfDouble(kDoubleValue);
const std::string kStringValue = "fifty";
writer.AppendVariantOfString(kStringValue);
MessageReader reader(response.get());
scoped_ptr<base::Value> value;
scoped_ptr<base::Value> expected_value;
// Pop a bool.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kBoolValue));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop an int32.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kInt32Value));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop a double.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::FundamentalValue(kDoubleValue));
EXPECT_TRUE(value->Equals(expected_value.get()));
// Pop a string.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(new base::StringValue(kStringValue));
EXPECT_TRUE(value->Equals(expected_value.get()));
}
// Pop extremely large integers which cannot be precisely represented in
// double.
TEST(ValuesUtilTest, PopExtremelyLargeIntegers) {
scoped_ptr<Response> response(Response::CreateEmpty());
// Append large integers.
MessageWriter writer(response.get());
const int64 kInt64Value = -123456789012345689LL;
writer.AppendInt64(kInt64Value);
const uint64 kUint64Value = 9876543210987654321ULL;
writer.AppendUint64(kUint64Value);
MessageReader reader(response.get());
scoped_ptr<base::Value> value;
scoped_ptr<base::Value> expected_value;
double double_value = 0;
// Pop an int64.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(
new base::FundamentalValue(static_cast<double>(kInt64Value)));
EXPECT_TRUE(value->Equals(expected_value.get()));
ASSERT_TRUE(value->GetAsDouble(&double_value));
EXPECT_NE(kInt64Value, static_cast<int64>(double_value));
// Pop a uint64.
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
expected_value.reset(
new base::FundamentalValue(static_cast<double>(kUint64Value)));
EXPECT_TRUE(value->Equals(expected_value.get()));
ASSERT_TRUE(value->GetAsDouble(&double_value));
EXPECT_NE(kUint64Value, static_cast<uint64>(double_value));
}
TEST(ValuesUtilTest, PopIntArray) {
scoped_ptr<Response> response(Response::CreateEmpty());
// Append an int32 array.
MessageWriter writer(response.get());
MessageWriter sub_writer(NULL);
std::vector<int32> data;
data.push_back(0);
data.push_back(1);
data.push_back(2);
writer.OpenArray("i", &sub_writer);
for (size_t i = 0; i != data.size(); ++i)
sub_writer.AppendInt32(data[i]);
writer.CloseContainer(&sub_writer);
// Create the expected value.
scoped_ptr<base::ListValue> list_value(new base::ListValue);
for (size_t i = 0; i != data.size(); ++i)
list_value->Append(new base::FundamentalValue(data[i]));
// Pop an int32 array.
MessageReader reader(response.get());
scoped_ptr<base::Value> value(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(list_value.get()));
}
TEST(ValuesUtilTest, PopStringArray) {
scoped_ptr<Response> response(Response::CreateEmpty());
// Append a string array.
MessageWriter writer(response.get());
MessageWriter sub_writer(NULL);
std::vector<std::string> data;
data.push_back("Dreamlifter");
data.push_back("Beluga");
data.push_back("Mriya");
writer.AppendArrayOfStrings(data);
// Create the expected value.
scoped_ptr<base::ListValue> list_value(new base::ListValue);
for (size_t i = 0; i != data.size(); ++i)
list_value->Append(new base::StringValue(data[i]));
// Pop a string array.
MessageReader reader(response.get());
scoped_ptr<base::Value> value(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(list_value.get()));
}
TEST(ValuesUtilTest, PopStruct) {
scoped_ptr<Response> response(Response::CreateEmpty());
// Append a struct.
MessageWriter writer(response.get());
MessageWriter sub_writer(NULL);
writer.OpenStruct(&sub_writer);
const bool kBoolValue = true;
sub_writer.AppendBool(kBoolValue);
const int32 kInt32Value = -123;
sub_writer.AppendInt32(kInt32Value);
const double kDoubleValue = 1.23;
sub_writer.AppendDouble(kDoubleValue);
const std::string kStringValue = "one two three";
sub_writer.AppendString(kStringValue);
writer.CloseContainer(&sub_writer);
// Create the expected value.
base::ListValue list_value;
list_value.Append(new base::FundamentalValue(kBoolValue));
list_value.Append(new base::FundamentalValue(kInt32Value));
list_value.Append(new base::FundamentalValue(kDoubleValue));
list_value.Append(new base::StringValue(kStringValue));
// Pop a struct.
MessageReader reader(response.get());
scoped_ptr<base::Value> value(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&list_value));
}
TEST(ValuesUtilTest, PopStringToVariantDictionary) {
scoped_ptr<Response> response(Response::CreateEmpty());
// Append a dictionary.
MessageWriter writer(response.get());
MessageWriter sub_writer(NULL);
MessageWriter entry_writer(NULL);
writer.OpenArray("{sv}", &sub_writer);
sub_writer.OpenDictEntry(&entry_writer);
const std::string kKey1 = "one";
entry_writer.AppendString(kKey1);
const bool kBoolValue = true;
entry_writer.AppendVariantOfBool(kBoolValue);
sub_writer.CloseContainer(&entry_writer);
sub_writer.OpenDictEntry(&entry_writer);
const std::string kKey2 = "two";
entry_writer.AppendString(kKey2);
const int32 kInt32Value = -45;
entry_writer.AppendVariantOfInt32(kInt32Value);
sub_writer.CloseContainer(&entry_writer);
sub_writer.OpenDictEntry(&entry_writer);
const std::string kKey3 = "three";
entry_writer.AppendString(kKey3);
const double kDoubleValue = 4.9;
entry_writer.AppendVariantOfDouble(kDoubleValue);
sub_writer.CloseContainer(&entry_writer);
sub_writer.OpenDictEntry(&entry_writer);
const std::string kKey4 = "four";
entry_writer.AppendString(kKey4);
const std::string kStringValue = "fifty";
entry_writer.AppendVariantOfString(kStringValue);
sub_writer.CloseContainer(&entry_writer);
writer.CloseContainer(&sub_writer);
// Create the expected value.
base::DictionaryValue dictionary_value;
dictionary_value.SetBoolean(kKey1, kBoolValue);
dictionary_value.SetInteger(kKey2, kInt32Value);
dictionary_value.SetDouble(kKey3, kDoubleValue);
dictionary_value.SetString(kKey4, kStringValue);
// Pop a dictinoary.
MessageReader reader(response.get());
scoped_ptr<base::Value> value(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&dictionary_value));
}
TEST(ValuesUtilTest, PopDictionaryWithDottedStringKey) {
scoped_ptr<Response> response(Response::CreateEmpty());
// Append a dictionary.
MessageWriter writer(response.get());
MessageWriter sub_writer(NULL);
MessageWriter entry_writer(NULL);
writer.OpenArray("{sv}", &sub_writer);
sub_writer.OpenDictEntry(&entry_writer);
const std::string kKey1 = "www.example.com"; // String including dots.
entry_writer.AppendString(kKey1);
const bool kBoolValue = true;
entry_writer.AppendVariantOfBool(kBoolValue);
sub_writer.CloseContainer(&entry_writer);
sub_writer.OpenDictEntry(&entry_writer);
const std::string kKey2 = ".example"; // String starting with a dot.
entry_writer.AppendString(kKey2);
const int32 kInt32Value = -45;
entry_writer.AppendVariantOfInt32(kInt32Value);
sub_writer.CloseContainer(&entry_writer);
sub_writer.OpenDictEntry(&entry_writer);
const std::string kKey3 = "example."; // String ending with a dot.
entry_writer.AppendString(kKey3);
const double kDoubleValue = 4.9;
entry_writer.AppendVariantOfDouble(kDoubleValue);
sub_writer.CloseContainer(&entry_writer);
writer.CloseContainer(&sub_writer);
// Create the expected value.
base::DictionaryValue dictionary_value;
dictionary_value.SetWithoutPathExpansion(
kKey1, new base::FundamentalValue(kBoolValue));
dictionary_value.SetWithoutPathExpansion(
kKey2, new base::FundamentalValue(kInt32Value));
dictionary_value.SetWithoutPathExpansion(
kKey3, new base::FundamentalValue(kDoubleValue));
// Pop a dictinoary.
MessageReader reader(response.get());
scoped_ptr<base::Value> value(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&dictionary_value));
}
TEST(ValuesUtilTest, PopDoubleToIntDictionary) {
// Create test data.
const int32 kValues[] = {0, 1, 1, 2, 3, 5, 8, 13, 21};
const std::vector<int32> values(kValues, kValues + arraysize(kValues));
std::vector<double> keys(values.size());
for (size_t i = 0; i != values.size(); ++i)
keys[i] = sqrt(values[i]);
// Append a dictionary.
scoped_ptr<Response> response(Response::CreateEmpty());
MessageWriter writer(response.get());
MessageWriter sub_writer(NULL);
writer.OpenArray("{di}", &sub_writer);
for (size_t i = 0; i != values.size(); ++i) {
MessageWriter entry_writer(NULL);
sub_writer.OpenDictEntry(&entry_writer);
entry_writer.AppendDouble(keys[i]);
entry_writer.AppendInt32(values[i]);
sub_writer.CloseContainer(&entry_writer);
}
writer.CloseContainer(&sub_writer);
// Create the expected value.
base::DictionaryValue dictionary_value;
for (size_t i = 0; i != values.size(); ++i) {
scoped_ptr<base::Value> key_value(new base::FundamentalValue(keys[i]));
std::string key_string;
base::JSONWriter::Write(key_value.get(), &key_string);
dictionary_value.SetWithoutPathExpansion(
key_string, new base::FundamentalValue(values[i]));
}
// Pop a dictionary.
MessageReader reader(response.get());
scoped_ptr<base::Value> value(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&dictionary_value));
}
TEST(ValuesUtilTest, AppendBasicTypes) {
const base::FundamentalValue kBoolValue(false);
const base::FundamentalValue kIntegerValue(42);
const base::FundamentalValue kDoubleValue(4.2);
const base::StringValue kStringValue("string");
scoped_ptr<Response> response(Response::CreateEmpty());
MessageWriter writer(response.get());
AppendBasicTypeValueData(&writer, kBoolValue);
AppendBasicTypeValueData(&writer, kIntegerValue);
AppendBasicTypeValueData(&writer, kDoubleValue);
AppendBasicTypeValueData(&writer, kStringValue);
MessageReader reader(response.get());
scoped_ptr<base::Value> value;
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&kBoolValue));
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&kIntegerValue));
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&kDoubleValue));
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&kStringValue));
}
TEST(ValuesUtilTest, AppendBasicTypesAsVariant) {
const base::FundamentalValue kBoolValue(false);
const base::FundamentalValue kIntegerValue(42);
const base::FundamentalValue kDoubleValue(4.2);
const base::StringValue kStringValue("string");
scoped_ptr<Response> response(Response::CreateEmpty());
MessageWriter writer(response.get());
AppendBasicTypeValueDataAsVariant(&writer, kBoolValue);
AppendBasicTypeValueDataAsVariant(&writer, kIntegerValue);
AppendBasicTypeValueDataAsVariant(&writer, kDoubleValue);
AppendBasicTypeValueDataAsVariant(&writer, kStringValue);
MessageReader reader(response.get());
scoped_ptr<base::Value> value;
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&kBoolValue));
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&kIntegerValue));
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&kDoubleValue));
value.reset(PopDataAsValue(&reader));
ASSERT_TRUE(value.get() != NULL);
EXPECT_TRUE(value->Equals(&kStringValue));
}
} // namespace dbus