• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 "base/values.h"
6 
7 #include <stddef.h>
8 
9 #include <algorithm>
10 #include <functional>
11 #include <iterator>
12 #include <limits>
13 #include <memory>
14 #include <string>
15 #include <type_traits>
16 #include <utility>
17 #include <vector>
18 
19 #include "base/bits.h"
20 #include "base/containers/adapters.h"
21 #include "base/containers/contains.h"
22 #include "base/strings/string_piece.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/test/gtest_util.h"
25 #include "build/build_config.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 
29 #if BUILDFLAG(ENABLE_BASE_TRACING)
30 #include "third_party/abseil-cpp/absl/types/optional.h"
31 #include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h"  // no-presubmit-check nogncheck
32 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
33 
34 namespace base {
35 
36 #ifdef NDEBUG
37 // `Value` should have a (relatively) small size to avoid creating excess
38 // overhead, e.g. for lists of values that are all ints.
39 //
40 // This test is limited to NDEBUG builds, since some containers may require
41 // extra storage for supporting debug checks for things like iterators.
TEST(ValuesTest,SizeOfValue)42 TEST(ValuesTest, SizeOfValue) {
43 #if defined(__GLIBCXX__)
44   // libstdc++ std::string takes already 4 machine words, so the absl::variant
45   // takes 5
46   constexpr size_t kExpectedSize = 5 * sizeof(void*);
47 #else   // !defined(__GLIBCXX__)
48   // libc++'s std::string and std::vector both take 3 machine words. An
49   // additional word is used by absl::variant for the type index.
50   constexpr size_t kExpectedSize = 4 * sizeof(void*);
51 #endif  // defined(__GLIBCXX__)
52 
53   // Use std::integral_constant so the compiler error message includes the
54   // evaluated size. In future versions of clang, it should be possible to
55   // simplify this to an equality comparison (i.e. newer clangs print out
56   // "comparison reduces to '(1 == 2)'").
57   static_assert(std::is_same_v<std::integral_constant<size_t, sizeof(Value)>,
58                                std::integral_constant<size_t, kExpectedSize>>,
59                 "base::Value has an unexpected size!");
60 }
61 #endif
62 
TEST(ValuesTest,TestNothrow)63 TEST(ValuesTest, TestNothrow) {
64   static_assert(std::is_nothrow_move_constructible_v<Value>,
65                 "IsNothrowMoveConstructible");
66   static_assert(std::is_nothrow_default_constructible_v<Value>,
67                 "IsNothrowDefaultConstructible");
68   static_assert(std::is_nothrow_constructible_v<Value, std::string&&>,
69                 "IsNothrowMoveConstructibleFromString");
70   static_assert(std::is_nothrow_constructible_v<Value, Value::BlobStorage&&>,
71                 "IsNothrowMoveConstructibleFromBlob");
72   static_assert(std::is_nothrow_move_assignable_v<Value>,
73                 "IsNothrowMoveAssignable");
74 }
75 
TEST(ValuesTest,EmptyValue)76 TEST(ValuesTest, EmptyValue) {
77   Value value;
78   EXPECT_EQ(Value::Type::NONE, value.type());
79   EXPECT_EQ(absl::nullopt, value.GetIfBool());
80   EXPECT_EQ(absl::nullopt, value.GetIfInt());
81   EXPECT_EQ(absl::nullopt, value.GetIfDouble());
82   EXPECT_EQ(nullptr, value.GetIfString());
83   EXPECT_EQ(nullptr, value.GetIfBlob());
84 }
85 
86 // Group of tests for the value constructors.
TEST(ValuesTest,ConstructBool)87 TEST(ValuesTest, ConstructBool) {
88   Value true_value(true);
89   EXPECT_EQ(Value::Type::BOOLEAN, true_value.type());
90   EXPECT_THAT(true_value.GetIfBool(), testing::Optional(true));
91   EXPECT_TRUE(true_value.GetBool());
92 
93   Value false_value(false);
94   EXPECT_EQ(Value::Type::BOOLEAN, false_value.type());
95   EXPECT_THAT(false_value.GetIfBool(), testing::Optional(false));
96   EXPECT_FALSE(false_value.GetBool());
97 }
98 
TEST(ValuesTest,ConstructFromPtrs)99 TEST(ValuesTest, ConstructFromPtrs) {
100   static_assert(!std::is_constructible_v<Value, int*>, "");
101   static_assert(!std::is_constructible_v<Value, const int*>, "");
102   static_assert(!std::is_constructible_v<Value, wchar_t*>, "");
103   static_assert(!std::is_constructible_v<Value, const wchar_t*>, "");
104 
105   static_assert(std::is_constructible_v<Value, char*>, "");
106   static_assert(std::is_constructible_v<Value, const char*>, "");
107   static_assert(std::is_constructible_v<Value, char16_t*>, "");
108   static_assert(std::is_constructible_v<Value, const char16_t*>, "");
109 }
110 
TEST(ValuesTest,ConstructInt)111 TEST(ValuesTest, ConstructInt) {
112   Value value(-37);
113   EXPECT_EQ(Value::Type::INTEGER, value.type());
114   EXPECT_THAT(value.GetIfInt(), testing::Optional(-37));
115   EXPECT_EQ(-37, value.GetInt());
116 
117   EXPECT_THAT(value.GetIfDouble(), testing::Optional(-37.0));
118   EXPECT_EQ(-37.0, value.GetDouble());
119 }
120 
TEST(ValuesTest,ConstructDouble)121 TEST(ValuesTest, ConstructDouble) {
122   Value value(-4.655);
123   EXPECT_EQ(Value::Type::DOUBLE, value.type());
124   EXPECT_THAT(value.GetIfDouble(), testing::Optional(-4.655));
125   EXPECT_EQ(-4.655, value.GetDouble());
126 }
127 
TEST(ValuesTest,ConstructStringFromConstCharPtr)128 TEST(ValuesTest, ConstructStringFromConstCharPtr) {
129   const char* str = "foobar";
130   Value value(str);
131   EXPECT_EQ(Value::Type::STRING, value.type());
132   EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
133   EXPECT_EQ("foobar", value.GetString());
134 }
135 
TEST(ValuesTest,ConstructStringFromStringPiece)136 TEST(ValuesTest, ConstructStringFromStringPiece) {
137   std::string str = "foobar";
138   Value value{StringPiece(str)};
139   EXPECT_EQ(Value::Type::STRING, value.type());
140   EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
141   EXPECT_EQ("foobar", value.GetString());
142 }
143 
TEST(ValuesTest,ConstructStringFromStdStringRRef)144 TEST(ValuesTest, ConstructStringFromStdStringRRef) {
145   std::string str = "foobar";
146   Value value(std::move(str));
147   EXPECT_EQ(Value::Type::STRING, value.type());
148   EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
149   EXPECT_EQ("foobar", value.GetString());
150 }
151 
TEST(ValuesTest,ConstructStringFromConstChar16Ptr)152 TEST(ValuesTest, ConstructStringFromConstChar16Ptr) {
153   std::u16string str = u"foobar";
154   Value value(str.c_str());
155   EXPECT_EQ(Value::Type::STRING, value.type());
156   EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
157   EXPECT_EQ("foobar", value.GetString());
158 }
159 
TEST(ValuesTest,ConstructStringFromStringPiece16)160 TEST(ValuesTest, ConstructStringFromStringPiece16) {
161   std::u16string str = u"foobar";
162   Value value{StringPiece16(str)};
163   EXPECT_EQ(Value::Type::STRING, value.type());
164   EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
165   EXPECT_EQ("foobar", value.GetString());
166 }
167 
TEST(ValuesTest,ConstructBinary)168 TEST(ValuesTest, ConstructBinary) {
169   Value::BlobStorage blob = {0xF, 0x0, 0x0, 0xB, 0xA, 0x2};
170   Value value(blob);
171   EXPECT_EQ(Value::Type::BINARY, value.type());
172   EXPECT_THAT(value.GetIfBlob(), testing::Pointee(blob));
173   EXPECT_EQ(blob, value.GetBlob());
174 }
175 
TEST(ValuesTest,ConstructDict)176 TEST(ValuesTest, ConstructDict) {
177   Value::Dict value;
178   EXPECT_EQ(Value::Type::DICT, Value(std::move(value)).type());
179 }
180 
TEST(ValuesTest,ConstructDictFromValueDict)181 TEST(ValuesTest, ConstructDictFromValueDict) {
182   Value::Dict dict;
183   dict.Set("foo", "bar");
184   {
185     Value value(dict.Clone());
186     EXPECT_EQ(Value::Type::DICT, value.type());
187     EXPECT_TRUE(value.GetIfDict());
188     EXPECT_TRUE(value.GetDict().FindString("foo"));
189     EXPECT_EQ("bar", *value.GetDict().FindString("foo"));
190   }
191 
192   dict.Set("foo", "baz");
193   {
194     Value value(std::move(dict));
195     EXPECT_EQ(Value::Type::DICT, value.type());
196     EXPECT_TRUE(value.GetIfDict());
197     EXPECT_TRUE(value.GetDict().FindString("foo"));
198     EXPECT_EQ("baz", *value.GetDict().FindString("foo"));
199   }
200 }
201 
TEST(ValuesTest,ConstructList)202 TEST(ValuesTest, ConstructList) {
203   Value value(Value::List{});
204   EXPECT_EQ(Value::Type::LIST, value.type());
205 }
206 
TEST(ValuesTest,UseTestingEachOnValueList)207 TEST(ValuesTest, UseTestingEachOnValueList) {
208   Value::List list;
209   list.Append(true);
210   list.Append(true);
211 
212   // This will only work if `Value::List::value_type` is defined.
213   EXPECT_THAT(list, testing::Each(testing::ResultOf(
214                         [](const Value& value) { return value.GetBool(); },
215                         testing::Eq(true))));
216 }
217 
TEST(ValuesTest,ConstructListFromValueList)218 TEST(ValuesTest, ConstructListFromValueList) {
219   Value::List list;
220   list.Append("foo");
221   {
222     Value value(list.Clone());
223     EXPECT_EQ(Value::Type::LIST, value.type());
224     EXPECT_EQ(1u, value.GetList().size());
225     EXPECT_EQ(Value::Type::STRING, value.GetList()[0].type());
226     EXPECT_EQ("foo", value.GetList()[0].GetString());
227   }
228 
229   list.back() = base::Value("bar");
230   {
231     Value value(std::move(list));
232     EXPECT_EQ(Value::Type::LIST, value.type());
233     EXPECT_EQ(1u, value.GetList().size());
234     EXPECT_EQ(Value::Type::STRING, value.GetList()[0].type());
235     EXPECT_EQ("bar", value.GetList()[0].GetString());
236   }
237 }
238 
TEST(ValuesTest,HardenTests)239 TEST(ValuesTest, HardenTests) {
240   Value value;
241   ASSERT_EQ(value.type(), Value::Type::NONE);
242   EXPECT_DEATH_IF_SUPPORTED(value.GetBool(), "");
243   EXPECT_DEATH_IF_SUPPORTED(value.GetInt(), "");
244   EXPECT_DEATH_IF_SUPPORTED(value.GetDouble(), "");
245   EXPECT_DEATH_IF_SUPPORTED(value.GetString(), "");
246   EXPECT_DEATH_IF_SUPPORTED(value.GetBlob(), "");
247 }
248 
249 // Group of tests for the copy constructors and copy-assigmnent. For equality
250 // checks comparisons of the interesting fields are done instead of relying on
251 // Equals being correct.
TEST(ValuesTest,CopyBool)252 TEST(ValuesTest, CopyBool) {
253   Value true_value(true);
254   Value copied_true_value(true_value.Clone());
255   EXPECT_EQ(true_value.type(), copied_true_value.type());
256   EXPECT_EQ(true_value.GetBool(), copied_true_value.GetBool());
257 
258   Value false_value(false);
259   Value copied_false_value(false_value.Clone());
260   EXPECT_EQ(false_value.type(), copied_false_value.type());
261   EXPECT_EQ(false_value.GetBool(), copied_false_value.GetBool());
262 
263   Value blank;
264 
265   blank = true_value.Clone();
266   EXPECT_EQ(true_value.type(), blank.type());
267   EXPECT_EQ(true_value.GetBool(), blank.GetBool());
268 
269   blank = false_value.Clone();
270   EXPECT_EQ(false_value.type(), blank.type());
271   EXPECT_EQ(false_value.GetBool(), blank.GetBool());
272 }
273 
TEST(ValuesTest,CopyInt)274 TEST(ValuesTest, CopyInt) {
275   Value value(74);
276   Value copied_value(value.Clone());
277   EXPECT_EQ(value.type(), copied_value.type());
278   EXPECT_EQ(value.GetInt(), copied_value.GetInt());
279 
280   Value blank;
281 
282   blank = value.Clone();
283   EXPECT_EQ(value.type(), blank.type());
284   EXPECT_EQ(value.GetInt(), blank.GetInt());
285 }
286 
TEST(ValuesTest,CopyDouble)287 TEST(ValuesTest, CopyDouble) {
288   Value value(74.896);
289   Value copied_value(value.Clone());
290   EXPECT_EQ(value.type(), copied_value.type());
291   EXPECT_EQ(value.GetDouble(), copied_value.GetDouble());
292 
293   Value blank;
294 
295   blank = value.Clone();
296   EXPECT_EQ(value.type(), blank.type());
297   EXPECT_EQ(value.GetDouble(), blank.GetDouble());
298 }
299 
TEST(ValuesTest,CopyString)300 TEST(ValuesTest, CopyString) {
301   Value value("foobar");
302   Value copied_value(value.Clone());
303   EXPECT_EQ(value.type(), copied_value.type());
304   EXPECT_EQ(value.GetString(), copied_value.GetString());
305 
306   Value blank;
307 
308   blank = value.Clone();
309   EXPECT_EQ(value.type(), blank.type());
310   EXPECT_EQ(value.GetString(), blank.GetString());
311 }
312 
TEST(ValuesTest,CopyBinary)313 TEST(ValuesTest, CopyBinary) {
314   Value value(Value::BlobStorage({0xF, 0x0, 0x0, 0xB, 0xA, 0x2}));
315   Value copied_value(value.Clone());
316   EXPECT_EQ(value.type(), copied_value.type());
317   EXPECT_EQ(value.GetBlob(), copied_value.GetBlob());
318 
319   Value blank;
320 
321   blank = value.Clone();
322   EXPECT_EQ(value.type(), blank.type());
323   EXPECT_EQ(value.GetBlob(), blank.GetBlob());
324 }
325 
TEST(ValuesTest,CopyDictionary)326 TEST(ValuesTest, CopyDictionary) {
327   Value::Dict dict;
328   dict.Set("Int", 123);
329   Value value(std::move(dict));
330 
331   Value copied_value(value.Clone());
332   EXPECT_EQ(value, copied_value);
333 
334   Value blank;
335   blank = value.Clone();
336   EXPECT_EQ(value, blank);
337 }
338 
TEST(ValuesTest,CopyList)339 TEST(ValuesTest, CopyList) {
340   Value::List list;
341   list.Append(123);
342   Value value(std::move(list));
343 
344   Value copied_value(value.Clone());
345   EXPECT_EQ(value, copied_value);
346 
347   Value blank;
348   blank = value.Clone();
349   EXPECT_EQ(value, blank);
350 }
351 
352 // Group of tests for the move constructors and move-assigmnent.
TEST(ValuesTest,MoveBool)353 TEST(ValuesTest, MoveBool) {
354   Value true_value(true);
355   Value moved_true_value(std::move(true_value));
356   EXPECT_EQ(Value::Type::BOOLEAN, moved_true_value.type());
357   EXPECT_TRUE(moved_true_value.GetBool());
358 
359   Value false_value(false);
360   Value moved_false_value(std::move(false_value));
361   EXPECT_EQ(Value::Type::BOOLEAN, moved_false_value.type());
362   EXPECT_FALSE(moved_false_value.GetBool());
363 
364   Value blank;
365 
366   blank = Value(true);
367   EXPECT_EQ(Value::Type::BOOLEAN, blank.type());
368   EXPECT_TRUE(blank.GetBool());
369 
370   blank = Value(false);
371   EXPECT_EQ(Value::Type::BOOLEAN, blank.type());
372   EXPECT_FALSE(blank.GetBool());
373 }
374 
TEST(ValuesTest,MoveInt)375 TEST(ValuesTest, MoveInt) {
376   Value value(74);
377   Value moved_value(std::move(value));
378   EXPECT_EQ(Value::Type::INTEGER, moved_value.type());
379   EXPECT_EQ(74, moved_value.GetInt());
380 
381   Value blank;
382 
383   blank = Value(47);
384   EXPECT_EQ(Value::Type::INTEGER, blank.type());
385   EXPECT_EQ(47, blank.GetInt());
386 }
387 
TEST(ValuesTest,MoveDouble)388 TEST(ValuesTest, MoveDouble) {
389   Value value(74.896);
390   Value moved_value(std::move(value));
391   EXPECT_EQ(Value::Type::DOUBLE, moved_value.type());
392   EXPECT_EQ(74.896, moved_value.GetDouble());
393 
394   Value blank;
395 
396   blank = Value(654.38);
397   EXPECT_EQ(Value::Type::DOUBLE, blank.type());
398   EXPECT_EQ(654.38, blank.GetDouble());
399 }
400 
TEST(ValuesTest,MoveString)401 TEST(ValuesTest, MoveString) {
402   Value value("foobar");
403   Value moved_value(std::move(value));
404   EXPECT_EQ(Value::Type::STRING, moved_value.type());
405   EXPECT_EQ("foobar", moved_value.GetString());
406 
407   Value blank;
408 
409   blank = Value("foobar");
410   EXPECT_EQ(Value::Type::STRING, blank.type());
411   EXPECT_EQ("foobar", blank.GetString());
412 }
413 
TEST(ValuesTest,MoveBinary)414 TEST(ValuesTest, MoveBinary) {
415   const Value::BlobStorage buffer = {0xF, 0x0, 0x0, 0xB, 0xA, 0x2};
416   Value value(buffer);
417   Value moved_value(std::move(value));
418   EXPECT_EQ(Value::Type::BINARY, moved_value.type());
419   EXPECT_EQ(buffer, moved_value.GetBlob());
420 
421   Value blank;
422 
423   blank = Value(buffer);
424   EXPECT_EQ(Value::Type::BINARY, blank.type());
425   EXPECT_EQ(buffer, blank.GetBlob());
426 }
427 
TEST(ValuesTest,MoveConstructDictionary)428 TEST(ValuesTest, MoveConstructDictionary) {
429   Value::Dict dict;
430   dict.Set("Int", 123);
431 
432   Value value(std::move(dict));
433   Value moved_value(std::move(value));
434   EXPECT_EQ(Value::Type::DICT, moved_value.type());
435   EXPECT_EQ(123, moved_value.GetDict().Find("Int")->GetInt());
436 }
437 
TEST(ValuesTest,MoveAssignDictionary)438 TEST(ValuesTest, MoveAssignDictionary) {
439   Value::Dict dict;
440   dict.Set("Int", 123);
441 
442   Value blank;
443   blank = Value(std::move(dict));
444   EXPECT_EQ(Value::Type::DICT, blank.type());
445   EXPECT_EQ(123, blank.GetDict().Find("Int")->GetInt());
446 }
447 
TEST(ValuesTest,ConstructDictWithIterators)448 TEST(ValuesTest, ConstructDictWithIterators) {
449   std::vector<std::pair<std::string, Value>> values;
450   values.emplace_back(std::make_pair("Int", 123));
451 
452   Value blank;
453   blank = Value(Value::Dict(std::make_move_iterator(values.begin()),
454                             std::make_move_iterator(values.end())));
455   EXPECT_EQ(Value::Type::DICT, blank.type());
456   EXPECT_EQ(123, blank.GetDict().Find("Int")->GetInt());
457 }
458 
TEST(ValuesTest,MoveList)459 TEST(ValuesTest, MoveList) {
460   Value::List list;
461   list.Append(123);
462   Value value(list.Clone());
463   Value moved_value(std::move(value));
464   EXPECT_EQ(Value::Type::LIST, moved_value.type());
465   EXPECT_EQ(123, moved_value.GetList().back().GetInt());
466 
467   Value blank;
468   blank = Value(std::move(list));
469   EXPECT_EQ(Value::Type::LIST, blank.type());
470   EXPECT_EQ(123, blank.GetList().back().GetInt());
471 }
472 
TEST(ValuesTest,Append)473 TEST(ValuesTest, Append) {
474   Value::List list;
475   list.Append(true);
476   EXPECT_TRUE(list.back().is_bool());
477 
478   list.Append(123);
479   EXPECT_TRUE(list.back().is_int());
480 
481   list.Append(3.14);
482   EXPECT_TRUE(list.back().is_double());
483 
484   std::string str = "foo";
485   list.Append(str.c_str());
486   EXPECT_TRUE(list.back().is_string());
487 
488   list.Append(StringPiece(str));
489   EXPECT_TRUE(list.back().is_string());
490 
491   list.Append(std::move(str));
492   EXPECT_TRUE(list.back().is_string());
493 
494   std::u16string str16 = u"bar";
495   list.Append(str16.c_str());
496   EXPECT_TRUE(list.back().is_string());
497 
498   list.Append(base::StringPiece16(str16));
499   EXPECT_TRUE(list.back().is_string());
500 
501   list.Append(Value());
502   EXPECT_TRUE(list.back().is_none());
503 
504   list.Append(Value::Dict());
505   EXPECT_TRUE(list.back().is_dict());
506 
507   list.Append(Value::List());
508   EXPECT_TRUE(list.back().is_list());
509 }
510 
TEST(ValuesTest,ListInsert)511 TEST(ValuesTest, ListInsert) {
512   Value::List list;
513   const Value::List& const_list = list;
514 
515   auto iter = list.Insert(list.end(), Value(true));
516   EXPECT_TRUE(list.begin() == iter);
517   EXPECT_EQ(*iter, true);
518 
519   iter = list.Insert(const_list.begin(), Value(123));
520   EXPECT_TRUE(const_list.begin() == iter);
521   EXPECT_EQ(*iter, 123);
522 
523   iter = list.Insert(list.begin() + 1, Value("Hello world!"));
524   EXPECT_TRUE(list.begin() + 1 == iter);
525   EXPECT_EQ(*iter, "Hello world!");
526 }
527 
TEST(ValuesTest,ListResize)528 TEST(ValuesTest, ListResize) {
529   auto list = base::Value::List().Append("Hello world!");
530   EXPECT_EQ(list.size(), 1U);
531 
532   list.resize(2);
533   // Adds an empty entry to the back to match the size.
534   EXPECT_EQ(list.size(), 2U);
535   EXPECT_TRUE(list[0].is_string());
536   EXPECT_TRUE(list[1].is_none());
537 
538   list.resize(1);
539   // Shrinks the list and kicks the new entry out.
540   EXPECT_EQ(list.size(), 1U);
541   EXPECT_TRUE(list[0].is_string());
542 
543   list.resize(0);
544   // Removes the remaining entry too.
545   EXPECT_EQ(list.size(), 0U);
546 }
547 
TEST(ValuesTest,ReverseIter)548 TEST(ValuesTest, ReverseIter) {
549   Value::List list;
550   const Value::List& const_list = list;
551 
552   list.Append(Value(true));
553   list.Append(Value(123));
554   list.Append(Value("Hello world!"));
555 
556   auto iter = list.rbegin();
557   EXPECT_TRUE(const_list.rbegin() == iter);
558   EXPECT_EQ(*iter, "Hello world!");
559 
560   ++iter;
561   EXPECT_EQ(*iter, 123);
562 
563   ++iter;
564   EXPECT_EQ(*iter, true);
565 
566   ++iter;
567   EXPECT_TRUE(list.rend() == iter);
568   EXPECT_TRUE(const_list.rend() == iter);
569 }
570 
571 // Test all three behaviors of EnsureDict() (Create a new dict where no
572 // matchining values exist, return an existing dict, create a dict overwriting
573 // a value of another type).
TEST(ValuesTest,DictEnsureDict)574 TEST(ValuesTest, DictEnsureDict) {
575   Value::Dict root;
576 
577   // This call should create a new nested dictionary.
578   Value::Dict* foo_dict = root.EnsureDict("foo");
579   EXPECT_TRUE(foo_dict->empty());
580   foo_dict->Set("a", "b");
581 
582   // This call should retrieve the dictionary created above, rather than
583   // creating a new one.
584   std::string* a_string = root.EnsureDict("foo")->FindString("a");
585   ASSERT_NE(nullptr, a_string);
586   EXPECT_EQ(*a_string, "b");
587 
588   // Use EnsureDict() to overwrite an existing non-dictionary value.
589   root.Set("bar", 3);
590   Value::Dict* bar_dict = root.EnsureDict("bar");
591   EXPECT_TRUE(bar_dict->empty());
592   bar_dict->Set("b", "c");
593 
594   // Test that the above call created a "bar" entry.
595   bar_dict = root.FindDict("bar");
596   ASSERT_NE(nullptr, bar_dict);
597   std::string* b_string = bar_dict->FindString("b");
598   ASSERT_NE(nullptr, b_string);
599   EXPECT_EQ(*b_string, "c");
600 }
601 
602 // Test all three behaviors of EnsureList() (Create a new list where no
603 // matchining value exists, return an existing list, create a list overwriting
604 // a value of another type).
TEST(ValuesTest,DictEnsureList)605 TEST(ValuesTest, DictEnsureList) {
606   Value::Dict root;
607 
608   // This call should create a new list.
609   Value::List* foo_list = root.EnsureList("foo");
610   EXPECT_TRUE(foo_list->empty());
611   foo_list->Append("a");
612 
613   // This call should retrieve the list created above, rather than creating a
614   // new one.
615   foo_list = root.EnsureList("foo");
616   ASSERT_EQ(1u, foo_list->size());
617   EXPECT_EQ((*foo_list)[0], Value("a"));
618 
619   // Use EnsureList() to overwrite an existing non-list value.
620   root.Set("bar", 3);
621   Value::List* bar_list = root.EnsureList("bar");
622   EXPECT_TRUE(bar_list->empty());
623   bar_list->Append("b");
624 
625   // Test that the above call created a "bar" entry.
626   bar_list = root.FindList("bar");
627   ASSERT_NE(nullptr, bar_list);
628   ASSERT_EQ(1u, bar_list->size());
629   EXPECT_EQ((*bar_list)[0], Value("b"));
630 }
631 
632 // TODO(dcheng): Add more tests directly exercising the updated dictionary and
633 // list APIs. For now, most of the updated APIs are tested indirectly via the
634 // legacy APIs that are largely backed by the updated APIs.
TEST(ValuesTest,DictFindByDottedPath)635 TEST(ValuesTest, DictFindByDottedPath) {
636   Value::Dict dict;
637 
638   EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
639 
640   Value::Dict& a_dict = dict.Set("a", Value::Dict())->GetDict();
641   EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
642 
643   Value::Dict& b_dict = a_dict.Set("b", Value::Dict())->GetDict();
644   EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
645 
646   b_dict.Set("c", true);
647   const Value* value = dict.FindByDottedPath("a.b.c");
648   ASSERT_NE(nullptr, value);
649   EXPECT_TRUE(value->GetBool());
650 }
651 
TEST(ValuesTest,DictSetByDottedPath)652 TEST(ValuesTest, DictSetByDottedPath) {
653   Value::Dict dict;
654 
655   Value* c = dict.SetByDottedPath("a.b.c", Value());
656   ASSERT_TRUE(c);
657 
658   Value::Dict* a = dict.FindDict("a");
659   ASSERT_TRUE(a);
660   EXPECT_EQ(1U, a->size());
661 
662   Value::Dict* b = a->FindDict("b");
663   ASSERT_TRUE(b);
664   EXPECT_EQ(1U, b->size());
665 
666   EXPECT_EQ(c, b->Find("c"));
667 }
668 
TEST(ValuesTest,RvalueDictSetByDottedPath)669 TEST(ValuesTest, RvalueDictSetByDottedPath) {
670   Value::Dict dict =
671       Value::Dict()
672           .SetByDottedPath("nested.dictionary.null", Value())
673           .SetByDottedPath("nested.dictionary.bool", false)
674           .SetByDottedPath("nested.dictionary.int", 42)
675           .SetByDottedPath("nested.dictionary.double", 1.2)
676           .SetByDottedPath("nested.dictionary.string", "value")
677           .SetByDottedPath("nested.dictionary.u16-string", u"u16-value")
678           .SetByDottedPath("nested.dictionary.std-string",
679                            std::string("std-value"))
680           .SetByDottedPath("nested.dictionary.blob", Value::BlobStorage({1, 2}))
681           .SetByDottedPath("nested.dictionary.list",
682                            Value::List().Append("value in list"))
683           .SetByDottedPath("nested.dictionary.dict",
684                            Value::Dict().Set("key", "value"));
685 
686   Value::Dict expected =
687       Value::Dict()  //
688           .Set("nested",
689                base::Value::Dict()  //
690                    .Set("dictionary",
691                         base::Value::Dict()
692                             .Set("null", Value())
693                             .Set("bool", false)
694                             .Set("int", 42)
695                             .Set("double", 1.2)
696                             .Set("string", "value")
697                             .Set("u16-string", u"u16-value")
698                             .Set("std-string", std::string("std-value"))
699                             .Set("blob", Value::BlobStorage({1, 2}))
700                             .Set("list", Value::List().Append("value in list"))
701                             .Set("dict", Value::Dict().Set("key", "value"))));
702 
703   EXPECT_EQ(dict, expected);
704 }
705 
TEST(ValuesTest,DictSetWithDottedKey)706 TEST(ValuesTest, DictSetWithDottedKey) {
707   Value::Dict dict;
708 
709   Value* abc = dict.Set("a.b.c", Value());
710   ASSERT_TRUE(abc);
711 
712   EXPECT_FALSE(dict.FindByDottedPath("a"));
713   EXPECT_FALSE(dict.FindByDottedPath("a.b"));
714   EXPECT_FALSE(dict.FindByDottedPath("a.b.c"));
715 
716   EXPECT_EQ(abc, dict.Find("a.b.c"));
717 }
718 
TEST(ValuesTest,ListFront)719 TEST(ValuesTest, ListFront) {
720   Value::List list;
721   const Value::List& const_list = list;
722 
723   list.Append(1);
724   list.Append(2);
725   list.Append(3);
726 
727   EXPECT_EQ(Value(1), list.front());
728   EXPECT_EQ(Value(1), const_list.front());
729 }
730 
TEST(ValuesTest,ListFrontWhenEmpty)731 TEST(ValuesTest, ListFrontWhenEmpty) {
732   Value::List list;
733   const Value::List& const_list = list;
734 
735   EXPECT_CHECK_DEATH(list.front());
736   EXPECT_CHECK_DEATH(const_list.front());
737 }
738 
TEST(ValuesTest,ListBack)739 TEST(ValuesTest, ListBack) {
740   Value::List list;
741   const Value::List& const_list = list;
742 
743   list.Append(1);
744   list.Append(2);
745   list.Append(3);
746 
747   EXPECT_EQ(Value(3), list.back());
748   EXPECT_EQ(Value(3), const_list.back());
749 }
750 
TEST(ValuesTest,ListBackWhenEmpty)751 TEST(ValuesTest, ListBackWhenEmpty) {
752   Value::List list;
753   const Value::List& const_list = list;
754 
755   EXPECT_CHECK_DEATH(list.back());
756   EXPECT_CHECK_DEATH(const_list.back());
757 }
758 
TEST(ValuesTest,ListErase)759 TEST(ValuesTest, ListErase) {
760   Value::List list;
761   list.Append(1);
762   list.Append(2);
763   list.Append(3);
764 
765   auto next_it = list.erase(list.begin() + 1);
766   ASSERT_EQ(2u, list.size());
767   EXPECT_EQ(list[0], Value(1));
768   EXPECT_EQ(list[1], Value(3));
769   EXPECT_EQ(*next_it, Value(3));
770   EXPECT_EQ(next_it + 1, list.end());
771 }
772 
TEST(ValuesTest,ListEraseRange)773 TEST(ValuesTest, ListEraseRange) {
774   Value::List list;
775   list.Append(1);
776   list.Append(2);
777   list.Append(3);
778   list.Append(4);
779 
780   auto next_it = list.erase(list.begin() + 1, list.begin() + 3);
781   ASSERT_EQ(2u, list.size());
782   EXPECT_EQ(list[0], Value(1));
783   EXPECT_EQ(list[1], Value(4));
784   EXPECT_EQ(*next_it, Value(4));
785   EXPECT_EQ(next_it + 1, list.end());
786 
787   next_it = list.erase(list.begin() + 1, list.begin() + 1);
788   ASSERT_EQ(2u, list.size());
789   EXPECT_EQ(list[0], Value(1));
790   EXPECT_EQ(list[1], Value(4));
791   EXPECT_EQ(*next_it, Value(4));
792   EXPECT_EQ(next_it + 1, list.end());
793 
794   next_it = list.erase(list.begin() + 1, list.end());
795   ASSERT_EQ(1u, list.size());
796   EXPECT_EQ(list[0], Value(1));
797   EXPECT_EQ(next_it, list.end());
798 
799   list.clear();
800   next_it = list.erase(list.begin(), list.begin());
801   ASSERT_EQ(0u, list.size());
802   EXPECT_EQ(next_it, list.begin());
803   EXPECT_EQ(next_it, list.end());
804 }
805 
TEST(ValuesTest,ListEraseValue)806 TEST(ValuesTest, ListEraseValue) {
807   Value::List list;
808   list.Append(1);
809   list.Append(2);
810   list.Append(2);
811   list.Append(3);
812 
813   EXPECT_EQ(2u, list.EraseValue(Value(2)));
814   EXPECT_EQ(2u, list.size());
815   EXPECT_EQ(1, list[0]);
816   EXPECT_EQ(3, list[1]);
817 
818   EXPECT_EQ(1u, list.EraseValue(Value(1)));
819   EXPECT_EQ(1u, list.size());
820   EXPECT_EQ(3, list[0]);
821 
822   EXPECT_EQ(1u, list.EraseValue(Value(3)));
823   EXPECT_TRUE(list.empty());
824 
825   EXPECT_EQ(0u, list.EraseValue(Value(3)));
826 }
827 
TEST(ValuesTest,ListEraseIf)828 TEST(ValuesTest, ListEraseIf) {
829   Value::List list;
830   list.Append(1);
831   list.Append(2);
832   list.Append(2);
833   list.Append(3);
834 
835   EXPECT_EQ(3u, list.EraseIf([](const auto& val) { return val >= Value(2); }));
836   EXPECT_EQ(1u, list.size());
837   EXPECT_EQ(1, list[0]);
838 
839   EXPECT_EQ(1u, list.EraseIf([](const auto& val) { return true; }));
840   EXPECT_TRUE(list.empty());
841 
842   EXPECT_EQ(0u, list.EraseIf([](const auto& val) { return true; }));
843 }
844 
TEST(ValuesTest,ClearList)845 TEST(ValuesTest, ClearList) {
846   Value::List list;
847   list.Append(1);
848   list.Append(2);
849   list.Append(3);
850   EXPECT_EQ(3u, list.size());
851   EXPECT_FALSE(list.empty());
852 
853   list.clear();
854   EXPECT_EQ(0u, list.size());
855   EXPECT_TRUE(list.empty());
856 
857   // list.clear() should be idempotent.
858   list.clear();
859   EXPECT_EQ(0u, list.size());
860   EXPECT_TRUE(list.empty());
861 }
862 
TEST(ValuesTest,FindKey)863 TEST(ValuesTest, FindKey) {
864   Value::Dict dict;
865   dict.Set("foo", "bar");
866   Value value(std::move(dict));
867   EXPECT_NE(nullptr, value.GetDict().Find("foo"));
868   EXPECT_EQ(nullptr, value.GetDict().Find("baz"));
869 }
870 
TEST(ValuesTest,FindKeyChangeValue)871 TEST(ValuesTest, FindKeyChangeValue) {
872   Value::Dict dict;
873   dict.Set("foo", "bar");
874   Value* found = dict.Find("foo");
875   ASSERT_NE(nullptr, found);
876   EXPECT_EQ("bar", found->GetString());
877 
878   *found = Value(123);
879   EXPECT_EQ(123, dict.Find("foo")->GetInt());
880 }
881 
TEST(ValuesTest,FindKeyConst)882 TEST(ValuesTest, FindKeyConst) {
883   Value::Dict dict;
884   dict.Set("foo", "bar");
885   const Value value(std::move(dict));
886   EXPECT_NE(nullptr, value.GetDict().Find("foo"));
887   EXPECT_EQ(nullptr, value.GetDict().Find("baz"));
888 }
889 
TEST(ValuesTest,FindBoolKey)890 TEST(ValuesTest, FindBoolKey) {
891   Value::Dict dict;
892   dict.Set("null", Value());
893   dict.Set("bool", false);
894   dict.Set("int", 0);
895   dict.Set("double", 0.0);
896   dict.Set("string", std::string());
897   dict.Set("blob", Value(Value::BlobStorage()));
898   dict.Set("list", Value::List());
899   dict.Set("dict", Value::Dict());
900 
901   EXPECT_EQ(absl::nullopt, dict.FindBool("null"));
902   EXPECT_NE(absl::nullopt, dict.FindBool("bool"));
903   EXPECT_EQ(absl::nullopt, dict.FindBool("int"));
904   EXPECT_EQ(absl::nullopt, dict.FindBool("double"));
905   EXPECT_EQ(absl::nullopt, dict.FindBool("string"));
906   EXPECT_EQ(absl::nullopt, dict.FindBool("blob"));
907   EXPECT_EQ(absl::nullopt, dict.FindBool("list"));
908   EXPECT_EQ(absl::nullopt, dict.FindBool("dict"));
909 }
910 
TEST(ValuesTest,FindIntKey)911 TEST(ValuesTest, FindIntKey) {
912   Value::Dict dict;
913   dict.Set("null", Value());
914   dict.Set("bool", false);
915   dict.Set("int", 0);
916   dict.Set("double", 0.0);
917   dict.Set("string", std::string());
918   dict.Set("blob", Value(Value::BlobStorage()));
919   dict.Set("list", Value::List());
920   dict.Set("dict", Value::Dict());
921 
922   EXPECT_EQ(absl::nullopt, dict.FindInt("null"));
923   EXPECT_EQ(absl::nullopt, dict.FindInt("bool"));
924   EXPECT_NE(absl::nullopt, dict.FindInt("int"));
925   EXPECT_EQ(absl::nullopt, dict.FindInt("double"));
926   EXPECT_EQ(absl::nullopt, dict.FindInt("string"));
927   EXPECT_EQ(absl::nullopt, dict.FindInt("blob"));
928   EXPECT_EQ(absl::nullopt, dict.FindInt("list"));
929   EXPECT_EQ(absl::nullopt, dict.FindInt("dict"));
930 }
931 
TEST(ValuesTest,FindStringKey)932 TEST(ValuesTest, FindStringKey) {
933   Value::Dict dict;
934   dict.Set("null", Value());
935   dict.Set("bool", false);
936   dict.Set("int", 0);
937   dict.Set("double", 0.0);
938   dict.Set("string", std::string());
939   dict.Set("blob", Value(Value::BlobStorage()));
940   dict.Set("list", Value::List());
941   dict.Set("dict", Value::Dict());
942 
943   EXPECT_EQ(nullptr, dict.FindString("null"));
944   EXPECT_EQ(nullptr, dict.FindString("bool"));
945   EXPECT_EQ(nullptr, dict.FindString("int"));
946   EXPECT_EQ(nullptr, dict.FindString("double"));
947   EXPECT_NE(nullptr, dict.FindString("string"));
948   EXPECT_EQ(nullptr, dict.FindString("blob"));
949   EXPECT_EQ(nullptr, dict.FindString("list"));
950   EXPECT_EQ(nullptr, dict.FindString("dict"));
951 }
952 
TEST(ValuesTest,MutableFindStringKey)953 TEST(ValuesTest, MutableFindStringKey) {
954   Value::Dict dict;
955   dict.Set("string", "foo");
956 
957   *(dict.FindString("string")) = "bar";
958 
959   Value::Dict expected_dict;
960   expected_dict.Set("string", "bar");
961 
962   EXPECT_EQ(expected_dict, dict);
963 
964   Value value(std::move(dict));
965   Value expected_value(std::move(expected_dict));
966   EXPECT_EQ(expected_value, value);
967 }
968 
TEST(ValuesTest,FindDictKey)969 TEST(ValuesTest, FindDictKey) {
970   Value::Dict dict;
971   dict.Set("null", Value());
972   dict.Set("bool", false);
973   dict.Set("int", 0);
974   dict.Set("double", 0.0);
975   dict.Set("string", std::string());
976   dict.Set("blob", Value(Value::BlobStorage()));
977   dict.Set("list", Value::List());
978   dict.Set("dict", Value::Dict());
979 
980   EXPECT_EQ(nullptr, dict.FindDict("null"));
981   EXPECT_EQ(nullptr, dict.FindDict("bool"));
982   EXPECT_EQ(nullptr, dict.FindDict("int"));
983   EXPECT_EQ(nullptr, dict.FindDict("double"));
984   EXPECT_EQ(nullptr, dict.FindDict("string"));
985   EXPECT_EQ(nullptr, dict.FindDict("blob"));
986   EXPECT_EQ(nullptr, dict.FindDict("list"));
987   EXPECT_NE(nullptr, dict.FindDict("dict"));
988 }
989 
TEST(ValuesTest,FindListKey)990 TEST(ValuesTest, FindListKey) {
991   Value::Dict dict;
992   dict.Set("null", Value());
993   dict.Set("bool", false);
994   dict.Set("int", 0);
995   dict.Set("double", 0.0);
996   dict.Set("string", std::string());
997   dict.Set("blob", Value(Value::BlobStorage()));
998   dict.Set("list", Value::List());
999   dict.Set("dict", Value::Dict());
1000 
1001   EXPECT_EQ(nullptr, dict.FindList("null"));
1002   EXPECT_EQ(nullptr, dict.FindList("bool"));
1003   EXPECT_EQ(nullptr, dict.FindList("int"));
1004   EXPECT_EQ(nullptr, dict.FindList("double"));
1005   EXPECT_EQ(nullptr, dict.FindList("string"));
1006   EXPECT_EQ(nullptr, dict.FindList("blob"));
1007   EXPECT_NE(nullptr, dict.FindList("list"));
1008   EXPECT_EQ(nullptr, dict.FindList("dict"));
1009 }
1010 
TEST(ValuesTest,FindBlob)1011 TEST(ValuesTest, FindBlob) {
1012   Value::Dict dict;
1013   dict.Set("null", Value());
1014   dict.Set("bool", false);
1015   dict.Set("int", 0);
1016   dict.Set("double", 0.0);
1017   dict.Set("string", std::string());
1018   dict.Set("blob", Value(Value::BlobStorage()));
1019   dict.Set("list", Value::List());
1020   dict.Set("dict", Value::Dict());
1021 
1022   EXPECT_EQ(nullptr, dict.FindBlob("null"));
1023   EXPECT_EQ(nullptr, dict.FindBlob("bool"));
1024   EXPECT_EQ(nullptr, dict.FindBlob("int"));
1025   EXPECT_EQ(nullptr, dict.FindBlob("double"));
1026   EXPECT_EQ(nullptr, dict.FindBlob("string"));
1027   EXPECT_NE(nullptr, dict.FindBlob("blob"));
1028   EXPECT_EQ(nullptr, dict.FindBlob("list"));
1029   EXPECT_EQ(nullptr, dict.FindBlob("dict"));
1030 }
1031 
TEST(ValuesTest,SetKey)1032 TEST(ValuesTest, SetKey) {
1033   Value::Dict dict;
1034   dict.Set("null", Value());
1035   dict.Set("bool", false);
1036   dict.Set("int", 0);
1037   dict.Set("double", 0.0);
1038   dict.Set("string", std::string());
1039   dict.Set("blob", Value(Value::BlobStorage()));
1040   dict.Set("list", Value::List());
1041   dict.Set("dict", Value::Dict());
1042 
1043   Value::Dict dict2;
1044   dict2.Set(StringPiece("null"), Value(Value::Type::NONE));
1045   dict2.Set(StringPiece("bool"), Value(Value::Type::BOOLEAN));
1046   dict2.Set(std::string("int"), Value(Value::Type::INTEGER));
1047   dict2.Set(std::string("double"), Value(Value::Type::DOUBLE));
1048   dict2.Set(std::string("string"), Value(Value::Type::STRING));
1049   dict2.Set("blob", Value(Value::Type::BINARY));
1050   dict2.Set("list", Value(Value::Type::LIST));
1051   dict2.Set("dict", Value(Value::Type::DICT));
1052 
1053   EXPECT_EQ(dict, dict2);
1054   EXPECT_EQ(Value(std::move(dict)), Value(std::move(dict2)));
1055 }
1056 
TEST(ValuesTest,SetBoolKey)1057 TEST(ValuesTest, SetBoolKey) {
1058   absl::optional<bool> value;
1059 
1060   Value::Dict dict;
1061   dict.Set("true_key", true);
1062   dict.Set("false_key", false);
1063 
1064   value = dict.FindBool("true_key");
1065   ASSERT_TRUE(value);
1066   ASSERT_TRUE(*value);
1067 
1068   value = dict.FindBool("false_key");
1069   ASSERT_TRUE(value);
1070   ASSERT_FALSE(*value);
1071 
1072   value = dict.FindBool("missing_key");
1073   ASSERT_FALSE(value);
1074 }
1075 
TEST(ValuesTest,SetIntKey)1076 TEST(ValuesTest, SetIntKey) {
1077   absl::optional<int> value;
1078 
1079   Value::Dict dict;
1080   dict.Set("one_key", 1);
1081   dict.Set("minus_one_key", -1);
1082 
1083   value = dict.FindInt("one_key");
1084   ASSERT_TRUE(value);
1085   ASSERT_EQ(1, *value);
1086 
1087   value = dict.FindInt("minus_one_key");
1088   ASSERT_TRUE(value);
1089   ASSERT_EQ(-1, *value);
1090 
1091   value = dict.FindInt("missing_key");
1092   ASSERT_FALSE(value);
1093 }
1094 
TEST(ValuesTest,SetDoubleKey)1095 TEST(ValuesTest, SetDoubleKey) {
1096   Value::Dict dict;
1097   dict.Set("one_key", 1.0);
1098   dict.Set("minus_one_key", -1.0);
1099   dict.Set("pi_key", 3.1415);
1100 
1101   const Value* value;
1102 
1103   value = dict.Find("one_key");
1104   ASSERT_TRUE(value);
1105   EXPECT_TRUE(value->is_double());
1106   EXPECT_EQ(1.0, value->GetDouble());
1107 
1108   value = dict.Find("minus_one_key");
1109   ASSERT_TRUE(value);
1110   EXPECT_TRUE(value->is_double());
1111   EXPECT_EQ(-1.0, value->GetDouble());
1112 
1113   value = dict.Find("pi_key");
1114   ASSERT_TRUE(value);
1115   EXPECT_TRUE(value->is_double());
1116   EXPECT_EQ(3.1415, value->GetDouble());
1117 }
1118 
TEST(ValuesTest,SetStringKey)1119 TEST(ValuesTest, SetStringKey) {
1120   Value::Dict dict;
1121   dict.Set("one_key", "one");
1122   dict.Set("hello_key", "hello world");
1123 
1124   std::string movable_value("movable_value");
1125   dict.Set("movable_key", std::move(movable_value));
1126   ASSERT_TRUE(movable_value.empty());
1127 
1128   const std::string* value;
1129 
1130   value = dict.FindString("one_key");
1131   ASSERT_TRUE(value);
1132   ASSERT_EQ("one", *value);
1133 
1134   value = dict.FindString("hello_key");
1135   ASSERT_TRUE(value);
1136   ASSERT_EQ("hello world", *value);
1137 
1138   value = dict.FindString("movable_key");
1139   ASSERT_TRUE(value);
1140   ASSERT_EQ("movable_value", *value);
1141 
1142   value = dict.FindString("missing_key");
1143   ASSERT_FALSE(value);
1144 }
1145 
TEST(ValuesTest,RvalueSet)1146 TEST(ValuesTest, RvalueSet) {
1147   Value::Dict dict = Value::Dict()
1148                          .Set("null", Value())
1149                          .Set("bool", false)
1150                          .Set("int", 42)
1151                          .Set("double", 1.2)
1152                          .Set("string", "value")
1153                          .Set("u16-string", u"u16-value")
1154                          .Set("std-string", std::string("std-value"))
1155                          .Set("blob", Value::BlobStorage({1, 2}))
1156                          .Set("list", Value::List().Append("value in list"))
1157                          .Set("dict", Value::Dict().Set("key", "value"));
1158 
1159   Value::Dict expected;
1160   expected.Set("null", Value());
1161   expected.Set("bool", false);
1162   expected.Set("int", 42);
1163   expected.Set("double", 1.2);
1164   expected.Set("string", "value");
1165   expected.Set("u16-string", u"u16-value");
1166   expected.Set("std-string", std::string("std-value"));
1167   expected.Set("blob", Value::BlobStorage({1, 2}));
1168   Value::List nested_list;
1169   nested_list.Append("value in list");
1170   expected.Set("list", std::move(nested_list));
1171   Value::Dict nested_dict;
1172   nested_dict.Set("key", "value");
1173   expected.Set("dict", std::move(nested_dict));
1174 
1175   EXPECT_EQ(dict, expected);
1176 }
1177 
TEST(ValuesTest,FindPath)1178 TEST(ValuesTest, FindPath) {
1179   // Construct a dictionary path {root}.foo.bar = 123
1180   Value::Dict foo;
1181   foo.Set("bar", Value(123));
1182 
1183   Value::Dict root;
1184   root.Set("foo", std::move(foo));
1185 
1186   // Double key, second not found.
1187   Value* found = root.FindByDottedPath("foo.notfound");
1188   EXPECT_FALSE(found);
1189 
1190   // Double key, found.
1191   found = root.FindByDottedPath("foo.bar");
1192   EXPECT_TRUE(found);
1193   EXPECT_TRUE(found->is_int());
1194   EXPECT_EQ(123, found->GetInt());
1195 }
1196 
TEST(ValuesTest,SetByDottedPath)1197 TEST(ValuesTest, SetByDottedPath) {
1198   Value::Dict root;
1199 
1200   Value* inserted = root.SetByDottedPath("one.two", Value(123));
1201   Value* found = root.FindByDottedPath("one.two");
1202   ASSERT_TRUE(found);
1203   EXPECT_EQ(found->type(), Value::Type::INTEGER);
1204   EXPECT_EQ(inserted, found);
1205   EXPECT_EQ(123, found->GetInt());
1206 
1207   inserted = root.SetByDottedPath("foo.bar", Value(123));
1208   found = root.FindByDottedPath("foo.bar");
1209   ASSERT_TRUE(found);
1210   EXPECT_EQ(found->type(), Value::Type::INTEGER);
1211   EXPECT_EQ(inserted, found);
1212   EXPECT_EQ(123, found->GetInt());
1213 
1214   // Overwrite with a different value.
1215   root.SetByDottedPath("foo.bar", Value("hello"));
1216   found = root.FindByDottedPath("foo.bar");
1217   ASSERT_TRUE(found);
1218   EXPECT_EQ(found->type(), Value::Type::STRING);
1219   EXPECT_EQ("hello", found->GetString());
1220 
1221   // Can't change existing non-dictionary keys to dictionaries.
1222   found = root.SetByDottedPath("foo.bar.baz", Value(123));
1223   EXPECT_FALSE(found);
1224 }
1225 
TEST(ValuesTest,SetBoolPath)1226 TEST(ValuesTest, SetBoolPath) {
1227   Value::Dict root;
1228   Value* inserted = root.SetByDottedPath("foo.bar", true);
1229   Value* found = root.FindByDottedPath("foo.bar");
1230   ASSERT_TRUE(found);
1231   EXPECT_EQ(inserted, found);
1232   ASSERT_TRUE(found->is_bool());
1233   EXPECT_TRUE(found->GetBool());
1234 
1235   // Overwrite with a different value.
1236   root.SetByDottedPath("foo.bar", false);
1237   found = root.FindByDottedPath("foo.bar");
1238   ASSERT_TRUE(found);
1239   ASSERT_TRUE(found->is_bool());
1240   EXPECT_FALSE(found->GetBool());
1241 
1242   // Can't change existing non-dictionary keys.
1243   ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", true));
1244 }
1245 
TEST(ValuesTest,SetIntPath)1246 TEST(ValuesTest, SetIntPath) {
1247   Value::Dict root;
1248   Value* inserted = root.SetByDottedPath("foo.bar", 123);
1249   Value* found = root.FindByDottedPath("foo.bar");
1250   ASSERT_TRUE(found);
1251   EXPECT_EQ(inserted, found);
1252   ASSERT_TRUE(found->is_int());
1253   EXPECT_EQ(123, found->GetInt());
1254 
1255   // Overwrite with a different value.
1256   root.SetByDottedPath("foo.bar", 234);
1257   found = root.FindByDottedPath("foo.bar");
1258   ASSERT_TRUE(found);
1259   ASSERT_TRUE(found->is_int());
1260   EXPECT_EQ(234, found->GetInt());
1261 
1262   // Can't change existing non-dictionary keys.
1263   ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", 567));
1264 }
1265 
TEST(ValuesTest,SetDoublePath)1266 TEST(ValuesTest, SetDoublePath) {
1267   Value::Dict root;
1268   Value* inserted = root.SetByDottedPath("foo.bar", 1.23);
1269   Value* found = root.FindByDottedPath("foo.bar");
1270   ASSERT_TRUE(found);
1271   EXPECT_EQ(inserted, found);
1272   ASSERT_TRUE(found->is_double());
1273   EXPECT_EQ(1.23, found->GetDouble());
1274 
1275   // Overwrite with a different value.
1276   root.SetByDottedPath("foo.bar", 2.34);
1277   found = root.FindByDottedPath("foo.bar");
1278   ASSERT_TRUE(found);
1279   ASSERT_TRUE(found->is_double());
1280   EXPECT_EQ(2.34, found->GetDouble());
1281 
1282   // Can't change existing non-dictionary keys.
1283   ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", 5.67));
1284 }
1285 
TEST(ValuesTest,SetStringPath)1286 TEST(ValuesTest, SetStringPath) {
1287   Value::Dict root;
1288   Value* inserted = root.SetByDottedPath("foo.bar", "hello world");
1289   Value* found = root.FindByDottedPath("foo.bar");
1290   ASSERT_TRUE(found);
1291   EXPECT_EQ(inserted, found);
1292   ASSERT_TRUE(found->is_string());
1293   EXPECT_EQ("hello world", found->GetString());
1294 
1295   // Overwrite with a different value.
1296   root.SetByDottedPath("foo.bar", "bonjour monde");
1297   found = root.FindByDottedPath("foo.bar");
1298   ASSERT_TRUE(found);
1299   ASSERT_TRUE(found->is_string());
1300   EXPECT_EQ("bonjour monde", found->GetString());
1301 
1302   ASSERT_TRUE(root.SetByDottedPath("foo.bar", StringPiece("rah rah")));
1303   ASSERT_TRUE(root.SetByDottedPath("foo.bar", std::string("temp string")));
1304   ASSERT_TRUE(root.SetByDottedPath("foo.bar", u"temp string"));
1305 
1306   // Can't change existing non-dictionary keys.
1307   ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", "ola mundo"));
1308 }
1309 
TEST(ValuesTest,Remove)1310 TEST(ValuesTest, Remove) {
1311   Value::Dict root;
1312   root.Set("one", Value(123));
1313 
1314   // Removal of missing key should fail.
1315   EXPECT_FALSE(root.Remove("two"));
1316 
1317   // Removal of existing key should succeed.
1318   EXPECT_TRUE(root.Remove("one"));
1319 
1320   // Second removal of previously existing key should fail.
1321   EXPECT_FALSE(root.Remove("one"));
1322 }
1323 
TEST(ValuesTest,Extract)1324 TEST(ValuesTest, Extract) {
1325   Value::Dict root;
1326   root.Set("one", Value(123));
1327 
1328   // Extraction of missing key should fail.
1329   EXPECT_EQ(absl::nullopt, root.Extract("two"));
1330 
1331   // Extraction of existing key should succeed.
1332   EXPECT_EQ(Value(123), root.Extract("one"));
1333 
1334   // Second extraction of previously existing key should fail.
1335   EXPECT_EQ(absl::nullopt, root.Extract("one"));
1336 }
1337 
TEST(ValuesTest,RemoveByDottedPath)1338 TEST(ValuesTest, RemoveByDottedPath) {
1339   Value::Dict root;
1340   root.SetByDottedPath("one.two.three", Value(123));
1341 
1342   // Removal of missing key should fail.
1343   EXPECT_FALSE(root.RemoveByDottedPath("one.two.four"));
1344 
1345   // Removal of existing key should succeed.
1346   EXPECT_TRUE(root.RemoveByDottedPath("one.two.three"));
1347 
1348   // Second removal of previously existing key should fail.
1349   EXPECT_FALSE(root.RemoveByDottedPath("one.two.three"));
1350 
1351   // Intermediate empty dictionaries should be cleared.
1352   EXPECT_EQ(nullptr, root.Find("one"));
1353 
1354   root.SetByDottedPath("one.two.three", Value(123));
1355   root.SetByDottedPath("one.two.four", Value(124));
1356 
1357   EXPECT_TRUE(root.RemoveByDottedPath("one.two.three"));
1358   // Intermediate non-empty dictionaries should be kept.
1359   EXPECT_NE(nullptr, root.Find("one"));
1360   EXPECT_NE(nullptr, root.FindByDottedPath("one.two"));
1361   EXPECT_NE(nullptr, root.FindByDottedPath("one.two.four"));
1362 }
1363 
TEST(ValuesTest,ExtractByDottedPath)1364 TEST(ValuesTest, ExtractByDottedPath) {
1365   Value::Dict root;
1366   root.SetByDottedPath("one.two.three", Value(123));
1367 
1368   // Extraction of missing key should fail.
1369   EXPECT_EQ(absl::nullopt, root.ExtractByDottedPath("one.two.four"));
1370 
1371   // Extraction of existing key should succeed.
1372   EXPECT_EQ(Value(123), root.ExtractByDottedPath("one.two.three"));
1373 
1374   // Second extraction of previously existing key should fail.
1375   EXPECT_EQ(absl::nullopt, root.ExtractByDottedPath("one.two.three"));
1376 
1377   // Intermediate empty dictionaries should be cleared.
1378   EXPECT_EQ(nullptr, root.Find("one"));
1379 
1380   root.SetByDottedPath("one.two.three", Value(123));
1381   root.SetByDottedPath("one.two.four", Value(124));
1382 
1383   EXPECT_EQ(Value(123), root.ExtractByDottedPath("one.two.three"));
1384   // Intermediate non-empty dictionaries should be kept.
1385   EXPECT_NE(nullptr, root.Find("one"));
1386   EXPECT_NE(nullptr, root.FindByDottedPath("one.two"));
1387   EXPECT_NE(nullptr, root.FindByDottedPath("one.two.four"));
1388 }
1389 
TEST(ValuesTest,Basic)1390 TEST(ValuesTest, Basic) {
1391   // Test basic dictionary getting/setting
1392   Value::Dict settings;
1393   ASSERT_FALSE(settings.FindByDottedPath("global.homepage"));
1394 
1395   ASSERT_FALSE(settings.Find("global"));
1396   settings.Set("global", Value(true));
1397   ASSERT_TRUE(settings.Find("global"));
1398   settings.Remove("global");
1399   settings.SetByDottedPath("global.homepage", Value("http://scurvy.com"));
1400   ASSERT_TRUE(settings.Find("global"));
1401   const std::string* homepage =
1402       settings.FindStringByDottedPath("global.homepage");
1403   ASSERT_TRUE(homepage);
1404   ASSERT_EQ(std::string("http://scurvy.com"), *homepage);
1405 
1406   // Test storing a dictionary in a list.
1407   ASSERT_FALSE(settings.FindByDottedPath("global.toolbar.bookmarks"));
1408 
1409   Value::List new_toolbar_bookmarks;
1410   settings.SetByDottedPath("global.toolbar.bookmarks",
1411                            std::move(new_toolbar_bookmarks));
1412   Value::List* toolbar_bookmarks =
1413       settings.FindListByDottedPath("global.toolbar.bookmarks");
1414   ASSERT_TRUE(toolbar_bookmarks);
1415 
1416   Value::Dict new_bookmark;
1417   new_bookmark.Set("name", Value("Froogle"));
1418   new_bookmark.Set("url", Value("http://froogle.com"));
1419   toolbar_bookmarks->Append(std::move(new_bookmark));
1420 
1421   Value* bookmark_list = settings.FindByDottedPath("global.toolbar.bookmarks");
1422   ASSERT_TRUE(bookmark_list);
1423   ASSERT_EQ(1U, bookmark_list->GetList().size());
1424   Value* bookmark = &bookmark_list->GetList()[0];
1425   ASSERT_TRUE(bookmark);
1426   ASSERT_TRUE(bookmark->is_dict());
1427   const std::string* bookmark_name = bookmark->GetDict().FindString("name");
1428   ASSERT_TRUE(bookmark_name);
1429   ASSERT_EQ(std::string("Froogle"), *bookmark_name);
1430   const std::string* bookmark_url = bookmark->GetDict().FindString("url");
1431   ASSERT_TRUE(bookmark_url);
1432   ASSERT_EQ(std::string("http://froogle.com"), *bookmark_url);
1433 }
1434 
TEST(ValuesTest,List)1435 TEST(ValuesTest, List) {
1436   Value::List mixed_list;
1437   mixed_list.Append(true);
1438   mixed_list.Append(42);
1439   mixed_list.Append(88.8);
1440   mixed_list.Append("foo");
1441 
1442   ASSERT_EQ(4u, mixed_list.size());
1443 
1444   EXPECT_EQ(true, mixed_list[0]);
1445   EXPECT_EQ(42, mixed_list[1]);
1446   EXPECT_EQ(88.8, mixed_list[2]);
1447   EXPECT_EQ("foo", mixed_list[3]);
1448 
1449   // Try searching in the mixed list.
1450   ASSERT_TRUE(Contains(mixed_list, 42));
1451   ASSERT_FALSE(Contains(mixed_list, false));
1452 }
1453 
TEST(ValuesTest,RvalueAppend)1454 TEST(ValuesTest, RvalueAppend) {
1455   Value::List list = Value::List()
1456                          .Append(Value())
1457                          .Append(false)
1458                          .Append(42)
1459                          .Append(1.2)
1460                          .Append("value")
1461                          .Append(u"u16-value")
1462                          .Append(std::string("std-value"))
1463                          .Append(Value::BlobStorage({1, 2}))
1464                          .Append(Value::List().Append("value in list"))
1465                          .Append(Value::Dict().Set("key", "value"));
1466 
1467   Value::List expected;
1468   expected.Append(Value());
1469   expected.Append(false);
1470   expected.Append(42);
1471   expected.Append(1.2);
1472   expected.Append("value");
1473   expected.Append(u"u16-value");
1474   expected.Append(std::string("std-value"));
1475   expected.Append(Value::BlobStorage({1, 2}));
1476   Value::List nested_list;
1477   nested_list.Append("value in list");
1478   expected.Append(std::move(nested_list));
1479   Value::Dict nested_dict;
1480   nested_dict.Set("key", "value");
1481   expected.Append(std::move(nested_dict));
1482 
1483   EXPECT_EQ(list, expected);
1484 }
1485 
TEST(ValuesTest,ListWithCapacity)1486 TEST(ValuesTest, ListWithCapacity) {
1487   Value::List list_with_capacity =
1488       Value::List::with_capacity(3).Append(true).Append(42).Append(88.8);
1489 
1490   ASSERT_EQ(3u, list_with_capacity.size());
1491 }
1492 
TEST(ValuesTest,BinaryValue)1493 TEST(ValuesTest, BinaryValue) {
1494   // Default constructor creates a BinaryValue with a buffer of size 0.
1495   Value binary(Value::Type::BINARY);
1496   ASSERT_TRUE(binary.GetBlob().empty());
1497 
1498   // Test the common case of a non-empty buffer
1499   Value::BlobStorage buffer(15);
1500   uint8_t* original_buffer = buffer.data();
1501   binary = Value(std::move(buffer));
1502   ASSERT_TRUE(binary.GetBlob().data());
1503   ASSERT_EQ(original_buffer, binary.GetBlob().data());
1504   ASSERT_EQ(15U, binary.GetBlob().size());
1505 
1506   char stack_buffer[42];
1507   memset(stack_buffer, '!', 42);
1508   binary = Value(Value::BlobStorage(stack_buffer, stack_buffer + 42));
1509   ASSERT_TRUE(binary.GetBlob().data());
1510   ASSERT_NE(stack_buffer,
1511             reinterpret_cast<const char*>(binary.GetBlob().data()));
1512   ASSERT_EQ(42U, binary.GetBlob().size());
1513   ASSERT_EQ(0, memcmp(stack_buffer, binary.GetBlob().data(),
1514                       binary.GetBlob().size()));
1515 }
1516 
TEST(ValuesTest,StringValue)1517 TEST(ValuesTest, StringValue) {
1518   // Test overloaded StringValue constructor.
1519   std::unique_ptr<Value> narrow_value(new Value("narrow"));
1520   ASSERT_TRUE(narrow_value.get());
1521   ASSERT_TRUE(narrow_value->is_string());
1522   std::unique_ptr<Value> utf16_value(new Value(u"utf16"));
1523   ASSERT_TRUE(utf16_value.get());
1524   ASSERT_TRUE(utf16_value->is_string());
1525 
1526   ASSERT_TRUE(narrow_value->is_string());
1527   ASSERT_EQ(std::string("narrow"), narrow_value->GetString());
1528 
1529   ASSERT_TRUE(utf16_value->is_string());
1530   ASSERT_EQ(std::string("utf16"), utf16_value->GetString());
1531 }
1532 
TEST(ValuesTest,DictionaryDeletion)1533 TEST(ValuesTest, DictionaryDeletion) {
1534   std::string key = "test";
1535   Value::Dict dict;
1536   dict.Set(key, Value());
1537   EXPECT_FALSE(dict.empty());
1538   EXPECT_EQ(1U, dict.size());
1539   dict.clear();
1540   EXPECT_TRUE(dict.empty());
1541   EXPECT_TRUE(dict.empty());
1542   EXPECT_EQ(0U, dict.size());
1543 }
1544 
TEST(ValuesTest,DictionarySetReturnsPointer)1545 TEST(ValuesTest, DictionarySetReturnsPointer) {
1546   {
1547     Value::Dict dict;
1548     Value* blank_ptr = dict.Set("foo.bar", Value());
1549     EXPECT_EQ(Value::Type::NONE, blank_ptr->type());
1550   }
1551 
1552   {
1553     Value::Dict dict;
1554     Value* blank_ptr = dict.Set("foo.bar", Value());
1555     EXPECT_EQ(Value::Type::NONE, blank_ptr->type());
1556   }
1557 
1558   {
1559     Value::Dict dict;
1560     Value* int_ptr = dict.Set("foo.bar", 42);
1561     EXPECT_EQ(Value::Type::INTEGER, int_ptr->type());
1562     EXPECT_EQ(42, int_ptr->GetInt());
1563   }
1564 
1565   {
1566     Value::Dict dict;
1567     Value* string_ptr = dict.Set("foo.bar", "foo");
1568     EXPECT_EQ(Value::Type::STRING, string_ptr->type());
1569     EXPECT_EQ("foo", string_ptr->GetString());
1570   }
1571 
1572   {
1573     Value::Dict dict;
1574     Value* string16_ptr = dict.Set("foo.bar", u"baz");
1575     EXPECT_EQ(Value::Type::STRING, string16_ptr->type());
1576     EXPECT_EQ("baz", string16_ptr->GetString());
1577   }
1578 
1579   {
1580     Value::Dict dict;
1581     Value* dict_ptr = dict.Set("foo.bar", Value::Dict());
1582     EXPECT_EQ(Value::Type::DICT, dict_ptr->type());
1583   }
1584 
1585   {
1586     Value::Dict dict;
1587     Value* list_ptr = dict.Set("foo.bar", Value::List());
1588     EXPECT_EQ(Value::Type::LIST, list_ptr->type());
1589   }
1590 }
1591 
TEST(ValuesTest,Clone)1592 TEST(ValuesTest, Clone) {
1593   Value original_null;
1594   Value original_bool(true);
1595   Value original_int(42);
1596   Value original_double(3.14);
1597   Value original_string("hello");
1598   Value original_string16(u"hello16");
1599   Value original_binary(Value::BlobStorage(42, '!'));
1600 
1601   Value::List list;
1602   list.Append(0);
1603   list.Append(1);
1604   Value original_list(std::move(list));
1605 
1606   Value original_dict(Value::Dict()
1607                           .Set("null", original_null.Clone())
1608                           .Set("bool", original_bool.Clone())
1609                           .Set("int", original_int.Clone())
1610                           .Set("double", original_double.Clone())
1611                           .Set("string", original_string.Clone())
1612                           .Set("string16", original_string16.Clone())
1613                           .Set("binary", original_binary.Clone())
1614                           .Set("list", original_list.Clone()));
1615 
1616   Value copy_value = original_dict.Clone();
1617   const Value::Dict& copy_dict = copy_value.GetDict();
1618   EXPECT_EQ(original_dict, copy_dict);
1619   EXPECT_EQ(original_null, *copy_dict.Find("null"));
1620   EXPECT_EQ(original_bool, *copy_dict.Find("bool"));
1621   EXPECT_EQ(original_int, *copy_dict.Find("int"));
1622   EXPECT_EQ(original_double, *copy_dict.Find("double"));
1623   EXPECT_EQ(original_string, *copy_dict.Find("string"));
1624   EXPECT_EQ(original_string16, *copy_dict.Find("string16"));
1625   EXPECT_EQ(original_binary, *copy_dict.Find("binary"));
1626   EXPECT_EQ(original_list, *copy_dict.Find("list"));
1627 }
1628 
TEST(ValuesTest,TakeString)1629 TEST(ValuesTest, TakeString) {
1630   Value value("foo");
1631   std::string taken = std::move(value).TakeString();
1632   EXPECT_EQ(taken, "foo");
1633 }
1634 
1635 // Check that the value can still be used after `TakeString()` was called, as
1636 // long as a new value was assigned to it.
TEST(ValuesTest,PopulateAfterTakeString)1637 TEST(ValuesTest, PopulateAfterTakeString) {
1638   Value value("foo");
1639   std::string taken = std::move(value).TakeString();
1640 
1641   value = Value(false);
1642   EXPECT_EQ(value, Value(false));
1643 }
1644 
TEST(ValuesTest,TakeDict)1645 TEST(ValuesTest, TakeDict) {
1646   Value::Dict dict;
1647   dict.Set("foo", 123);
1648   Value value(std::move(dict));
1649   Value clone = value.Clone();
1650 
1651   Value::Dict taken = std::move(value).TakeDict();
1652   EXPECT_EQ(taken, clone);
1653 }
1654 
1655 // Check that the value can still be used after `TakeDict()` was called, as long
1656 // as a new value was assigned to it.
TEST(ValuesTest,PopulateAfterTakeDict)1657 TEST(ValuesTest, PopulateAfterTakeDict) {
1658   Value::Dict dict;
1659   dict.Set("foo", 123);
1660   Value value(std::move(dict));
1661   Value::Dict taken = std::move(value).TakeDict();
1662 
1663   value = Value(false);
1664   EXPECT_EQ(value, Value(false));
1665 }
1666 
TEST(ValuesTest,TakeList)1667 TEST(ValuesTest, TakeList) {
1668   Value::List list;
1669   list.Append(true);
1670   list.Append(123);
1671   Value value(std::move(list));
1672   Value clone = value.Clone();
1673 
1674   Value::List taken = std::move(value).TakeList();
1675   EXPECT_EQ(taken, clone);
1676 }
1677 
1678 // Check that the value can still be used after `TakeList()` was called, as long
1679 // as a new value was assigned to it.
TEST(ValuesTest,PopulateAfterTakeList)1680 TEST(ValuesTest, PopulateAfterTakeList) {
1681   Value::List list;
1682   list.Append("hello");
1683   Value value(std::move(list));
1684   Value::List taken = std::move(value).TakeList();
1685 
1686   value = Value(false);
1687   EXPECT_EQ(value, Value(false));
1688 }
1689 
TEST(ValuesTest,SpecializedEquals)1690 TEST(ValuesTest, SpecializedEquals) {
1691   std::vector<Value> values;
1692   values.emplace_back(false);
1693   values.emplace_back(true);
1694   values.emplace_back(0);
1695   values.emplace_back(1);
1696   values.emplace_back(1.0);
1697   values.emplace_back(2.0);
1698   values.emplace_back("hello");
1699   values.emplace_back("world");
1700   base::Value::Dict dict;
1701   dict.Set("hello", "world");
1702   values.emplace_back(std::move(dict));
1703   base::Value::Dict dict2;
1704   dict2.Set("world", "hello");
1705   values.emplace_back(std::move(dict2));
1706   base::Value::List list;
1707   list.Append("hello");
1708   list.Append("world");
1709   values.emplace_back(std::move(list));
1710   base::Value::List list2;
1711   list2.Append("world");
1712   list2.Append("hello");
1713   values.emplace_back(std::move(list2));
1714 
1715   for (const Value& outer_value : values) {
1716     for (const Value& inner_value : values) {
1717       SCOPED_TRACE(::testing::Message()
1718                    << "Outer: " << outer_value << "Inner: " << inner_value);
1719       const bool should_be_equal = &outer_value == &inner_value;
1720       if (should_be_equal) {
1721         EXPECT_EQ(outer_value, inner_value);
1722         EXPECT_EQ(inner_value, outer_value);
1723         EXPECT_FALSE(outer_value != inner_value);
1724         EXPECT_FALSE(inner_value != outer_value);
1725       } else {
1726         EXPECT_NE(outer_value, inner_value);
1727         EXPECT_NE(inner_value, outer_value);
1728         EXPECT_FALSE(outer_value == inner_value);
1729         EXPECT_FALSE(inner_value == outer_value);
1730       }
1731       // Also test the various overloads for operator== against concrete
1732       // subtypes.
1733       outer_value.Visit([&](const auto& outer_member) {
1734         using T = std::decay_t<decltype(outer_member)>;
1735         if constexpr (!std::is_same_v<T, absl::monostate> &&
1736                       !std::is_same_v<T, Value::BlobStorage>) {
1737           if (should_be_equal) {
1738             EXPECT_EQ(outer_member, inner_value);
1739             EXPECT_EQ(inner_value, outer_member);
1740             EXPECT_FALSE(outer_member != inner_value);
1741             EXPECT_FALSE(inner_value != outer_member);
1742           } else {
1743             EXPECT_NE(outer_member, inner_value);
1744             EXPECT_NE(inner_value, outer_member);
1745             EXPECT_FALSE(outer_member == inner_value);
1746             EXPECT_FALSE(inner_value == outer_member);
1747           }
1748         }
1749       });
1750     }
1751 
1752     // A copy of a Value should also compare equal to itself.
1753     Value copied_value = outer_value.Clone();
1754     EXPECT_EQ(outer_value, copied_value);
1755     EXPECT_EQ(copied_value, outer_value);
1756     EXPECT_FALSE(outer_value != copied_value);
1757     EXPECT_FALSE(copied_value != outer_value);
1758   }
1759 }
1760 
1761 // Test that a literal string comparison does not end up using the bool (!!)
1762 // overload.
TEST(ValuesTest,LiteralStringEquals)1763 TEST(ValuesTest, LiteralStringEquals) {
1764   EXPECT_EQ("hello world", base::Value("hello world"));
1765   EXPECT_EQ(base::Value("hello world"), "hello world");
1766   EXPECT_NE("hello world", base::Value(true));
1767   EXPECT_NE(base::Value(true), "hello world");
1768 }
1769 
TEST(ValuesTest,Equals)1770 TEST(ValuesTest, Equals) {
1771   auto null1 = std::make_unique<Value>();
1772   auto null2 = std::make_unique<Value>();
1773   EXPECT_NE(null1.get(), null2.get());
1774   EXPECT_EQ(*null1, *null2);
1775 
1776   Value boolean(false);
1777   EXPECT_NE(*null1, boolean);
1778 
1779   Value::Dict dv;
1780   dv.Set("a", false);
1781   dv.Set("b", 2);
1782   dv.Set("c", 2.5);
1783   dv.Set("d1", "string");
1784   dv.Set("d2", u"http://google.com");
1785   dv.Set("e", Value());
1786 
1787   Value::Dict copy = dv.Clone();
1788   EXPECT_EQ(dv, copy);
1789 
1790   Value::List list;
1791   list.Append(Value());
1792   list.Append(Value(Value::Type::DICT));
1793   Value::List list_copy(list.Clone());
1794 
1795   Value* list_weak = dv.Set("f", std::move(list));
1796   EXPECT_NE(dv, copy);
1797   copy.Set("f", std::move(list_copy));
1798   EXPECT_EQ(dv, copy);
1799 
1800   list_weak->GetList().Append(true);
1801   EXPECT_NE(dv, copy);
1802 
1803   // Check if Equals detects differences in only the keys.
1804   copy = dv.Clone();
1805   EXPECT_EQ(dv, copy);
1806   copy.Remove("a");
1807   copy.Set("aa", false);
1808   EXPECT_NE(dv, copy);
1809 }
1810 
TEST(ValuesTest,Comparisons)1811 TEST(ValuesTest, Comparisons) {
1812   // Test None Values.
1813   Value null1;
1814   Value null2;
1815   EXPECT_EQ(null1, null2);
1816   EXPECT_FALSE(null1 != null2);
1817   EXPECT_FALSE(null1 < null2);
1818   EXPECT_FALSE(null1 > null2);
1819   EXPECT_LE(null1, null2);
1820   EXPECT_GE(null1, null2);
1821 
1822   // Test Bool Values.
1823   Value bool1(false);
1824   Value bool2(true);
1825   EXPECT_FALSE(bool1 == bool2);
1826   EXPECT_NE(bool1, bool2);
1827   EXPECT_LT(bool1, bool2);
1828   EXPECT_FALSE(bool1 > bool2);
1829   EXPECT_LE(bool1, bool2);
1830   EXPECT_FALSE(bool1 >= bool2);
1831 
1832   // Test Int Values.
1833   Value int1(1);
1834   Value int2(2);
1835   EXPECT_FALSE(int1 == int2);
1836   EXPECT_NE(int1, int2);
1837   EXPECT_LT(int1, int2);
1838   EXPECT_FALSE(int1 > int2);
1839   EXPECT_LE(int1, int2);
1840   EXPECT_FALSE(int1 >= int2);
1841 
1842   // Test Double Values.
1843   Value double1(1.0);
1844   Value double2(2.0);
1845   EXPECT_FALSE(double1 == double2);
1846   EXPECT_NE(double1, double2);
1847   EXPECT_LT(double1, double2);
1848   EXPECT_FALSE(double1 > double2);
1849   EXPECT_LE(double1, double2);
1850   EXPECT_FALSE(double1 >= double2);
1851 
1852   // Test String Values.
1853   Value string1("1");
1854   Value string2("2");
1855   EXPECT_FALSE(string1 == string2);
1856   EXPECT_NE(string1, string2);
1857   EXPECT_LT(string1, string2);
1858   EXPECT_FALSE(string1 > string2);
1859   EXPECT_LE(string1, string2);
1860   EXPECT_FALSE(string1 >= string2);
1861 
1862   // Test Binary Values.
1863   Value binary1(Value::BlobStorage{0x01});
1864   Value binary2(Value::BlobStorage{0x02});
1865   EXPECT_FALSE(binary1 == binary2);
1866   EXPECT_NE(binary1, binary2);
1867   EXPECT_LT(binary1, binary2);
1868   EXPECT_FALSE(binary1 > binary2);
1869   EXPECT_LE(binary1, binary2);
1870   EXPECT_FALSE(binary1 >= binary2);
1871 
1872   // Test Empty List Values.
1873   Value::List null_list1;
1874   Value::List null_list2;
1875   EXPECT_EQ(null_list1, null_list2);
1876   EXPECT_FALSE(null_list1 != null_list2);
1877   EXPECT_FALSE(null_list1 < null_list2);
1878   EXPECT_FALSE(null_list1 > null_list2);
1879   EXPECT_LE(null_list1, null_list2);
1880   EXPECT_GE(null_list1, null_list2);
1881 
1882   // Test Non Empty List Values.
1883   Value::List int_list1;
1884   Value::List int_list2;
1885   int_list1.Append(1);
1886   int_list2.Append(2);
1887   EXPECT_FALSE(int_list1 == int_list2);
1888   EXPECT_NE(int_list1, int_list2);
1889   EXPECT_LT(int_list1, int_list2);
1890   EXPECT_FALSE(int_list1 > int_list2);
1891   EXPECT_LE(int_list1, int_list2);
1892   EXPECT_FALSE(int_list1 >= int_list2);
1893 
1894   // Test Empty Dict Values.
1895   Value::Dict null_dict1;
1896   Value::Dict null_dict2;
1897   EXPECT_EQ(null_dict1, null_dict2);
1898   EXPECT_FALSE(null_dict1 != null_dict2);
1899   EXPECT_FALSE(null_dict1 < null_dict2);
1900   EXPECT_FALSE(null_dict1 > null_dict2);
1901   EXPECT_LE(null_dict1, null_dict2);
1902   EXPECT_GE(null_dict1, null_dict2);
1903 
1904   // Test Non Empty Dict Values.
1905   Value::Dict int_dict1;
1906   Value::Dict int_dict2;
1907   int_dict1.Set("key", 1);
1908   int_dict2.Set("key", 2);
1909   EXPECT_FALSE(int_dict1 == int_dict2);
1910   EXPECT_NE(int_dict1, int_dict2);
1911   EXPECT_LT(int_dict1, int_dict2);
1912   EXPECT_FALSE(int_dict1 > int_dict2);
1913   EXPECT_LE(int_dict1, int_dict2);
1914   EXPECT_FALSE(int_dict1 >= int_dict2);
1915 
1916   // Test Values of different types.
1917   std::vector<Value> values;
1918   values.emplace_back(std::move(null1));
1919   values.emplace_back(std::move(bool1));
1920   values.emplace_back(std::move(int1));
1921   values.emplace_back(std::move(double1));
1922   values.emplace_back(std::move(string1));
1923   values.emplace_back(std::move(binary1));
1924   values.emplace_back(std::move(int_dict1));
1925   values.emplace_back(std::move(int_list1));
1926   for (size_t i = 0; i < values.size(); ++i) {
1927     for (size_t j = i + 1; j < values.size(); ++j) {
1928       EXPECT_FALSE(values[i] == values[j]);
1929       EXPECT_NE(values[i], values[j]);
1930       EXPECT_LT(values[i], values[j]);
1931       EXPECT_FALSE(values[i] > values[j]);
1932       EXPECT_LE(values[i], values[j]);
1933       EXPECT_FALSE(values[i] >= values[j]);
1934     }
1935   }
1936 }
1937 
TEST(ValuesTest,Merge)1938 TEST(ValuesTest, Merge) {
1939   Value::Dict base;
1940   base.Set("base_key", "base_key_value_base");
1941   base.Set("collide_key", "collide_key_value_base");
1942   Value::Dict base_sub_dict;
1943   base_sub_dict.Set("sub_base_key", "sub_base_key_value_base");
1944   base_sub_dict.Set("sub_collide_key", "sub_collide_key_value_base");
1945   base.Set("sub_dict_key", std::move(base_sub_dict));
1946 
1947   Value::Dict merge;
1948   merge.Set("merge_key", "merge_key_value_merge");
1949   merge.Set("collide_key", "collide_key_value_merge");
1950   Value::Dict merge_sub_dict;
1951   merge_sub_dict.Set("sub_merge_key", "sub_merge_key_value_merge");
1952   merge_sub_dict.Set("sub_collide_key", "sub_collide_key_value_merge");
1953   merge.Set("sub_dict_key", std::move(merge_sub_dict));
1954 
1955   base.Merge(std::move(merge));
1956 
1957   EXPECT_EQ(4U, base.size());
1958   const std::string* base_key_value = base.FindString("base_key");
1959   ASSERT_TRUE(base_key_value);
1960   EXPECT_EQ("base_key_value_base", *base_key_value);  // Base value preserved.
1961   const std::string* collide_key_value = base.FindString("collide_key");
1962   ASSERT_TRUE(collide_key_value);
1963   EXPECT_EQ("collide_key_value_merge", *collide_key_value);  // Replaced.
1964   const std::string* merge_key_value = base.FindString("merge_key");
1965   ASSERT_TRUE(merge_key_value);
1966   EXPECT_EQ("merge_key_value_merge", *merge_key_value);  // Merged in.
1967 
1968   Value::Dict* res_sub_dict = base.FindDict("sub_dict_key");
1969   ASSERT_TRUE(res_sub_dict);
1970   EXPECT_EQ(3U, res_sub_dict->size());
1971   const std::string* sub_base_key_value =
1972       res_sub_dict->FindString("sub_base_key");
1973   ASSERT_TRUE(sub_base_key_value);
1974   EXPECT_EQ("sub_base_key_value_base", *sub_base_key_value);  // Preserved.
1975   const std::string* sub_collide_key_value =
1976       res_sub_dict->FindString("sub_collide_key");
1977   ASSERT_TRUE(sub_collide_key_value);
1978   EXPECT_EQ("sub_collide_key_value_merge",
1979             *sub_collide_key_value);  // Replaced.
1980   const std::string* sub_merge_key_value =
1981       res_sub_dict->FindString("sub_merge_key");
1982   ASSERT_TRUE(sub_merge_key_value);
1983   EXPECT_EQ("sub_merge_key_value_merge", *sub_merge_key_value);  // Merged in.
1984 }
1985 
TEST(ValuesTest,DictionaryIterator)1986 TEST(ValuesTest, DictionaryIterator) {
1987   Value::Dict dict;
1988   for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
1989     ADD_FAILURE();
1990   }
1991 
1992   Value value1("value1");
1993   dict.Set("key1", value1.Clone());
1994   bool seen1 = false;
1995   for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
1996     EXPECT_FALSE(seen1);
1997     EXPECT_EQ("key1", it->first);
1998     EXPECT_EQ(value1, it->second);
1999     seen1 = true;
2000   }
2001   EXPECT_TRUE(seen1);
2002 
2003   Value value2("value2");
2004   dict.Set("key2", value2.Clone());
2005   bool seen2 = seen1 = false;
2006   for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
2007     if (it->first == "key1") {
2008       EXPECT_FALSE(seen1);
2009       EXPECT_EQ(value1, it->second);
2010       seen1 = true;
2011     } else if (it->first == "key2") {
2012       EXPECT_FALSE(seen2);
2013       EXPECT_EQ(value2, it->second);
2014       seen2 = true;
2015     } else {
2016       ADD_FAILURE();
2017     }
2018   }
2019   EXPECT_TRUE(seen1);
2020   EXPECT_TRUE(seen2);
2021 }
2022 
TEST(ValuesTest,MutatingCopiedPairsInDictMutatesUnderlyingValues)2023 TEST(ValuesTest, MutatingCopiedPairsInDictMutatesUnderlyingValues) {
2024   Value::Dict dict;
2025   dict.Set("key", Value("initial value"));
2026 
2027   // Because the non-const dict iterates over <const std::string&, Value&>
2028   // pairs, it's possible to alter iterated-over values in place even when
2029   // "copying" the key-value pair:
2030   for (auto kv : dict) {
2031     kv.second.GetString() = "replacement";
2032   }
2033 
2034   std::string* found = dict.FindString("key");
2035   ASSERT_TRUE(found);
2036   EXPECT_EQ(*found, "replacement");
2037 }
2038 
TEST(ValuesTest,StdDictionaryIterator)2039 TEST(ValuesTest, StdDictionaryIterator) {
2040   Value::Dict dict;
2041   for (auto it = dict.begin(); it != dict.end(); ++it) {
2042     ADD_FAILURE();
2043   }
2044 
2045   Value value1("value1");
2046   dict.Set("key1", value1.Clone());
2047   bool seen1 = false;
2048   for (auto it : dict) {
2049     EXPECT_FALSE(seen1);
2050     EXPECT_EQ("key1", it.first);
2051     EXPECT_EQ(value1, it.second);
2052     seen1 = true;
2053   }
2054   EXPECT_TRUE(seen1);
2055 
2056   Value value2("value2");
2057   dict.Set("key2", value2.Clone());
2058   bool seen2 = seen1 = false;
2059   for (auto it : dict) {
2060     if (it.first == "key1") {
2061       EXPECT_FALSE(seen1);
2062       EXPECT_EQ(value1, it.second);
2063       seen1 = true;
2064     } else if (it.first == "key2") {
2065       EXPECT_FALSE(seen2);
2066       EXPECT_EQ(value2, it.second);
2067       seen2 = true;
2068     } else {
2069       ADD_FAILURE();
2070     }
2071   }
2072   EXPECT_TRUE(seen1);
2073   EXPECT_TRUE(seen2);
2074 }
2075 
TEST(ValuesTest,SelfSwap)2076 TEST(ValuesTest, SelfSwap) {
2077   base::Value test(1);
2078   std::swap(test, test);
2079   EXPECT_EQ(1, test.GetInt());
2080 }
2081 
TEST(ValuesTest,FromToUniquePtrValue)2082 TEST(ValuesTest, FromToUniquePtrValue) {
2083   std::unique_ptr<Value> dict = std::make_unique<Value>(Value::Type::DICT);
2084   dict->GetDict().Set("name", "Froogle");
2085   dict->GetDict().Set("url", "http://froogle.com");
2086   Value dict_copy = dict->Clone();
2087 
2088   Value dict_converted = Value::FromUniquePtrValue(std::move(dict));
2089   EXPECT_EQ(dict_copy, dict_converted);
2090 
2091   std::unique_ptr<Value> val =
2092       Value::ToUniquePtrValue(std::move(dict_converted));
2093   EXPECT_EQ(dict_copy, *val);
2094 }
2095 
TEST(ValuesTest,MutableFindStringPath)2096 TEST(ValuesTest, MutableFindStringPath) {
2097   Value::Dict dict;
2098   dict.SetByDottedPath("foo.bar", "value");
2099 
2100   *(dict.FindStringByDottedPath("foo.bar")) = "new_value";
2101 
2102   Value::Dict expected_dict;
2103   expected_dict.SetByDottedPath("foo.bar", "new_value");
2104 
2105   EXPECT_EQ(expected_dict, dict);
2106 }
2107 
TEST(ValuesTest,MutableGetString)2108 TEST(ValuesTest, MutableGetString) {
2109   Value value("value");
2110   value.GetString() = "new_value";
2111   EXPECT_EQ("new_value", value.GetString());
2112 }
2113 
2114 #if BUILDFLAG(ENABLE_BASE_TRACING)
TEST(ValuesTest,TracingSupport)2115 TEST(ValuesTest, TracingSupport) {
2116   EXPECT_EQ(perfetto::TracedValueToString(Value(false)), "false");
2117   EXPECT_EQ(perfetto::TracedValueToString(Value(1)), "1");
2118   EXPECT_EQ(perfetto::TracedValueToString(Value(1.5)), "1.5");
2119   EXPECT_EQ(perfetto::TracedValueToString(Value("value")), "value");
2120   EXPECT_EQ(perfetto::TracedValueToString(Value(Value::Type::NONE)), "<none>");
2121   {
2122     Value::List list;
2123     EXPECT_EQ(perfetto::TracedValueToString(list), "{}");
2124     list.Append(2);
2125     list.Append(3);
2126     EXPECT_EQ(perfetto::TracedValueToString(list), "[2,3]");
2127     EXPECT_EQ(perfetto::TracedValueToString(Value(std::move(list))), "[2,3]");
2128   }
2129   {
2130     Value::Dict dict;
2131     EXPECT_EQ(perfetto::TracedValueToString(dict), "{}");
2132     dict.Set("key", "value");
2133     EXPECT_EQ(perfetto::TracedValueToString(dict), "{key:value}");
2134     EXPECT_EQ(perfetto::TracedValueToString(Value(std::move(dict))),
2135               "{key:value}");
2136   }
2137 }
2138 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
2139 
TEST(ValueViewTest,BasicConstruction)2140 TEST(ValueViewTest, BasicConstruction) {
2141   {
2142     ValueView v = true;
2143     EXPECT_EQ(true, absl::get<bool>(v.data_view_for_test()));
2144   }
2145   {
2146     ValueView v = 25;
2147     EXPECT_EQ(25, absl::get<int>(v.data_view_for_test()));
2148   }
2149   {
2150     ValueView v = 3.14;
2151     EXPECT_DOUBLE_EQ(3.14, absl::get<ValueView::DoubleStorageForTest>(
2152                                v.data_view_for_test()));
2153   }
2154   {
2155     ValueView v = StringPiece("hello world");
2156     EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2157   }
2158   {
2159     ValueView v = "hello world";
2160     EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2161   }
2162   {
2163     std::string str = "hello world";
2164     ValueView v = str;
2165     EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2166   }
2167   {
2168     Value::Dict dict;
2169     dict.Set("hello", "world");
2170     ValueView v = dict;
2171     EXPECT_EQ(dict, absl::get<std::reference_wrapper<const Value::Dict>>(
2172                         v.data_view_for_test()));
2173   }
2174   {
2175     Value::List list;
2176     list.Append("hello");
2177     list.Append("world");
2178     ValueView v = list;
2179     EXPECT_EQ(list, absl::get<std::reference_wrapper<const Value::List>>(
2180                         v.data_view_for_test()));
2181   }
2182 }
2183 
TEST(ValueViewTest,ValueConstruction)2184 TEST(ValueViewTest, ValueConstruction) {
2185   {
2186     Value val(true);
2187     ValueView v = val;
2188     EXPECT_EQ(true, absl::get<bool>(v.data_view_for_test()));
2189   }
2190   {
2191     Value val(25);
2192     ValueView v = val;
2193     EXPECT_EQ(25, absl::get<int>(v.data_view_for_test()));
2194   }
2195   {
2196     Value val(3.14);
2197     ValueView v = val;
2198     EXPECT_DOUBLE_EQ(3.14, absl::get<ValueView::DoubleStorageForTest>(
2199                                v.data_view_for_test()));
2200   }
2201   {
2202     Value val("hello world");
2203     ValueView v = val;
2204     EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2205   }
2206   {
2207     Value::Dict dict;
2208     dict.Set("hello", "world");
2209     Value val(dict.Clone());
2210     ValueView v = val;
2211     EXPECT_EQ(dict, absl::get<std::reference_wrapper<const Value::Dict>>(
2212                         v.data_view_for_test()));
2213   }
2214   {
2215     Value::List list;
2216     list.Append("hello");
2217     list.Append("world");
2218     Value val(list.Clone());
2219     ValueView v = val;
2220     EXPECT_EQ(list, absl::get<std::reference_wrapper<const Value::List>>(
2221                         v.data_view_for_test()));
2222   }
2223 }
2224 
TEST(ValueViewTest,ToValue)2225 TEST(ValueViewTest, ToValue) {
2226   {
2227     Value val(true);
2228     Value to_val = ValueView(val).ToValue();
2229     EXPECT_EQ(val, to_val);
2230   }
2231   {
2232     Value val(25);
2233     Value to_val = ValueView(val).ToValue();
2234     EXPECT_EQ(val, to_val);
2235   }
2236   {
2237     Value val(3.14);
2238     Value to_val = ValueView(val).ToValue();
2239     EXPECT_EQ(val, to_val);
2240   }
2241   {
2242     Value val("hello world");
2243     Value to_val = ValueView(val).ToValue();
2244     EXPECT_EQ(val, to_val);
2245   }
2246   {
2247     Value::Dict dict;
2248     dict.Set("hello", "world");
2249     Value val(dict.Clone());
2250     Value to_val = ValueView(val).ToValue();
2251     EXPECT_EQ(val, to_val);
2252   }
2253   {
2254     Value::List list;
2255     list.Append("hello");
2256     list.Append("world");
2257     Value val(list.Clone());
2258     Value to_val = ValueView(val).ToValue();
2259     EXPECT_EQ(val, to_val);
2260   }
2261 }
2262 
2263 }  // namespace base
2264