// 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));
}

TEST(ValuesUtilTest, AppendValueDataBasicTypes) {
  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());
  AppendValueData(&writer, kBoolValue);
  AppendValueData(&writer, kIntegerValue);
  AppendValueData(&writer, kDoubleValue);
  AppendValueData(&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, AppendValueDataAsVariantBasicTypes) {
  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());
  AppendValueDataAsVariant(&writer, kBoolValue);
  AppendValueDataAsVariant(&writer, kIntegerValue);
  AppendValueDataAsVariant(&writer, kDoubleValue);
  AppendValueDataAsVariant(&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, AppendDictionary) {
  // Set up the input dictionary.
  const std::string kKey1 = "one";
  const std::string kKey2 = "two";
  const std::string kKey3 = "three";
  const std::string kKey4 = "four";
  const std::string kKey5 = "five";
  const std::string kKey6 = "six";

  const bool kBoolValue = true;
  const int32 kInt32Value = -45;
  const double kDoubleValue = 4.9;
  const std::string kStringValue = "fifty";

  base::ListValue* list_value = new base::ListValue();
  list_value->AppendBoolean(kBoolValue);
  list_value->AppendInteger(kInt32Value);

  base::DictionaryValue* dictionary_value = new base::DictionaryValue();
  dictionary_value->SetBoolean(kKey1, kBoolValue);
  dictionary_value->SetInteger(kKey2, kDoubleValue);

  base::DictionaryValue test_dictionary;
  test_dictionary.SetBoolean(kKey1, kBoolValue);
  test_dictionary.SetInteger(kKey2, kInt32Value);
  test_dictionary.SetDouble(kKey3, kDoubleValue);
  test_dictionary.SetString(kKey4, kStringValue);
  test_dictionary.Set(kKey5, list_value);  // takes ownership
  test_dictionary.Set(kKey6, dictionary_value);  // takes ownership

  scoped_ptr<Response> response(Response::CreateEmpty());
  MessageWriter writer(response.get());
  AppendValueData(&writer, test_dictionary);
  base::FundamentalValue int_value(kInt32Value);
  AppendValueData(&writer, int_value);

  // Read the data.
  MessageReader reader(response.get());
  scoped_ptr<base::Value> value;
  value.reset(PopDataAsValue(&reader));
  ASSERT_TRUE(value.get() != NULL);
  EXPECT_TRUE(value->Equals(&test_dictionary));
  value.reset(PopDataAsValue(&reader));
  ASSERT_TRUE(value.get() != NULL);
  EXPECT_TRUE(value->Equals(&int_value));
}

TEST(ValuesUtilTest, AppendDictionaryAsVariant) {
  // Set up the input dictionary.
  const std::string kKey1 = "one";
  const std::string kKey2 = "two";
  const std::string kKey3 = "three";
  const std::string kKey4 = "four";
  const std::string kKey5 = "five";
  const std::string kKey6 = "six";

  const bool kBoolValue = true;
  const int32 kInt32Value = -45;
  const double kDoubleValue = 4.9;
  const std::string kStringValue = "fifty";

  base::ListValue* list_value = new base::ListValue();
  list_value->AppendBoolean(kBoolValue);
  list_value->AppendInteger(kInt32Value);

  base::DictionaryValue* dictionary_value = new base::DictionaryValue();
  dictionary_value->SetBoolean(kKey1, kBoolValue);
  dictionary_value->SetInteger(kKey2, kDoubleValue);

  base::DictionaryValue test_dictionary;
  test_dictionary.SetBoolean(kKey1, kBoolValue);
  test_dictionary.SetInteger(kKey2, kInt32Value);
  test_dictionary.SetDouble(kKey3, kDoubleValue);
  test_dictionary.SetString(kKey4, kStringValue);
  test_dictionary.Set(kKey5, list_value);  // takes ownership
  test_dictionary.Set(kKey6, dictionary_value);  // takes ownership

  scoped_ptr<Response> response(Response::CreateEmpty());
  MessageWriter writer(response.get());
  AppendValueDataAsVariant(&writer, test_dictionary);
  base::FundamentalValue int_value(kInt32Value);
  AppendValueData(&writer, int_value);

  // Read the data.
  MessageReader reader(response.get());
  scoped_ptr<base::Value> value;
  value.reset(PopDataAsValue(&reader));
  ASSERT_TRUE(value.get() != NULL);
  EXPECT_TRUE(value->Equals(&test_dictionary));
  value.reset(PopDataAsValue(&reader));
  ASSERT_TRUE(value.get() != NULL);
  EXPECT_TRUE(value->Equals(&int_value));
}

