values_util_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "dbus/values_util.h"
6
7#include <vector>
8
9#include "base/float_util.h"
10#include "base/json/json_writer.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/values.h"
13#include "dbus/message.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16TEST(ValuesUtilTest, PopBasicTypes) {
17  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
18  // Append basic type values.
19  dbus::MessageWriter writer(response.get());
20  const uint8 kByteValue = 42;
21  writer.AppendByte(kByteValue);
22  const bool kBoolValue = true;
23  writer.AppendBool(kBoolValue);
24  const int16 kInt16Value = -43;
25  writer.AppendInt16(kInt16Value);
26  const uint16 kUint16Value = 44;
27  writer.AppendUint16(kUint16Value);
28  const int32 kInt32Value = -45;
29  writer.AppendInt32(kInt32Value);
30  const uint32 kUint32Value = 46;
31  writer.AppendUint32(kUint32Value);
32  const int64 kInt64Value = -47;
33  writer.AppendInt64(kInt64Value);
34  const uint64 kUint64Value = 48;
35  writer.AppendUint64(kUint64Value);
36  const double kDoubleValue = 4.9;
37  writer.AppendDouble(kDoubleValue);
38  const std::string kStringValue = "fifty";
39  writer.AppendString(kStringValue);
40  const std::string kEmptyStringValue;
41  writer.AppendString(kEmptyStringValue);
42  const dbus::ObjectPath kObjectPathValue("/ObjectPath");
43  writer.AppendObjectPath(kObjectPathValue);
44
45  dbus::MessageReader reader(response.get());
46  scoped_ptr<base::Value> value;
47  scoped_ptr<base::Value> expected_value;
48  // Pop a byte.
49  value.reset(dbus::PopDataAsValue(&reader));
50  ASSERT_TRUE(value.get() != NULL);
51  expected_value.reset(new base::FundamentalValue(kByteValue));
52  EXPECT_TRUE(value->Equals(expected_value.get()));
53  // Pop a bool.
54  value.reset(dbus::PopDataAsValue(&reader));
55  ASSERT_TRUE(value.get() != NULL);
56  expected_value.reset(new base::FundamentalValue(kBoolValue));
57  EXPECT_TRUE(value->Equals(expected_value.get()));
58  // Pop an int16.
59  value.reset(dbus::PopDataAsValue(&reader));
60  ASSERT_TRUE(value.get() != NULL);
61  expected_value.reset(new base::FundamentalValue(kInt16Value));
62  EXPECT_TRUE(value->Equals(expected_value.get()));
63  // Pop a uint16.
64  value.reset(dbus::PopDataAsValue(&reader));
65  ASSERT_TRUE(value.get() != NULL);
66  expected_value.reset(new base::FundamentalValue(kUint16Value));
67  EXPECT_TRUE(value->Equals(expected_value.get()));
68  // Pop an int32.
69  value.reset(dbus::PopDataAsValue(&reader));
70  ASSERT_TRUE(value.get() != NULL);
71  expected_value.reset(new base::FundamentalValue(kInt32Value));
72  EXPECT_TRUE(value->Equals(expected_value.get()));
73  // Pop a uint32.
74  value.reset(dbus::PopDataAsValue(&reader));
75  ASSERT_TRUE(value.get() != NULL);
76  expected_value.reset(
77      new base::FundamentalValue(static_cast<double>(kUint32Value)));
78  EXPECT_TRUE(value->Equals(expected_value.get()));
79  // Pop an int64.
80  value.reset(dbus::PopDataAsValue(&reader));
81  ASSERT_TRUE(value.get() != NULL);
82  expected_value.reset(
83      new base::FundamentalValue(static_cast<double>(kInt64Value)));
84  EXPECT_TRUE(value->Equals(expected_value.get()));
85  // Pop a uint64.
86  value.reset(dbus::PopDataAsValue(&reader));
87  ASSERT_TRUE(value.get() != NULL);
88  expected_value.reset(
89      new base::FundamentalValue(static_cast<double>(kUint64Value)));
90  EXPECT_TRUE(value->Equals(expected_value.get()));
91  // Pop a double.
92  value.reset(dbus::PopDataAsValue(&reader));
93  ASSERT_TRUE(value.get() != NULL);
94  expected_value.reset(new base::FundamentalValue(kDoubleValue));
95  EXPECT_TRUE(value->Equals(expected_value.get()));
96  // Pop a string.
97  value.reset(dbus::PopDataAsValue(&reader));
98  ASSERT_TRUE(value.get() != NULL);
99  expected_value.reset(new base::StringValue(kStringValue));
100  EXPECT_TRUE(value->Equals(expected_value.get()));
101  // Pop an empty string.
102  value.reset(dbus::PopDataAsValue(&reader));
103  ASSERT_TRUE(value.get() != NULL);
104  expected_value.reset(new base::StringValue(kEmptyStringValue));
105  EXPECT_TRUE(value->Equals(expected_value.get()));
106  // Pop an object path.
107  value.reset(dbus::PopDataAsValue(&reader));
108  ASSERT_TRUE(value.get() != NULL);
109  expected_value.reset(new base::StringValue(kObjectPathValue.value()));
110  EXPECT_TRUE(value->Equals(expected_value.get()));
111}
112
113TEST(ValuesUtilTest, PopVariant) {
114  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
115  // Append variant values.
116  dbus::MessageWriter writer(response.get());
117  const bool kBoolValue = true;
118  writer.AppendVariantOfBool(kBoolValue);
119  const int32 kInt32Value = -45;
120  writer.AppendVariantOfInt32(kInt32Value);
121  const double kDoubleValue = 4.9;
122  writer.AppendVariantOfDouble(kDoubleValue);
123  const std::string kStringValue = "fifty";
124  writer.AppendVariantOfString(kStringValue);
125
126  dbus::MessageReader reader(response.get());
127  scoped_ptr<base::Value> value;
128  scoped_ptr<base::Value> expected_value;
129  // Pop a bool.
130  value.reset(dbus::PopDataAsValue(&reader));
131  ASSERT_TRUE(value.get() != NULL);
132  expected_value.reset(new base::FundamentalValue(kBoolValue));
133  EXPECT_TRUE(value->Equals(expected_value.get()));
134  // Pop an int32.
135  value.reset(dbus::PopDataAsValue(&reader));
136  ASSERT_TRUE(value.get() != NULL);
137  expected_value.reset(new base::FundamentalValue(kInt32Value));
138  EXPECT_TRUE(value->Equals(expected_value.get()));
139  // Pop a double.
140  value.reset(dbus::PopDataAsValue(&reader));
141  ASSERT_TRUE(value.get() != NULL);
142  expected_value.reset(new base::FundamentalValue(kDoubleValue));
143  EXPECT_TRUE(value->Equals(expected_value.get()));
144  // Pop a string.
145  value.reset(dbus::PopDataAsValue(&reader));
146  ASSERT_TRUE(value.get() != NULL);
147  expected_value.reset(new base::StringValue(kStringValue));
148  EXPECT_TRUE(value->Equals(expected_value.get()));
149}
150
151// Pop extremely large integers which cannot be precisely represented in
152// double.
153TEST(ValuesUtilTest, PopExtremelyLargeIntegers) {
154  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
155  // Append large integers.
156  dbus::MessageWriter writer(response.get());
157  const int64 kInt64Value = -123456789012345689LL;
158  writer.AppendInt64(kInt64Value);
159  const uint64 kUint64Value = 9876543210987654321ULL;
160  writer.AppendUint64(kUint64Value);
161
162  dbus::MessageReader reader(response.get());
163  scoped_ptr<base::Value> value;
164  scoped_ptr<base::Value> expected_value;
165  double double_value = 0;
166  // Pop an int64.
167  value.reset(dbus::PopDataAsValue(&reader));
168  ASSERT_TRUE(value.get() != NULL);
169  expected_value.reset(
170      new base::FundamentalValue(static_cast<double>(kInt64Value)));
171  EXPECT_TRUE(value->Equals(expected_value.get()));
172  ASSERT_TRUE(value->GetAsDouble(&double_value));
173  EXPECT_NE(kInt64Value, static_cast<int64>(double_value));
174  // Pop a uint64.
175  value.reset(dbus::PopDataAsValue(&reader));
176  ASSERT_TRUE(value.get() != NULL);
177  expected_value.reset(
178      new base::FundamentalValue(static_cast<double>(kUint64Value)));
179  EXPECT_TRUE(value->Equals(expected_value.get()));
180  ASSERT_TRUE(value->GetAsDouble(&double_value));
181  EXPECT_NE(kUint64Value, static_cast<uint64>(double_value));
182}
183
184TEST(ValuesUtilTest, PopIntArray) {
185  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
186  // Append an int32 array.
187  dbus::MessageWriter writer(response.get());
188  dbus::MessageWriter sub_writer(NULL);
189  std::vector<int32> data;
190  data.push_back(0);
191  data.push_back(1);
192  data.push_back(2);
193  writer.OpenArray("i", &sub_writer);
194  for (size_t i = 0; i != data.size(); ++i)
195    sub_writer.AppendInt32(data[i]);
196  writer.CloseContainer(&sub_writer);
197
198  // Create the expected value.
199  scoped_ptr<base::ListValue> list_value(new base::ListValue);
200  for (size_t i = 0; i != data.size(); ++i)
201    list_value->Append(new base::FundamentalValue(data[i]));
202
203  // Pop an int32 array.
204  dbus::MessageReader reader(response.get());
205  scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
206  ASSERT_TRUE(value.get() != NULL);
207  EXPECT_TRUE(value->Equals(list_value.get()));
208}
209
210TEST(ValuesUtilTest, PopStringArray) {
211  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
212  // Append a string array.
213  dbus::MessageWriter writer(response.get());
214  dbus::MessageWriter sub_writer(NULL);
215  std::vector<std::string> data;
216  data.push_back("Dreamlifter");
217  data.push_back("Beluga");
218  data.push_back("Mriya");
219  writer.AppendArrayOfStrings(data);
220
221  // Create the expected value.
222  scoped_ptr<base::ListValue> list_value(new base::ListValue);
223  for (size_t i = 0; i != data.size(); ++i)
224    list_value->Append(new base::StringValue(data[i]));
225
226  // Pop a string array.
227  dbus::MessageReader reader(response.get());
228  scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
229  ASSERT_TRUE(value.get() != NULL);
230  EXPECT_TRUE(value->Equals(list_value.get()));
231}
232
233TEST(ValuesUtilTest, PopStruct) {
234  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
235  // Append a struct.
236  dbus::MessageWriter writer(response.get());
237  dbus::MessageWriter sub_writer(NULL);
238  writer.OpenStruct(&sub_writer);
239  const bool kBoolValue = true;
240  sub_writer.AppendBool(kBoolValue);
241  const int32 kInt32Value = -123;
242  sub_writer.AppendInt32(kInt32Value);
243  const double kDoubleValue = 1.23;
244  sub_writer.AppendDouble(kDoubleValue);
245  const std::string kStringValue = "one two three";
246  sub_writer.AppendString(kStringValue);
247  writer.CloseContainer(&sub_writer);
248
249  // Create the expected value.
250  base::ListValue list_value;
251  list_value.Append(new base::FundamentalValue(kBoolValue));
252  list_value.Append(new base::FundamentalValue(kInt32Value));
253  list_value.Append(new base::FundamentalValue(kDoubleValue));
254  list_value.Append(new base::StringValue(kStringValue));
255
256  // Pop a struct.
257  dbus::MessageReader reader(response.get());
258  scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
259  ASSERT_TRUE(value.get() != NULL);
260  EXPECT_TRUE(value->Equals(&list_value));
261}
262
263TEST(ValuesUtilTest, PopStringToVariantDictionary) {
264  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
265  // Append a dictionary.
266  dbus::MessageWriter writer(response.get());
267  dbus::MessageWriter sub_writer(NULL);
268  dbus::MessageWriter entry_writer(NULL);
269  writer.OpenArray("{sv}", &sub_writer);
270  sub_writer.OpenDictEntry(&entry_writer);
271  const std::string kKey1 = "one";
272  entry_writer.AppendString(kKey1);
273  const bool kBoolValue = true;
274  entry_writer.AppendVariantOfBool(kBoolValue);
275  sub_writer.CloseContainer(&entry_writer);
276  sub_writer.OpenDictEntry(&entry_writer);
277  const std::string kKey2 = "two";
278  entry_writer.AppendString(kKey2);
279  const int32 kInt32Value = -45;
280  entry_writer.AppendVariantOfInt32(kInt32Value);
281  sub_writer.CloseContainer(&entry_writer);
282  sub_writer.OpenDictEntry(&entry_writer);
283  const std::string kKey3 = "three";
284  entry_writer.AppendString(kKey3);
285  const double kDoubleValue = 4.9;
286  entry_writer.AppendVariantOfDouble(kDoubleValue);
287  sub_writer.CloseContainer(&entry_writer);
288  sub_writer.OpenDictEntry(&entry_writer);
289  const std::string kKey4 = "four";
290  entry_writer.AppendString(kKey4);
291  const std::string kStringValue = "fifty";
292  entry_writer.AppendVariantOfString(kStringValue);
293  sub_writer.CloseContainer(&entry_writer);
294  writer.CloseContainer(&sub_writer);
295
296  // Create the expected value.
297  base::DictionaryValue dictionary_value;
298  dictionary_value.SetBoolean(kKey1, kBoolValue);
299  dictionary_value.SetInteger(kKey2, kInt32Value);
300  dictionary_value.SetDouble(kKey3, kDoubleValue);
301  dictionary_value.SetString(kKey4, kStringValue);
302
303  // Pop a dictinoary.
304  dbus::MessageReader reader(response.get());
305  scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
306  ASSERT_TRUE(value.get() != NULL);
307  EXPECT_TRUE(value->Equals(&dictionary_value));
308}
309
310TEST(ValuesUtilTest, PopDictionaryWithDottedStringKey) {
311  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
312  // Append a dictionary.
313  dbus::MessageWriter writer(response.get());
314  dbus::MessageWriter sub_writer(NULL);
315  dbus::MessageWriter entry_writer(NULL);
316  writer.OpenArray("{sv}", &sub_writer);
317  sub_writer.OpenDictEntry(&entry_writer);
318  const std::string kKey1 = "www.example.com";  // String including dots.
319  entry_writer.AppendString(kKey1);
320  const bool kBoolValue = true;
321  entry_writer.AppendVariantOfBool(kBoolValue);
322  sub_writer.CloseContainer(&entry_writer);
323  sub_writer.OpenDictEntry(&entry_writer);
324  const std::string kKey2 = ".example";  // String starting with a dot.
325  entry_writer.AppendString(kKey2);
326  const int32 kInt32Value = -45;
327  entry_writer.AppendVariantOfInt32(kInt32Value);
328  sub_writer.CloseContainer(&entry_writer);
329  sub_writer.OpenDictEntry(&entry_writer);
330  const std::string kKey3 = "example.";  // String ending with a dot.
331  entry_writer.AppendString(kKey3);
332  const double kDoubleValue = 4.9;
333  entry_writer.AppendVariantOfDouble(kDoubleValue);
334  sub_writer.CloseContainer(&entry_writer);
335  writer.CloseContainer(&sub_writer);
336
337  // Create the expected value.
338  base::DictionaryValue dictionary_value;
339  dictionary_value.SetWithoutPathExpansion(
340      kKey1, new base::FundamentalValue(kBoolValue));
341  dictionary_value.SetWithoutPathExpansion(
342      kKey2, new base::FundamentalValue(kInt32Value));
343  dictionary_value.SetWithoutPathExpansion(
344      kKey3, new base::FundamentalValue(kDoubleValue));
345
346  // Pop a dictinoary.
347  dbus::MessageReader reader(response.get());
348  scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
349  ASSERT_TRUE(value.get() != NULL);
350  EXPECT_TRUE(value->Equals(&dictionary_value));
351}
352
353TEST(ValuesUtilTest, PopDoubleToIntDictionary) {
354  // Create test data.
355  const int32 kValues[] = {0, 1, 1, 2, 3, 5, 8, 13, 21};
356  const std::vector<int32> values(kValues, kValues + arraysize(kValues));
357  std::vector<double> keys(values.size());
358  for (size_t i = 0; i != values.size(); ++i)
359    keys[i] = sqrt(values[i]);
360
361  // Append a dictionary.
362  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
363  dbus::MessageWriter writer(response.get());
364  dbus::MessageWriter sub_writer(NULL);
365  writer.OpenArray("{di}", &sub_writer);
366  for (size_t i = 0; i != values.size(); ++i) {
367    dbus::MessageWriter entry_writer(NULL);
368    sub_writer.OpenDictEntry(&entry_writer);
369    entry_writer.AppendDouble(keys[i]);
370    entry_writer.AppendInt32(values[i]);
371    sub_writer.CloseContainer(&entry_writer);
372  }
373  writer.CloseContainer(&sub_writer);
374
375  // Create the expected value.
376  base::DictionaryValue dictionary_value;
377  for (size_t i = 0; i != values.size(); ++i) {
378    scoped_ptr<base::Value> key_value(new base::FundamentalValue(keys[i]));
379    std::string key_string;
380    base::JSONWriter::Write(key_value.get(), &key_string);
381    dictionary_value.SetWithoutPathExpansion(
382        key_string, new base::FundamentalValue(values[i]));
383  }
384
385  // Pop a dictionary.
386  dbus::MessageReader reader(response.get());
387  scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
388  ASSERT_TRUE(value.get() != NULL);
389  EXPECT_TRUE(value->Equals(&dictionary_value));
390}
391
392TEST(ValuesUtilTest, AppendBasicTypes) {
393  const base::FundamentalValue kBoolValue(false);
394  const base::FundamentalValue kIntegerValue(42);
395  const base::FundamentalValue kDoubleValue(4.2);
396  const base::StringValue kStringValue("string");
397
398  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
399  dbus::MessageWriter writer(response.get());
400  AppendBasicTypeValueData(&writer, kBoolValue);
401  AppendBasicTypeValueData(&writer, kIntegerValue);
402  AppendBasicTypeValueData(&writer, kDoubleValue);
403  AppendBasicTypeValueData(&writer, kStringValue);
404
405  dbus::MessageReader reader(response.get());
406  scoped_ptr<base::Value> value;
407  value.reset(dbus::PopDataAsValue(&reader));
408  ASSERT_TRUE(value.get() != NULL);
409  EXPECT_TRUE(value->Equals(&kBoolValue));
410  value.reset(dbus::PopDataAsValue(&reader));
411  ASSERT_TRUE(value.get() != NULL);
412  EXPECT_TRUE(value->Equals(&kIntegerValue));
413  value.reset(dbus::PopDataAsValue(&reader));
414  ASSERT_TRUE(value.get() != NULL);
415  EXPECT_TRUE(value->Equals(&kDoubleValue));
416  value.reset(dbus::PopDataAsValue(&reader));
417  ASSERT_TRUE(value.get() != NULL);
418  EXPECT_TRUE(value->Equals(&kStringValue));
419}
420
421TEST(ValuesUtilTest, AppendBasicTypesAsVariant) {
422  const base::FundamentalValue kBoolValue(false);
423  const base::FundamentalValue kIntegerValue(42);
424  const base::FundamentalValue kDoubleValue(4.2);
425  const base::StringValue kStringValue("string");
426
427  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
428  dbus::MessageWriter writer(response.get());
429  AppendBasicTypeValueDataAsVariant(&writer, kBoolValue);
430  AppendBasicTypeValueDataAsVariant(&writer, kIntegerValue);
431  AppendBasicTypeValueDataAsVariant(&writer, kDoubleValue);
432  AppendBasicTypeValueDataAsVariant(&writer, kStringValue);
433
434  dbus::MessageReader reader(response.get());
435  scoped_ptr<base::Value> value;
436  value.reset(dbus::PopDataAsValue(&reader));
437  ASSERT_TRUE(value.get() != NULL);
438  EXPECT_TRUE(value->Equals(&kBoolValue));
439  value.reset(dbus::PopDataAsValue(&reader));
440  ASSERT_TRUE(value.get() != NULL);
441  EXPECT_TRUE(value->Equals(&kIntegerValue));
442  value.reset(dbus::PopDataAsValue(&reader));
443  ASSERT_TRUE(value.get() != NULL);
444  EXPECT_TRUE(value->Equals(&kDoubleValue));
445  value.reset(dbus::PopDataAsValue(&reader));
446  ASSERT_TRUE(value.get() != NULL);
447  EXPECT_TRUE(value->Equals(&kStringValue));
448}
449