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