TEST(ValuesUtilTest, AppendList) {
  // Set up the input list.
  const std::string kKey1 = "one";
  const std::string kKey2 = "two";

  const bool kBoolValue = true;
  const int32 kInt32Value = -45;
  const double kDoubleValue = 4.9;
  const std::string kStringValue = "fifty";

  base::ListValue* list_value = new base::ListValue();
  list_value->AppendBoolean(kBoolValue);
  list_value->AppendInteger(kInt32Value);

  base::DictionaryValue* dictionary_value = new base::DictionaryValue();
  dictionary_value->SetBoolean(kKey1, kBoolValue);
  dictionary_value->SetInteger(kKey2, kDoubleValue);

  base::ListValue test_list;
  test_list.AppendBoolean(kBoolValue);
  test_list.AppendInteger(kInt32Value);
  test_list.AppendDouble(kDoubleValue);
  test_list.AppendString(kStringValue);
  test_list.Append(list_value);  // takes ownership
  test_list.Append(dictionary_value);  // takes ownership

  scoped_ptr<Response> response(Response::CreateEmpty());
  MessageWriter writer(response.get());
  AppendValueData(&writer, test_list);
  base::FundamentalValue int_value(kInt32Value);
  AppendValueData(&writer, int_value);

  // Read the data.
  MessageReader reader(response.get());
  scoped_ptr<base::Value> value;
  value.reset(PopDataAsValue(&reader));
  ASSERT_TRUE(value.get() != NULL);
  EXPECT_TRUE(value->Equals(&test_list));
  value.reset(PopDataAsValue(&reader));
  ASSERT_TRUE(value.get() != NULL);
  EXPECT_TRUE(value->Equals(&int_value));
}

TEST(ValuesUtilTest, AppendListAsVariant) {
  // Set up the input list.
  const std::string kKey1 = "one";
  const std::string kKey2 = "two";

  const bool kBoolValue = true;
  const int32 kInt32Value = -45;
  const double kDoubleValue = 4.9;
  const std::string kStringValue = "fifty";

  base::ListValue* list_value = new base::ListValue();
  list_value->AppendBoolean(kBoolValue);
  list_value->AppendInteger(kInt32Value);

  base::DictionaryValue* dictionary_value = new base::DictionaryValue();
  dictionary_value->SetBoolean(kKey1, kBoolValue);
  dictionary_value->SetInteger(kKey2, kDoubleValue);

  base::ListValue test_list;
  test_list.AppendBoolean(kBoolValue);
  test_list.AppendInteger(kInt32Value);
  test_list.AppendDouble(kDoubleValue);
  test_list.AppendString(kStringValue);
  test_list.Append(list_value);  // takes ownership
  test_list.Append(dictionary_value);  // takes ownership

  scoped_ptr<Response> response(Response::CreateEmpty());
  MessageWriter writer(response.get());
  AppendValueDataAsVariant(&writer, test_list);
  base::FundamentalValue int_value(kInt32Value);
  AppendValueData(&writer, int_value);

  // Read the data.
  MessageReader reader(response.get());
  scoped_ptr<base::Value> value;
  value.reset(PopDataAsValue(&reader));
  ASSERT_TRUE(value.get() != NULL);
  EXPECT_TRUE(value->Equals(&test_list));
  value.reset(PopDataAsValue(&reader));
  ASSERT_TRUE(value.get() != NULL);
  EXPECT_TRUE(value->Equals(&int_value));
}

}  // namespace dbus
