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.
5 #include "base/values.h"
15 #include <type_traits>
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"
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)
37 // `Value` should have a (relatively) small size to avoid creating excess
38 // overhead, e.g. for lists of values that are all ints.
40 // This test is limited to NDEBUG builds, since some containers may require
41 // extra storage for supporting debug checks for things like iterators.
42 TEST(ValuesTest, SizeOfValue) {
44 // On Windows, clang-cl does not support `[[no_unique_address]]` (see
45 // https://github.com/llvm/llvm-project/issues/49358). `base::Value::Dict` has
46 // a `base::flat_tree` which relies on this attribute to avoid wasting space
47 // when the comparator is stateless. Unfortunately, this means
48 // `base::Value::Dict` ends up taking 4 machine words instead of 3. An
49 // additional word is used by absl::variant for the type index.
50 constexpr size_t kExpectedSize = 5 * sizeof(void*);
51 #elif defined(__GLIBCXX__)
52 // libstdc++ std::string takes already 4 machine words, so the absl::variant
54 constexpr size_t kExpectedSize = 5 * sizeof(void*);
55 #else // !BUILDFLAG(IS_WIN) && !defined(__GLIBCXX__)
56 // libc++'s std::string and std::vector both take 3 machine words. An
57 // additional word is used by absl::variant for the type index.
58 constexpr size_t kExpectedSize = 4 * sizeof(void*);
59 #endif // BUILDFLAG(IS_WIN)
61 // Use std::integral_constant so the compiler error message includes the
62 // evaluated size. In future versions of clang, it should be possible to
63 // simplify this to an equality comparison (i.e. newer clangs print out
64 // "comparison reduces to '(1 == 2)'").
65 static_assert(std::is_same_v<std::integral_constant<size_t, sizeof(Value)>,
66 std::integral_constant<size_t, kExpectedSize>>,
67 "base::Value has an unexpected size!");
71 TEST(ValuesTest, TestNothrow) {
72 static_assert(std::is_nothrow_move_constructible<Value>::value,
73 "IsNothrowMoveConstructible");
74 static_assert(std::is_nothrow_default_constructible<Value>::value,
75 "IsNothrowDefaultConstructible");
76 static_assert(std::is_nothrow_constructible<Value, std::string&&>::value,
77 "IsNothrowMoveConstructibleFromString");
79 std::is_nothrow_constructible<Value, Value::BlobStorage&&>::value,
80 "IsNothrowMoveConstructibleFromBlob");
81 static_assert(std::is_nothrow_move_assignable<Value>::value,
82 "IsNothrowMoveAssignable");
85 TEST(ValuesTest, EmptyValue) {
87 EXPECT_EQ(Value::Type::NONE, value.type());
88 EXPECT_EQ(absl::nullopt, value.GetIfBool());
89 EXPECT_EQ(absl::nullopt, value.GetIfInt());
90 EXPECT_EQ(absl::nullopt, value.GetIfDouble());
91 EXPECT_EQ(nullptr, value.GetIfString());
92 EXPECT_EQ(nullptr, value.GetIfBlob());
95 // Group of tests for the value constructors.
96 TEST(ValuesTest, ConstructBool) {
97 Value true_value(true);
98 EXPECT_EQ(Value::Type::BOOLEAN, true_value.type());
99 EXPECT_THAT(true_value.GetIfBool(), testing::Optional(true));
100 EXPECT_TRUE(true_value.GetBool());
102 Value false_value(false);
103 EXPECT_EQ(Value::Type::BOOLEAN, false_value.type());
104 EXPECT_THAT(false_value.GetIfBool(), testing::Optional(false));
105 EXPECT_FALSE(false_value.GetBool());
108 TEST(ValuesTest, ConstructFromPtrs) {
109 static_assert(!std::is_constructible<Value, int*>::value, "");
110 static_assert(!std::is_constructible<Value, const int*>::value, "");
111 static_assert(!std::is_constructible<Value, wchar_t*>::value, "");
112 static_assert(!std::is_constructible<Value, const wchar_t*>::value, "");
114 static_assert(std::is_constructible<Value, char*>::value, "");
115 static_assert(std::is_constructible<Value, const char*>::value, "");
116 static_assert(std::is_constructible<Value, char16_t*>::value, "");
117 static_assert(std::is_constructible<Value, const char16_t*>::value, "");
120 TEST(ValuesTest, ConstructInt) {
122 EXPECT_EQ(Value::Type::INTEGER, value.type());
123 EXPECT_THAT(value.GetIfInt(), testing::Optional(-37));
124 EXPECT_EQ(-37, value.GetInt());
126 EXPECT_THAT(value.GetIfDouble(), testing::Optional(-37.0));
127 EXPECT_EQ(-37.0, value.GetDouble());
130 TEST(ValuesTest, ConstructDouble) {
132 EXPECT_EQ(Value::Type::DOUBLE, value.type());
133 EXPECT_THAT(value.GetIfDouble(), testing::Optional(-4.655));
134 EXPECT_EQ(-4.655, value.GetDouble());
137 TEST(ValuesTest, ConstructStringFromConstCharPtr) {
138 const char* str = "foobar";
140 EXPECT_EQ(Value::Type::STRING, value.type());
141 EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
142 EXPECT_EQ("foobar", value.GetString());
145 TEST(ValuesTest, ConstructStringFromStringPiece) {
146 std::string str = "foobar";
147 Value value{StringPiece(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());
153 TEST(ValuesTest, ConstructStringFromStdStringRRef) {
154 std::string str = "foobar";
155 Value value(std::move(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());
161 TEST(ValuesTest, ConstructStringFromConstChar16Ptr) {
162 std::u16string str = u"foobar";
163 Value value(str.c_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());
169 TEST(ValuesTest, ConstructStringFromStringPiece16) {
170 std::u16string str = u"foobar";
171 Value value{StringPiece16(str)};
172 EXPECT_EQ(Value::Type::STRING, value.type());
173 EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
174 EXPECT_EQ("foobar", value.GetString());
177 TEST(ValuesTest, ConstructBinary) {
178 Value::BlobStorage blob = {0xF, 0x0, 0x0, 0xB, 0xA, 0x2};
180 EXPECT_EQ(Value::Type::BINARY, value.type());
181 EXPECT_THAT(value.GetIfBlob(), testing::Pointee(blob));
182 EXPECT_EQ(blob, value.GetBlob());
185 TEST(ValuesTest, ConstructDict) {
187 EXPECT_EQ(Value::Type::DICTIONARY, Value(std::move(value)).type());
190 TEST(ValuesTest, ConstructDictFromValueDict) {
192 dict.Set("foo", "bar");
194 Value value(dict.Clone());
195 EXPECT_EQ(Value::Type::DICT, value.type());
196 EXPECT_TRUE(value.GetIfDict());
197 EXPECT_TRUE(value.GetDict().FindString("foo"));
198 EXPECT_EQ("bar", *value.GetDict().FindString("foo"));
201 dict.Set("foo", "baz");
203 Value value(std::move(dict));
204 EXPECT_EQ(Value::Type::DICT, value.type());
205 EXPECT_TRUE(value.GetIfDict());
206 EXPECT_TRUE(value.GetDict().FindString("foo"));
207 EXPECT_EQ("baz", *value.GetDict().FindString("foo"));
211 TEST(ValuesTest, ConstructList) {
213 EXPECT_EQ(Value::Type::LIST, value.type());
216 TEST(ValuesTest, UseTestingEachOnValueList) {
221 // This will only work if `Value::List::value_type` is defined.
222 EXPECT_THAT(list, testing::Each(testing::ResultOf(
223 [](const Value& value) { return value.GetBool(); },
224 testing::Eq(true))));
227 TEST(ValuesTest, ConstructListFromValueList) {
231 Value value(list.Clone());
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("foo", value.GetList()[0].GetString());
238 list.back() = base::Value("bar");
240 Value value(std::move(list));
241 EXPECT_EQ(Value::Type::LIST, value.type());
242 EXPECT_EQ(1u, value.GetList().size());
243 EXPECT_EQ(Value::Type::STRING, value.GetList()[0].type());
244 EXPECT_EQ("bar", value.GetList()[0].GetString());
248 TEST(ValuesTest, HardenTests) {
250 ASSERT_EQ(value.type(), Value::Type::NONE);
251 EXPECT_DEATH_IF_SUPPORTED(value.GetBool(), "");
252 EXPECT_DEATH_IF_SUPPORTED(value.GetInt(), "");
253 EXPECT_DEATH_IF_SUPPORTED(value.GetDouble(), "");
254 EXPECT_DEATH_IF_SUPPORTED(value.GetString(), "");
255 EXPECT_DEATH_IF_SUPPORTED(value.GetBlob(), "");
256 EXPECT_DEATH_IF_SUPPORTED(value.DictItems(), "");
257 EXPECT_DEATH_IF_SUPPORTED(value.GetListDeprecated(), "");
260 // Group of tests for the copy constructors and copy-assigmnent. For equality
261 // checks comparisons of the interesting fields are done instead of relying on
262 // Equals being correct.
263 TEST(ValuesTest, CopyBool) {
264 Value true_value(true);
265 Value copied_true_value(true_value.Clone());
266 EXPECT_EQ(true_value.type(), copied_true_value.type());
267 EXPECT_EQ(true_value.GetBool(), copied_true_value.GetBool());
269 Value false_value(false);
270 Value copied_false_value(false_value.Clone());
271 EXPECT_EQ(false_value.type(), copied_false_value.type());
272 EXPECT_EQ(false_value.GetBool(), copied_false_value.GetBool());
276 blank = true_value.Clone();
277 EXPECT_EQ(true_value.type(), blank.type());
278 EXPECT_EQ(true_value.GetBool(), blank.GetBool());
280 blank = false_value.Clone();
281 EXPECT_EQ(false_value.type(), blank.type());
282 EXPECT_EQ(false_value.GetBool(), blank.GetBool());
285 TEST(ValuesTest, CopyInt) {
287 Value copied_value(value.Clone());
288 EXPECT_EQ(value.type(), copied_value.type());
289 EXPECT_EQ(value.GetInt(), copied_value.GetInt());
293 blank = value.Clone();
294 EXPECT_EQ(value.type(), blank.type());
295 EXPECT_EQ(value.GetInt(), blank.GetInt());
298 TEST(ValuesTest, CopyDouble) {
300 Value copied_value(value.Clone());
301 EXPECT_EQ(value.type(), copied_value.type());
302 EXPECT_EQ(value.GetDouble(), copied_value.GetDouble());
306 blank = value.Clone();
307 EXPECT_EQ(value.type(), blank.type());
308 EXPECT_EQ(value.GetDouble(), blank.GetDouble());
311 TEST(ValuesTest, CopyString) {
312 Value value("foobar");
313 Value copied_value(value.Clone());
314 EXPECT_EQ(value.type(), copied_value.type());
315 EXPECT_EQ(value.GetString(), copied_value.GetString());
319 blank = value.Clone();
320 EXPECT_EQ(value.type(), blank.type());
321 EXPECT_EQ(value.GetString(), blank.GetString());
324 TEST(ValuesTest, CopyBinary) {
325 Value value(Value::BlobStorage({0xF, 0x0, 0x0, 0xB, 0xA, 0x2}));
326 Value copied_value(value.Clone());
327 EXPECT_EQ(value.type(), copied_value.type());
328 EXPECT_EQ(value.GetBlob(), copied_value.GetBlob());
332 blank = value.Clone();
333 EXPECT_EQ(value.type(), blank.type());
334 EXPECT_EQ(value.GetBlob(), blank.GetBlob());
337 TEST(ValuesTest, CopyDictionary) {
339 dict.Set("Int", 123);
340 Value value(std::move(dict));
342 Value copied_value(value.Clone());
343 EXPECT_EQ(value, copied_value);
346 blank = value.Clone();
347 EXPECT_EQ(value, blank);
350 TEST(ValuesTest, CopyList) {
353 Value value(std::move(list));
355 Value copied_value(value.Clone());
356 EXPECT_EQ(value, copied_value);
359 blank = value.Clone();
360 EXPECT_EQ(value, blank);
363 // Group of tests for the move constructors and move-assigmnent.
364 TEST(ValuesTest, MoveBool) {
365 Value true_value(true);
366 Value moved_true_value(std::move(true_value));
367 EXPECT_EQ(Value::Type::BOOLEAN, moved_true_value.type());
368 EXPECT_TRUE(moved_true_value.GetBool());
370 Value false_value(false);
371 Value moved_false_value(std::move(false_value));
372 EXPECT_EQ(Value::Type::BOOLEAN, moved_false_value.type());
373 EXPECT_FALSE(moved_false_value.GetBool());
378 EXPECT_EQ(Value::Type::BOOLEAN, blank.type());
379 EXPECT_TRUE(blank.GetBool());
381 blank = Value(false);
382 EXPECT_EQ(Value::Type::BOOLEAN, blank.type());
383 EXPECT_FALSE(blank.GetBool());
386 TEST(ValuesTest, MoveInt) {
388 Value moved_value(std::move(value));
389 EXPECT_EQ(Value::Type::INTEGER, moved_value.type());
390 EXPECT_EQ(74, moved_value.GetInt());
395 EXPECT_EQ(Value::Type::INTEGER, blank.type());
396 EXPECT_EQ(47, blank.GetInt());
399 TEST(ValuesTest, MoveDouble) {
401 Value moved_value(std::move(value));
402 EXPECT_EQ(Value::Type::DOUBLE, moved_value.type());
403 EXPECT_EQ(74.896, moved_value.GetDouble());
407 blank = Value(654.38);
408 EXPECT_EQ(Value::Type::DOUBLE, blank.type());
409 EXPECT_EQ(654.38, blank.GetDouble());
412 TEST(ValuesTest, MoveString) {
413 Value value("foobar");
414 Value moved_value(std::move(value));
415 EXPECT_EQ(Value::Type::STRING, moved_value.type());
416 EXPECT_EQ("foobar", moved_value.GetString());
420 blank = Value("foobar");
421 EXPECT_EQ(Value::Type::STRING, blank.type());
422 EXPECT_EQ("foobar", blank.GetString());
425 TEST(ValuesTest, MoveBinary) {
426 const Value::BlobStorage buffer = {0xF, 0x0, 0x0, 0xB, 0xA, 0x2};
428 Value moved_value(std::move(value));
429 EXPECT_EQ(Value::Type::BINARY, moved_value.type());
430 EXPECT_EQ(buffer, moved_value.GetBlob());
434 blank = Value(buffer);
435 EXPECT_EQ(Value::Type::BINARY, blank.type());
436 EXPECT_EQ(buffer, blank.GetBlob());
439 TEST(ValuesTest, MoveConstructDictionary) {
441 dict.Set("Int", 123);
443 Value value(std::move(dict));
444 Value moved_value(std::move(value));
445 EXPECT_EQ(Value::Type::DICTIONARY, moved_value.type());
446 EXPECT_EQ(123, moved_value.GetDict().Find("Int")->GetInt());
449 TEST(ValuesTest, MoveAssignDictionary) {
451 dict.Set("Int", 123);
454 blank = Value(std::move(dict));
455 EXPECT_EQ(Value::Type::DICTIONARY, blank.type());
456 EXPECT_EQ(123, blank.GetDict().Find("Int")->GetInt());
459 TEST(ValuesTest, ConstructDictWithIterators) {
460 std::vector<std::pair<std::string, Value>> values;
461 values.emplace_back(std::make_pair("Int", 123));
464 blank = Value(Value::Dict(std::make_move_iterator(values.begin()),
465 std::make_move_iterator(values.end())));
466 EXPECT_EQ(Value::Type::DICTIONARY, blank.type());
467 EXPECT_EQ(123, blank.GetDict().Find("Int")->GetInt());
470 TEST(ValuesTest, MoveList) {
473 Value value(list.Clone());
474 Value moved_value(std::move(value));
475 EXPECT_EQ(Value::Type::LIST, moved_value.type());
476 EXPECT_EQ(123, moved_value.GetListDeprecated().back().GetInt());
479 blank = Value(std::move(list));
480 EXPECT_EQ(Value::Type::LIST, blank.type());
481 EXPECT_EQ(123, blank.GetListDeprecated().back().GetInt());
484 TEST(ValuesTest, Append) {
487 EXPECT_TRUE(value.GetListDeprecated().back().is_bool());
490 EXPECT_TRUE(value.GetListDeprecated().back().is_int());
493 EXPECT_TRUE(value.GetListDeprecated().back().is_double());
495 std::string str = "foo";
496 value.Append(str.c_str());
497 EXPECT_TRUE(value.GetListDeprecated().back().is_string());
499 value.Append(StringPiece(str));
500 EXPECT_TRUE(value.GetListDeprecated().back().is_string());
502 value.Append(std::move(str));
503 EXPECT_TRUE(value.GetListDeprecated().back().is_string());
505 std::u16string str16 = u"bar";
506 value.GetList().Append(str16.c_str());
507 EXPECT_TRUE(value.GetList().back().is_string());
509 value.Append(base::StringPiece16(str16));
510 EXPECT_TRUE(value.GetListDeprecated().back().is_string());
512 value.Append(Value());
513 EXPECT_TRUE(value.GetListDeprecated().back().is_none());
515 value.Append(Value(Value::Type::DICTIONARY));
516 EXPECT_TRUE(value.GetListDeprecated().back().is_dict());
518 value.Append(Value(Value::Type::LIST));
519 EXPECT_TRUE(value.GetListDeprecated().back().is_list());
522 TEST(ValuesTest, ListInsert) {
524 const Value::List& const_list = list;
526 auto iter = list.Insert(list.end(), Value(true));
527 EXPECT_TRUE(list.begin() == iter);
528 EXPECT_EQ(*iter, true);
530 iter = list.Insert(const_list.begin(), Value(123));
531 EXPECT_TRUE(const_list.begin() == iter);
532 EXPECT_EQ(*iter, 123);
534 iter = list.Insert(list.begin() + 1, Value("Hello world!"));
535 EXPECT_TRUE(list.begin() + 1 == iter);
536 EXPECT_EQ(*iter, "Hello world!");
539 // Test all three behaviors of EnsureDict() (Create a new dict where no
540 // matchining values exist, return an existing dict, create a dict overwriting
541 // a value of another type).
542 TEST(ValuesTest, DictEnsureDict) {
545 // This call should create a new nested dictionary.
546 Value::Dict* foo_dict = root.EnsureDict("foo");
547 EXPECT_TRUE(foo_dict->empty());
548 foo_dict->Set("a", "b");
550 // This call should retrieve the dictionary created above, rather than
551 // creating a new one.
552 std::string* a_string = root.EnsureDict("foo")->FindString("a");
553 ASSERT_NE(nullptr, a_string);
554 EXPECT_EQ(*a_string, "b");
556 // Use EnsureDict() to overwrite an existing non-dictionary value.
558 Value::Dict* bar_dict = root.EnsureDict("bar");
559 EXPECT_TRUE(bar_dict->empty());
560 bar_dict->Set("b", "c");
562 // Test that the above call created a "bar" entry.
563 bar_dict = root.FindDict("bar");
564 ASSERT_NE(nullptr, bar_dict);
565 std::string* b_string = bar_dict->FindString("b");
566 ASSERT_NE(nullptr, b_string);
567 EXPECT_EQ(*b_string, "c");
570 // Test all three behaviors of EnsureList() (Create a new list where no
571 // matchining value exists, return an existing list, create a list overwriting
572 // a value of another type).
573 TEST(ValuesTest, DictEnsureList) {
576 // This call should create a new list.
577 Value::List* foo_list = root.EnsureList("foo");
578 EXPECT_TRUE(foo_list->empty());
579 foo_list->Append("a");
581 // This call should retrieve the list created above, rather than creating a
583 foo_list = root.EnsureList("foo");
584 ASSERT_EQ(1u, foo_list->size());
585 EXPECT_EQ((*foo_list)[0], Value("a"));
587 // Use EnsureList() to overwrite an existing non-list value.
589 Value::List* bar_list = root.EnsureList("bar");
590 EXPECT_TRUE(bar_list->empty());
591 bar_list->Append("b");
593 // Test that the above call created a "bar" entry.
594 bar_list = root.FindList("bar");
595 ASSERT_NE(nullptr, bar_list);
596 ASSERT_EQ(1u, bar_list->size());
597 EXPECT_EQ((*bar_list)[0], Value("b"));
600 // TODO(dcheng): Add more tests directly exercising the updated dictionary and
601 // list APIs. For now, most of the updated APIs are tested indirectly via the
602 // legacy APIs that are largely backed by the updated APIs.
603 TEST(ValuesTest, DictFindByDottedPath) {
606 EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
608 Value::Dict& a_dict = dict.Set("a", Value::Dict())->GetDict();
609 EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
611 Value::Dict& b_dict = a_dict.Set("b", Value::Dict())->GetDict();
612 EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
614 b_dict.Set("c", true);
615 const Value* value = dict.FindByDottedPath("a.b.c");
616 ASSERT_NE(nullptr, value);
617 EXPECT_TRUE(value->GetBool());
620 TEST(ValuesTest, DictSetByDottedPath) {
623 Value* c = dict.SetByDottedPath("a.b.c", Value());
626 Value::Dict* a = dict.FindDict("a");
628 EXPECT_EQ(1U, a->size());
630 Value::Dict* b = a->FindDict("b");
632 EXPECT_EQ(1U, b->size());
634 EXPECT_EQ(c, b->Find("c"));
637 TEST(ValuesTest, DictSetWithDottedKey) {
640 Value* abc = dict.Set("a.b.c", Value());
643 EXPECT_FALSE(dict.FindByDottedPath("a"));
644 EXPECT_FALSE(dict.FindByDottedPath("a.b"));
645 EXPECT_FALSE(dict.FindByDottedPath("a.b.c"));
647 EXPECT_EQ(abc, dict.Find("a.b.c"));
650 TEST(ValuesTest, ListFront) {
652 const Value::List& const_list = list;
658 EXPECT_EQ(Value(1), list.front());
659 EXPECT_EQ(Value(1), const_list.front());
662 TEST(ValuesTest, ListFrontWhenEmpty) {
664 const Value::List& const_list = list;
666 EXPECT_CHECK_DEATH(list.front());
667 EXPECT_CHECK_DEATH(const_list.front());
670 TEST(ValuesTest, ListBack) {
672 const Value::List& const_list = list;
678 EXPECT_EQ(Value(3), list.back());
679 EXPECT_EQ(Value(3), const_list.back());
682 TEST(ValuesTest, ListBackWhenEmpty) {
684 const Value::List& const_list = list;
686 EXPECT_CHECK_DEATH(list.back());
687 EXPECT_CHECK_DEATH(const_list.back());
690 TEST(ValuesTest, ListErase) {
696 auto next_it = list.erase(list.begin() + 1);
697 ASSERT_EQ(2u, list.size());
698 EXPECT_EQ(list[0], Value(1));
699 EXPECT_EQ(list[1], Value(3));
700 EXPECT_EQ(*next_it, Value(3));
701 EXPECT_EQ(next_it + 1, list.end());
704 TEST(ValuesTest, ListEraseRange) {
711 auto next_it = list.erase(list.begin() + 1, list.begin() + 3);
712 ASSERT_EQ(2u, list.size());
713 EXPECT_EQ(list[0], Value(1));
714 EXPECT_EQ(list[1], Value(4));
715 EXPECT_EQ(*next_it, Value(4));
716 EXPECT_EQ(next_it + 1, list.end());
718 next_it = list.erase(list.begin() + 1, list.begin() + 1);
719 ASSERT_EQ(2u, list.size());
720 EXPECT_EQ(list[0], Value(1));
721 EXPECT_EQ(list[1], Value(4));
722 EXPECT_EQ(*next_it, Value(4));
723 EXPECT_EQ(next_it + 1, list.end());
725 next_it = list.erase(list.begin() + 1, list.end());
726 ASSERT_EQ(1u, list.size());
727 EXPECT_EQ(list[0], Value(1));
728 EXPECT_EQ(next_it, list.end());
731 next_it = list.erase(list.begin(), list.begin());
732 ASSERT_EQ(0u, list.size());
733 EXPECT_EQ(next_it, list.begin());
734 EXPECT_EQ(next_it, list.end());
737 TEST(ValuesTest, ListEraseValue) {
744 EXPECT_EQ(2u, list.EraseValue(Value(2)));
745 EXPECT_EQ(2u, list.size());
746 EXPECT_EQ(1, list[0]);
747 EXPECT_EQ(3, list[1]);
749 EXPECT_EQ(1u, list.EraseValue(Value(1)));
750 EXPECT_EQ(1u, list.size());
751 EXPECT_EQ(3, list[0]);
753 EXPECT_EQ(1u, list.EraseValue(Value(3)));
754 EXPECT_TRUE(list.empty());
756 EXPECT_EQ(0u, list.EraseValue(Value(3)));
759 TEST(ValuesTest, ListEraseIf) {
766 EXPECT_EQ(3u, list.EraseIf([](const auto& val) { return val >= Value(2); }));
767 EXPECT_EQ(1u, list.size());
768 EXPECT_EQ(1, list[0]);
770 EXPECT_EQ(1u, list.EraseIf([](const auto& val) { return true; }));
771 EXPECT_TRUE(list.empty());
773 EXPECT_EQ(0u, list.EraseIf([](const auto& val) { return true; }));
776 TEST(ValuesTest, ClearList) {
781 EXPECT_EQ(3u, value.GetListDeprecated().size());
784 EXPECT_TRUE(value.GetListDeprecated().empty());
786 // ClearList() should be idempotent.
788 EXPECT_TRUE(value.GetListDeprecated().empty());
791 TEST(ValuesTest, FindKey) {
793 dict.Set("foo", "bar");
794 Value value(std::move(dict));
795 EXPECT_NE(nullptr, value.GetDict().Find("foo"));
796 EXPECT_EQ(nullptr, value.GetDict().Find("baz"));
799 TEST(ValuesTest, FindKeyChangeValue) {
801 dict.Set("foo", "bar");
802 Value* found = dict.Find("foo");
803 ASSERT_NE(nullptr, found);
804 EXPECT_EQ("bar", found->GetString());
807 EXPECT_EQ(123, dict.Find("foo")->GetInt());
810 TEST(ValuesTest, FindKeyConst) {
812 dict.Set("foo", "bar");
813 const Value value(std::move(dict));
814 EXPECT_NE(nullptr, value.GetDict().Find("foo"));
815 EXPECT_EQ(nullptr, value.GetDict().Find("baz"));
818 TEST(ValuesTest, FindKeyOfType) {
820 dict.Set("null", Value());
821 dict.Set("bool", false);
823 dict.Set("double", 0.0);
824 dict.Set("string", std::string());
825 dict.Set("blob", Value(Value::BlobStorage()));
826 dict.Set("list", Value::List());
827 dict.Set("dict", Value::Dict());
829 Value value(std::move(dict));
830 EXPECT_NE(nullptr, value.FindKeyOfType("null", Value::Type::NONE));
831 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::BOOLEAN));
832 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::INTEGER));
833 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::DOUBLE));
834 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::STRING));
835 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::BINARY));
836 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::LIST));
837 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::DICTIONARY));
839 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::NONE));
840 EXPECT_NE(nullptr, value.FindKeyOfType("bool", Value::Type::BOOLEAN));
841 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::INTEGER));
842 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::DOUBLE));
843 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::STRING));
844 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::BINARY));
845 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::LIST));
846 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::DICTIONARY));
848 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::NONE));
849 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::BOOLEAN));
850 EXPECT_NE(nullptr, value.FindKeyOfType("int", Value::Type::INTEGER));
851 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::DOUBLE));
852 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::STRING));
853 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::BINARY));
854 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::LIST));
855 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::DICTIONARY));
857 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::NONE));
858 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::BOOLEAN));
859 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::INTEGER));
860 EXPECT_NE(nullptr, value.FindKeyOfType("double", Value::Type::DOUBLE));
861 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::STRING));
862 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::BINARY));
863 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::LIST));
864 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::DICTIONARY));
866 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::NONE));
867 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::BOOLEAN));
868 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::INTEGER));
869 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::DOUBLE));
870 EXPECT_NE(nullptr, value.FindKeyOfType("string", Value::Type::STRING));
871 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::BINARY));
872 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::LIST));
873 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::DICTIONARY));
875 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::NONE));
876 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::BOOLEAN));
877 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::INTEGER));
878 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::DOUBLE));
879 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::STRING));
880 EXPECT_NE(nullptr, value.FindKeyOfType("blob", Value::Type::BINARY));
881 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::LIST));
882 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::DICTIONARY));
884 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::NONE));
885 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::BOOLEAN));
886 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::INTEGER));
887 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::DOUBLE));
888 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::STRING));
889 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::BINARY));
890 EXPECT_NE(nullptr, value.FindKeyOfType("list", Value::Type::LIST));
891 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::DICTIONARY));
893 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::NONE));
894 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::BOOLEAN));
895 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::INTEGER));
896 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::DOUBLE));
897 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::STRING));
898 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::BINARY));
899 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::LIST));
900 EXPECT_NE(nullptr, value.FindKeyOfType("dict", Value::Type::DICTIONARY));
903 TEST(ValuesTest, FindKeyOfTypeConst) {
905 dict.Set("null", Value());
906 dict.Set("bool", false);
908 dict.Set("double", 0.0);
909 dict.Set("string", std::string());
910 dict.Set("blob", Value(Value::BlobStorage()));
911 dict.Set("list", Value::List());
912 dict.Set("dict", Value::Dict());
914 const Value value(std::move(dict));
915 EXPECT_NE(nullptr, value.FindKeyOfType("null", Value::Type::NONE));
916 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::BOOLEAN));
917 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::INTEGER));
918 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::DOUBLE));
919 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::STRING));
920 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::BINARY));
921 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::LIST));
922 EXPECT_EQ(nullptr, value.FindKeyOfType("null", Value::Type::DICTIONARY));
924 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::NONE));
925 EXPECT_NE(nullptr, value.FindKeyOfType("bool", Value::Type::BOOLEAN));
926 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::INTEGER));
927 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::DOUBLE));
928 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::STRING));
929 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::BINARY));
930 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::LIST));
931 EXPECT_EQ(nullptr, value.FindKeyOfType("bool", Value::Type::DICTIONARY));
933 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::NONE));
934 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::BOOLEAN));
935 EXPECT_NE(nullptr, value.FindKeyOfType("int", Value::Type::INTEGER));
936 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::DOUBLE));
937 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::STRING));
938 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::BINARY));
939 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::LIST));
940 EXPECT_EQ(nullptr, value.FindKeyOfType("int", Value::Type::DICTIONARY));
942 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::NONE));
943 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::BOOLEAN));
944 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::INTEGER));
945 EXPECT_NE(nullptr, value.FindKeyOfType("double", Value::Type::DOUBLE));
946 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::STRING));
947 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::BINARY));
948 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::LIST));
949 EXPECT_EQ(nullptr, value.FindKeyOfType("double", Value::Type::DICTIONARY));
951 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::NONE));
952 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::BOOLEAN));
953 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::INTEGER));
954 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::DOUBLE));
955 EXPECT_NE(nullptr, value.FindKeyOfType("string", Value::Type::STRING));
956 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::BINARY));
957 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::LIST));
958 EXPECT_EQ(nullptr, value.FindKeyOfType("string", Value::Type::DICTIONARY));
960 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::NONE));
961 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::BOOLEAN));
962 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::INTEGER));
963 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::DOUBLE));
964 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::STRING));
965 EXPECT_NE(nullptr, value.FindKeyOfType("blob", Value::Type::BINARY));
966 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::LIST));
967 EXPECT_EQ(nullptr, value.FindKeyOfType("blob", Value::Type::DICTIONARY));
969 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::NONE));
970 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::BOOLEAN));
971 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::INTEGER));
972 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::DOUBLE));
973 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::STRING));
974 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::BINARY));
975 EXPECT_NE(nullptr, value.FindKeyOfType("list", Value::Type::LIST));
976 EXPECT_EQ(nullptr, value.FindKeyOfType("list", Value::Type::DICTIONARY));
978 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::NONE));
979 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::BOOLEAN));
980 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::INTEGER));
981 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::DOUBLE));
982 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::STRING));
983 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::BINARY));
984 EXPECT_EQ(nullptr, value.FindKeyOfType("dict", Value::Type::LIST));
985 EXPECT_NE(nullptr, value.FindKeyOfType("dict", Value::Type::DICTIONARY));
988 TEST(ValuesTest, FindBoolKey) {
990 dict.Set("null", Value());
991 dict.Set("bool", false);
993 dict.Set("double", 0.0);
994 dict.Set("string", std::string());
995 dict.Set("blob", Value(Value::BlobStorage()));
996 dict.Set("list", Value::List());
997 dict.Set("dict", Value::Dict());
999 EXPECT_EQ(absl::nullopt, dict.FindBool("null"));
1000 EXPECT_NE(absl::nullopt, dict.FindBool("bool"));
1001 EXPECT_EQ(absl::nullopt, dict.FindBool("int"));
1002 EXPECT_EQ(absl::nullopt, dict.FindBool("double"));
1003 EXPECT_EQ(absl::nullopt, dict.FindBool("string"));
1004 EXPECT_EQ(absl::nullopt, dict.FindBool("blob"));
1005 EXPECT_EQ(absl::nullopt, dict.FindBool("list"));
1006 EXPECT_EQ(absl::nullopt, dict.FindBool("dict"));
1009 TEST(ValuesTest, FindIntKey) {
1011 dict.Set("null", Value());
1012 dict.Set("bool", false);
1014 dict.Set("double", 0.0);
1015 dict.Set("string", std::string());
1016 dict.Set("blob", Value(Value::BlobStorage()));
1017 dict.Set("list", Value::List());
1018 dict.Set("dict", Value::Dict());
1020 EXPECT_EQ(absl::nullopt, dict.FindInt("null"));
1021 EXPECT_EQ(absl::nullopt, dict.FindInt("bool"));
1022 EXPECT_NE(absl::nullopt, dict.FindInt("int"));
1023 EXPECT_EQ(absl::nullopt, dict.FindInt("double"));
1024 EXPECT_EQ(absl::nullopt, dict.FindInt("string"));
1025 EXPECT_EQ(absl::nullopt, dict.FindInt("blob"));
1026 EXPECT_EQ(absl::nullopt, dict.FindInt("list"));
1027 EXPECT_EQ(absl::nullopt, dict.FindInt("dict"));
1030 TEST(ValuesTest, FindDoubleKey) {
1032 dict.Set("null", Value());
1033 dict.Set("bool", false);
1035 dict.Set("double", 0.0);
1036 dict.Set("string", std::string());
1037 dict.Set("blob", Value(Value::BlobStorage()));
1038 dict.Set("list", Value::List());
1039 dict.Set("dict", Value::Dict());
1041 EXPECT_EQ(absl::nullopt, dict.FindDouble("null"));
1042 EXPECT_EQ(absl::nullopt, dict.FindDouble("bool"));
1043 EXPECT_NE(absl::nullopt, dict.FindDouble("int"));
1044 EXPECT_NE(absl::nullopt, dict.FindDouble("double"));
1045 EXPECT_EQ(absl::nullopt, dict.FindDouble("string"));
1046 EXPECT_EQ(absl::nullopt, dict.FindDouble("blob"));
1047 EXPECT_EQ(absl::nullopt, dict.FindDouble("list"));
1048 EXPECT_EQ(absl::nullopt, dict.FindDouble("dict"));
1051 TEST(ValuesTest, FindStringKey) {
1053 dict.Set("null", Value());
1054 dict.Set("bool", false);
1056 dict.Set("double", 0.0);
1057 dict.Set("string", std::string());
1058 dict.Set("blob", Value(Value::BlobStorage()));
1059 dict.Set("list", Value::List());
1060 dict.Set("dict", Value::Dict());
1062 EXPECT_EQ(nullptr, dict.FindString("null"));
1063 EXPECT_EQ(nullptr, dict.FindString("bool"));
1064 EXPECT_EQ(nullptr, dict.FindString("int"));
1065 EXPECT_EQ(nullptr, dict.FindString("double"));
1066 EXPECT_NE(nullptr, dict.FindString("string"));
1067 EXPECT_EQ(nullptr, dict.FindString("blob"));
1068 EXPECT_EQ(nullptr, dict.FindString("list"));
1069 EXPECT_EQ(nullptr, dict.FindString("dict"));
1072 TEST(ValuesTest, MutableFindStringKey) {
1074 dict.Set("string", "foo");
1076 *(dict.FindString("string")) = "bar";
1078 Value::Dict expected_dict;
1079 expected_dict.Set("string", "bar");
1081 EXPECT_EQ(expected_dict, dict);
1083 Value value(std::move(dict));
1084 Value expected_value(std::move(expected_dict));
1085 EXPECT_EQ(expected_value, value);
1088 TEST(ValuesTest, FindDictKey) {
1090 dict.Set("null", Value());
1091 dict.Set("bool", false);
1093 dict.Set("double", 0.0);
1094 dict.Set("string", std::string());
1095 dict.Set("blob", Value(Value::BlobStorage()));
1096 dict.Set("list", Value::List());
1097 dict.Set("dict", Value::Dict());
1099 EXPECT_EQ(nullptr, dict.FindDict("null"));
1100 EXPECT_EQ(nullptr, dict.FindDict("bool"));
1101 EXPECT_EQ(nullptr, dict.FindDict("int"));
1102 EXPECT_EQ(nullptr, dict.FindDict("double"));
1103 EXPECT_EQ(nullptr, dict.FindDict("string"));
1104 EXPECT_EQ(nullptr, dict.FindDict("blob"));
1105 EXPECT_EQ(nullptr, dict.FindDict("list"));
1106 EXPECT_NE(nullptr, dict.FindDict("dict"));
1109 TEST(ValuesTest, FindListKey) {
1111 dict.Set("null", Value());
1112 dict.Set("bool", false);
1114 dict.Set("double", 0.0);
1115 dict.Set("string", std::string());
1116 dict.Set("blob", Value(Value::BlobStorage()));
1117 dict.Set("list", Value::List());
1118 dict.Set("dict", Value::Dict());
1120 EXPECT_EQ(nullptr, dict.FindList("null"));
1121 EXPECT_EQ(nullptr, dict.FindList("bool"));
1122 EXPECT_EQ(nullptr, dict.FindList("int"));
1123 EXPECT_EQ(nullptr, dict.FindList("double"));
1124 EXPECT_EQ(nullptr, dict.FindList("string"));
1125 EXPECT_EQ(nullptr, dict.FindList("blob"));
1126 EXPECT_NE(nullptr, dict.FindList("list"));
1127 EXPECT_EQ(nullptr, dict.FindList("dict"));
1130 TEST(ValuesTest, FindBlob) {
1132 dict.Set("null", Value());
1133 dict.Set("bool", false);
1135 dict.Set("double", 0.0);
1136 dict.Set("string", std::string());
1137 dict.Set("blob", Value(Value::BlobStorage()));
1138 dict.Set("list", Value::List());
1139 dict.Set("dict", Value::Dict());
1141 EXPECT_EQ(nullptr, dict.FindBlob("null"));
1142 EXPECT_EQ(nullptr, dict.FindBlob("bool"));
1143 EXPECT_EQ(nullptr, dict.FindBlob("int"));
1144 EXPECT_EQ(nullptr, dict.FindBlob("double"));
1145 EXPECT_EQ(nullptr, dict.FindBlob("string"));
1146 EXPECT_NE(nullptr, dict.FindBlob("blob"));
1147 EXPECT_EQ(nullptr, dict.FindBlob("list"));
1148 EXPECT_EQ(nullptr, dict.FindBlob("dict"));
1151 TEST(ValuesTest, SetKey) {
1153 dict.Set("null", Value());
1154 dict.Set("bool", false);
1156 dict.Set("double", 0.0);
1157 dict.Set("string", std::string());
1158 dict.Set("blob", Value(Value::BlobStorage()));
1159 dict.Set("list", Value::List());
1160 dict.Set("dict", Value::Dict());
1163 dict2.Set(StringPiece("null"), Value(Value::Type::NONE));
1164 dict2.Set(StringPiece("bool"), Value(Value::Type::BOOLEAN));
1165 dict2.Set(std::string("int"), Value(Value::Type::INTEGER));
1166 dict2.Set(std::string("double"), Value(Value::Type::DOUBLE));
1167 dict2.Set(std::string("string"), Value(Value::Type::STRING));
1168 dict2.Set("blob", Value(Value::Type::BINARY));
1169 dict2.Set("list", Value(Value::Type::LIST));
1170 dict2.Set("dict", Value(Value::Type::DICTIONARY));
1172 EXPECT_EQ(dict, dict2);
1173 EXPECT_EQ(Value(std::move(dict)), Value(std::move(dict2)));
1176 TEST(ValuesTest, SetBoolKey) {
1177 absl::optional<bool> value;
1180 dict.Set("true_key", true);
1181 dict.Set("false_key", false);
1183 value = dict.FindBool("true_key");
1185 ASSERT_TRUE(*value);
1187 value = dict.FindBool("false_key");
1189 ASSERT_FALSE(*value);
1191 value = dict.FindBool("missing_key");
1192 ASSERT_FALSE(value);
1195 TEST(ValuesTest, SetIntKey) {
1196 absl::optional<int> value;
1199 dict.Set("one_key", 1);
1200 dict.Set("minus_one_key", -1);
1202 value = dict.FindInt("one_key");
1204 ASSERT_EQ(1, *value);
1206 value = dict.FindInt("minus_one_key");
1208 ASSERT_EQ(-1, *value);
1210 value = dict.FindInt("missing_key");
1211 ASSERT_FALSE(value);
1214 TEST(ValuesTest, SetDoubleKey) {
1216 dict.Set("one_key", 1.0);
1217 dict.Set("minus_one_key", -1.0);
1218 dict.Set("pi_key", 3.1415);
1220 // NOTE: Use FindKey() instead of FindDoubleKey() because the latter will
1221 // auto-convert integers to doubles as well.
1224 value = dict.Find("one_key");
1226 EXPECT_TRUE(value->is_double());
1227 EXPECT_EQ(1.0, value->GetDouble());
1229 value = dict.Find("minus_one_key");
1231 EXPECT_TRUE(value->is_double());
1232 EXPECT_EQ(-1.0, value->GetDouble());
1234 value = dict.Find("pi_key");
1236 EXPECT_TRUE(value->is_double());
1237 EXPECT_EQ(3.1415, value->GetDouble());
1240 TEST(ValuesTest, SetStringKey) {
1242 dict.Set("one_key", "one");
1243 dict.Set("hello_key", "hello world");
1245 std::string movable_value("movable_value");
1246 dict.Set("movable_key", std::move(movable_value));
1247 ASSERT_TRUE(movable_value.empty());
1249 const std::string* value;
1251 value = dict.FindString("one_key");
1253 ASSERT_EQ("one", *value);
1255 value = dict.FindString("hello_key");
1257 ASSERT_EQ("hello world", *value);
1259 value = dict.FindString("movable_key");
1261 ASSERT_EQ("movable_value", *value);
1263 value = dict.FindString("missing_key");
1264 ASSERT_FALSE(value);
1267 TEST(ValuesTest, FindPath) {
1268 // Construct a dictionary path {root}.foo.bar = 123
1270 foo.Set("bar", Value(123));
1273 root.Set("foo", std::move(foo));
1275 // Double key, second not found.
1276 Value* found = root.FindByDottedPath("foo.notfound");
1277 EXPECT_FALSE(found);
1279 // Double key, found.
1280 found = root.FindByDottedPath("foo.bar");
1282 EXPECT_TRUE(found->is_int());
1283 EXPECT_EQ(123, found->GetInt());
1286 TEST(ValuesTest, SetPath) {
1289 Value* inserted = root.SetByDottedPath("one.two", Value(123));
1290 Value* found = root.FindByDottedPath("one.two");
1292 EXPECT_EQ(found->type(), Value::Type::INTEGER);
1293 EXPECT_EQ(inserted, found);
1294 EXPECT_EQ(123, found->GetInt());
1296 inserted = root.SetByDottedPath("foo.bar", Value(123));
1297 found = root.FindByDottedPath("foo.bar");
1299 EXPECT_EQ(found->type(), Value::Type::INTEGER);
1300 EXPECT_EQ(inserted, found);
1301 EXPECT_EQ(123, found->GetInt());
1303 // Overwrite with a different value.
1304 root.SetByDottedPath("foo.bar", Value("hello"));
1305 found = root.FindByDottedPath("foo.bar");
1307 EXPECT_EQ(found->type(), Value::Type::STRING);
1308 EXPECT_EQ("hello", found->GetString());
1310 // Can't change existing non-dictionary keys to dictionaries.
1311 found = root.SetByDottedPath("foo.bar.baz", Value(123));
1312 EXPECT_FALSE(found);
1315 TEST(ValuesTest, SetBoolPath) {
1317 Value* inserted = root.SetByDottedPath("foo.bar", true);
1318 Value* found = root.FindByDottedPath("foo.bar");
1320 EXPECT_EQ(inserted, found);
1321 ASSERT_TRUE(found->is_bool());
1322 EXPECT_TRUE(found->GetBool());
1324 // Overwrite with a different value.
1325 root.SetByDottedPath("foo.bar", false);
1326 found = root.FindByDottedPath("foo.bar");
1328 ASSERT_TRUE(found->is_bool());
1329 EXPECT_FALSE(found->GetBool());
1331 // Can't change existing non-dictionary keys.
1332 ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", true));
1335 TEST(ValuesTest, SetIntPath) {
1337 Value* inserted = root.SetByDottedPath("foo.bar", 123);
1338 Value* found = root.FindByDottedPath("foo.bar");
1340 EXPECT_EQ(inserted, found);
1341 ASSERT_TRUE(found->is_int());
1342 EXPECT_EQ(123, found->GetInt());
1344 // Overwrite with a different value.
1345 root.SetByDottedPath("foo.bar", 234);
1346 found = root.FindByDottedPath("foo.bar");
1348 ASSERT_TRUE(found->is_int());
1349 EXPECT_EQ(234, found->GetInt());
1351 // Can't change existing non-dictionary keys.
1352 ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", 567));
1355 TEST(ValuesTest, SetDoublePath) {
1357 Value* inserted = root.SetByDottedPath("foo.bar", 1.23);
1358 Value* found = root.FindByDottedPath("foo.bar");
1360 EXPECT_EQ(inserted, found);
1361 ASSERT_TRUE(found->is_double());
1362 EXPECT_EQ(1.23, found->GetDouble());
1364 // Overwrite with a different value.
1365 root.SetByDottedPath("foo.bar", 2.34);
1366 found = root.FindByDottedPath("foo.bar");
1368 ASSERT_TRUE(found->is_double());
1369 EXPECT_EQ(2.34, found->GetDouble());
1371 // Can't change existing non-dictionary keys.
1372 ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", 5.67));
1375 TEST(ValuesTest, SetStringPath) {
1377 Value* inserted = root.SetByDottedPath("foo.bar", "hello world");
1378 Value* found = root.FindByDottedPath("foo.bar");
1380 EXPECT_EQ(inserted, found);
1381 ASSERT_TRUE(found->is_string());
1382 EXPECT_EQ("hello world", found->GetString());
1384 // Overwrite with a different value.
1385 root.SetByDottedPath("foo.bar", "bonjour monde");
1386 found = root.FindByDottedPath("foo.bar");
1388 ASSERT_TRUE(found->is_string());
1389 EXPECT_EQ("bonjour monde", found->GetString());
1391 ASSERT_TRUE(root.SetByDottedPath("foo.bar", StringPiece("rah rah")));
1392 ASSERT_TRUE(root.SetByDottedPath("foo.bar", std::string("temp string")));
1393 ASSERT_TRUE(root.SetByDottedPath("foo.bar", u"temp string"));
1395 // Can't change existing non-dictionary keys.
1396 ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", "ola mundo"));
1399 TEST(ValuesTest, RemoveKey) {
1401 root.Set("one", Value(123));
1403 // Removal of missing key should fail.
1404 EXPECT_FALSE(root.Remove("two"));
1406 // Removal of existing key should succeed.
1407 EXPECT_TRUE(root.Remove("one"));
1409 // Second removal of previously existing key should fail.
1410 EXPECT_FALSE(root.Remove("one"));
1413 TEST(ValuesTest, ExtractKey) {
1415 root.Set("one", Value(123));
1417 // Extraction of missing key should fail.
1418 EXPECT_EQ(absl::nullopt, root.Extract("two"));
1420 // Extraction of existing key should succeed.
1421 EXPECT_EQ(Value(123), root.Extract("one"));
1423 // Second extraction of previously existing key should fail.
1424 EXPECT_EQ(absl::nullopt, root.Extract("one"));
1427 TEST(ValuesTest, RemovePath) {
1429 root.SetByDottedPath("one.two.three", Value(123));
1431 // Removal of missing key should fail.
1432 EXPECT_FALSE(root.RemoveByDottedPath("one.two.four"));
1434 // Removal of existing key should succeed.
1435 EXPECT_TRUE(root.RemoveByDottedPath("one.two.three"));
1437 // Second removal of previously existing key should fail.
1438 EXPECT_FALSE(root.RemoveByDottedPath("one.two.three"));
1440 // Intermediate empty dictionaries should be cleared.
1441 EXPECT_EQ(nullptr, root.Find("one"));
1443 root.SetByDottedPath("one.two.three", Value(123));
1444 root.SetByDottedPath("one.two.four", Value(124));
1446 EXPECT_TRUE(root.RemoveByDottedPath("one.two.three"));
1447 // Intermediate non-empty dictionaries should be kept.
1448 EXPECT_NE(nullptr, root.Find("one"));
1449 EXPECT_NE(nullptr, root.FindByDottedPath("one.two"));
1450 EXPECT_NE(nullptr, root.FindByDottedPath("one.two.four"));
1453 TEST(ValuesTest, ExtractByDottedPath) {
1455 root.SetByDottedPath("one.two.three", Value(123));
1457 // Extraction of missing key should fail.
1458 EXPECT_EQ(absl::nullopt, root.ExtractByDottedPath("one.two.four"));
1460 // Extraction of existing key should succeed.
1461 EXPECT_EQ(Value(123), root.ExtractByDottedPath("one.two.three"));
1463 // Second extraction of previously existing key should fail.
1464 EXPECT_EQ(absl::nullopt, root.ExtractByDottedPath("one.two.three"));
1466 // Intermediate empty dictionaries should be cleared.
1467 EXPECT_EQ(nullptr, root.Find("one"));
1469 root.SetByDottedPath("one.two.three", Value(123));
1470 root.SetByDottedPath("one.two.four", Value(124));
1472 EXPECT_EQ(Value(123), root.ExtractByDottedPath("one.two.three"));
1473 // Intermediate non-empty dictionaries should be kept.
1474 EXPECT_NE(nullptr, root.Find("one"));
1475 EXPECT_NE(nullptr, root.FindByDottedPath("one.two"));
1476 EXPECT_NE(nullptr, root.FindByDottedPath("one.two.four"));
1479 TEST(ValuesTest, Basic) {
1480 // Test basic dictionary getting/setting
1481 Value::Dict settings;
1482 ASSERT_FALSE(settings.FindByDottedPath("global.homepage"));
1484 ASSERT_FALSE(settings.Find("global"));
1485 settings.Set("global", Value(true));
1486 ASSERT_TRUE(settings.Find("global"));
1487 settings.Remove("global");
1488 settings.SetByDottedPath("global.homepage", Value("http://scurvy.com"));
1489 ASSERT_TRUE(settings.Find("global"));
1490 const std::string* homepage =
1491 settings.FindStringByDottedPath("global.homepage");
1492 ASSERT_TRUE(homepage);
1493 ASSERT_EQ(std::string("http://scurvy.com"), *homepage);
1495 // Test storing a dictionary in a list.
1496 ASSERT_FALSE(settings.FindByDottedPath("global.toolbar.bookmarks"));
1498 ListValue new_toolbar_bookmarks;
1499 settings.SetByDottedPath("global.toolbar.bookmarks",
1500 std::move(new_toolbar_bookmarks));
1501 Value::List* toolbar_bookmarks =
1502 settings.FindListByDottedPath("global.toolbar.bookmarks");
1503 ASSERT_TRUE(toolbar_bookmarks);
1505 Value::Dict new_bookmark;
1506 new_bookmark.Set("name", Value("Froogle"));
1507 new_bookmark.Set("url", Value("http://froogle.com"));
1508 toolbar_bookmarks->Append(std::move(new_bookmark));
1510 Value* bookmark_list = settings.FindByDottedPath("global.toolbar.bookmarks");
1511 ASSERT_TRUE(bookmark_list);
1512 ASSERT_EQ(1U, bookmark_list->GetListDeprecated().size());
1513 Value* bookmark = &bookmark_list->GetListDeprecated()[0];
1514 ASSERT_TRUE(bookmark);
1515 ASSERT_TRUE(bookmark->is_dict());
1516 const std::string* bookmark_name = bookmark->GetDict().FindString("name");
1517 ASSERT_TRUE(bookmark_name);
1518 ASSERT_EQ(std::string("Froogle"), *bookmark_name);
1519 const std::string* bookmark_url = bookmark->GetDict().FindString("url");
1520 ASSERT_TRUE(bookmark_url);
1521 ASSERT_EQ(std::string("http://froogle.com"), *bookmark_url);
1524 TEST(ValuesTest, List) {
1525 Value mixed_list(Value::Type::LIST);
1526 mixed_list.Append(true);
1527 mixed_list.Append(42);
1528 mixed_list.Append(88.8);
1529 mixed_list.Append("foo");
1531 Value::ConstListView list_view = mixed_list.GetListDeprecated();
1532 ASSERT_EQ(4u, list_view.size());
1534 ASSERT_FALSE(list_view[0].is_int());
1535 ASSERT_FALSE(list_view[1].is_bool());
1536 ASSERT_FALSE(list_view[2].is_string());
1537 ASSERT_FALSE(list_view[2].is_int());
1538 ASSERT_FALSE(list_view[2].is_bool());
1540 ASSERT_TRUE(list_view[0].is_bool());
1541 ASSERT_TRUE(list_view[1].is_int());
1542 ASSERT_EQ(42, list_view[1].GetInt());
1543 // Implicit conversion from Integer to Double should be possible.
1544 ASSERT_EQ(42, list_view[1].GetDouble());
1545 ASSERT_EQ(88.8, list_view[2].GetDouble());
1546 ASSERT_EQ("foo", list_view[3].GetString());
1548 // Try searching in the mixed list.
1549 ASSERT_TRUE(Contains(list_view, base::Value(42)));
1550 ASSERT_FALSE(Contains(list_view, base::Value(false)));
1553 TEST(ValuesTest, BinaryValue) {
1554 // Default constructor creates a BinaryValue with a buffer of size 0.
1555 Value binary(Value::Type::BINARY);
1556 ASSERT_TRUE(binary.GetBlob().empty());
1558 // Test the common case of a non-empty buffer
1559 Value::BlobStorage buffer(15);
1560 uint8_t* original_buffer = buffer.data();
1561 binary = Value(std::move(buffer));
1562 ASSERT_TRUE(binary.GetBlob().data());
1563 ASSERT_EQ(original_buffer, binary.GetBlob().data());
1564 ASSERT_EQ(15U, binary.GetBlob().size());
1566 char stack_buffer[42];
1567 memset(stack_buffer, '!', 42);
1568 binary = Value(Value::BlobStorage(stack_buffer, stack_buffer + 42));
1569 ASSERT_TRUE(binary.GetBlob().data());
1570 ASSERT_NE(stack_buffer,
1571 reinterpret_cast<const char*>(binary.GetBlob().data()));
1572 ASSERT_EQ(42U, binary.GetBlob().size());
1573 ASSERT_EQ(0, memcmp(stack_buffer, binary.GetBlob().data(),
1574 binary.GetBlob().size()));
1577 TEST(ValuesTest, StringValue) {
1578 // Test overloaded StringValue constructor.
1579 std::unique_ptr<Value> narrow_value(new Value("narrow"));
1580 ASSERT_TRUE(narrow_value.get());
1581 ASSERT_TRUE(narrow_value->is_string());
1582 std::unique_ptr<Value> utf16_value(new Value(u"utf16"));
1583 ASSERT_TRUE(utf16_value.get());
1584 ASSERT_TRUE(utf16_value->is_string());
1586 ASSERT_TRUE(narrow_value->is_string());
1587 ASSERT_EQ(std::string("narrow"), narrow_value->GetString());
1589 ASSERT_TRUE(utf16_value->is_string());
1590 ASSERT_EQ(std::string("utf16"), utf16_value->GetString());
1593 TEST(ValuesTest, ListDeletion) {
1595 list.Append(Value());
1596 EXPECT_FALSE(list.GetList().empty());
1598 EXPECT_TRUE(list.GetListDeprecated().empty());
1601 TEST(ValuesTest, DictionaryDeletion) {
1602 std::string key = "test";
1604 dict.Set(key, Value());
1605 EXPECT_FALSE(dict.empty());
1606 EXPECT_EQ(1U, dict.size());
1608 EXPECT_TRUE(dict.empty());
1609 EXPECT_TRUE(dict.empty());
1610 EXPECT_EQ(0U, dict.size());
1613 TEST(ValuesTest, DictionarySetReturnsPointer) {
1616 Value* blank_ptr = dict.Set("foo.bar", Value());
1617 EXPECT_EQ(Value::Type::NONE, blank_ptr->type());
1622 Value* blank_ptr = dict.Set("foo.bar", Value());
1623 EXPECT_EQ(Value::Type::NONE, blank_ptr->type());
1628 Value* int_ptr = dict.Set("foo.bar", 42);
1629 EXPECT_EQ(Value::Type::INTEGER, int_ptr->type());
1630 EXPECT_EQ(42, int_ptr->GetInt());
1635 Value* string_ptr = dict.Set("foo.bar", "foo");
1636 EXPECT_EQ(Value::Type::STRING, string_ptr->type());
1637 EXPECT_EQ("foo", string_ptr->GetString());
1642 Value* string16_ptr = dict.Set("foo.bar", u"baz");
1643 EXPECT_EQ(Value::Type::STRING, string16_ptr->type());
1644 EXPECT_EQ("baz", string16_ptr->GetString());
1649 Value* dict_ptr = dict.Set("foo.bar", Value::Dict());
1650 EXPECT_EQ(Value::Type::DICTIONARY, dict_ptr->type());
1655 Value* list_ptr = dict.Set("foo.bar", Value::List());
1656 EXPECT_EQ(Value::Type::LIST, list_ptr->type());
1660 TEST(ValuesTest, Clone) {
1661 Value::Dict original_dict;
1662 Value* null_weak = original_dict.Set("null", Value());
1663 Value* bool_weak = original_dict.Set("bool", Value(true));
1664 Value* int_weak = original_dict.Set("int", Value(42));
1665 Value* double_weak = original_dict.Set("double", Value(3.14));
1666 Value* string_weak = original_dict.Set("string", Value("hello"));
1667 Value* string16_weak = original_dict.Set("string16", Value(u"hello16"));
1669 Value* binary_weak =
1670 original_dict.Set("binary", Value(Value::BlobStorage(42, '!')));
1675 Value* list_weak = original_dict.Set("list", Value(std::move(list)));
1678 original_dict.Set("dictionary", Value(Value::Type::DICTIONARY));
1679 dict_weak->GetDict().Set("key", "value");
1681 Value::Dict copy_dict = original_dict.Clone();
1683 Value* copy_null = copy_dict.Find("null");
1684 ASSERT_TRUE(copy_null);
1685 ASSERT_NE(copy_null, null_weak);
1686 ASSERT_TRUE(copy_null->is_none());
1688 Value* copy_bool = copy_dict.Find("bool");
1689 ASSERT_TRUE(copy_bool);
1690 ASSERT_NE(copy_bool, bool_weak);
1691 ASSERT_TRUE(copy_bool->is_bool());
1692 ASSERT_TRUE(copy_bool->GetBool());
1694 Value* copy_int = copy_dict.Find("int");
1695 ASSERT_TRUE(copy_int);
1696 ASSERT_NE(copy_int, int_weak);
1697 ASSERT_TRUE(copy_int->is_int());
1698 ASSERT_EQ(42, copy_int->GetInt());
1700 Value* copy_double = copy_dict.Find("double");
1701 ASSERT_TRUE(copy_double);
1702 ASSERT_NE(copy_double, double_weak);
1703 ASSERT_TRUE(copy_double->is_double());
1704 ASSERT_EQ(3.14, copy_double->GetDouble());
1706 Value* copy_string = copy_dict.Find("string");
1707 ASSERT_TRUE(copy_string);
1708 ASSERT_NE(copy_string, string_weak);
1709 ASSERT_TRUE(copy_string->is_string());
1710 ASSERT_EQ(std::string("hello"), copy_string->GetString());
1712 Value* copy_string16 = copy_dict.Find("string16");
1713 ASSERT_TRUE(copy_string16);
1714 ASSERT_NE(copy_string16, string16_weak);
1715 ASSERT_TRUE(copy_string16->is_string());
1716 ASSERT_EQ(std::string("hello16"), copy_string16->GetString());
1718 Value* copy_binary = copy_dict.Find("binary");
1719 ASSERT_TRUE(copy_binary);
1720 ASSERT_NE(copy_binary, binary_weak);
1721 ASSERT_TRUE(copy_binary->is_blob());
1722 ASSERT_NE(binary_weak->GetBlob().data(), copy_binary->GetBlob().data());
1723 ASSERT_EQ(binary_weak->GetBlob(), copy_binary->GetBlob());
1725 Value* copy_value = copy_dict.Find("list");
1726 ASSERT_TRUE(copy_value);
1727 ASSERT_NE(copy_value, list_weak);
1728 ASSERT_TRUE(copy_value->is_list());
1729 ASSERT_EQ(2U, copy_value->GetList().size());
1731 copy_value = copy_dict.Find("dictionary");
1732 ASSERT_TRUE(copy_value);
1733 ASSERT_NE(copy_value, dict_weak);
1734 ASSERT_TRUE(copy_value->is_dict());
1735 Value::Dict* copy_nested_dictionary = copy_value->GetIfDict();
1736 ASSERT_TRUE(copy_nested_dictionary);
1737 EXPECT_TRUE(copy_nested_dictionary->Find("key"));
1740 TEST(ValuesTest, TakeString) {
1742 std::string taken = std::move(value).TakeString();
1743 EXPECT_EQ(taken, "foo");
1746 // Check that the value can still be used after `TakeString()` was called, as
1747 // long as a new value was assigned to it.
1748 TEST(ValuesTest, PopulateAfterTakeString) {
1750 std::string taken = std::move(value).TakeString();
1752 value = Value(false);
1753 EXPECT_EQ(value, Value(false));
1756 TEST(ValuesTest, TakeDict) {
1758 dict.Set("foo", 123);
1759 Value value(std::move(dict));
1760 Value clone = value.Clone();
1762 Value::Dict taken = std::move(value).TakeDict();
1763 EXPECT_EQ(taken, clone);
1766 // Check that the value can still be used after `TakeDict()` was called, as long
1767 // as a new value was assigned to it.
1768 TEST(ValuesTest, PopulateAfterTakeDict) {
1770 dict.Set("foo", 123);
1771 Value value(std::move(dict));
1772 Value::Dict taken = std::move(value).TakeDict();
1774 value = Value(false);
1775 EXPECT_EQ(value, Value(false));
1778 TEST(ValuesTest, TakeList) {
1782 Value value(std::move(list));
1783 Value clone = value.Clone();
1785 Value::List taken = std::move(value).TakeList();
1786 EXPECT_EQ(taken, clone);
1789 // Check that the value can still be used after `TakeList()` was called, as long
1790 // as a new value was assigned to it.
1791 TEST(ValuesTest, PopulateAfterTakeList) {
1793 list.Append("hello");
1794 Value value(std::move(list));
1795 Value::List taken = std::move(value).TakeList();
1797 value = Value(false);
1798 EXPECT_EQ(value, Value(false));
1801 TEST(ValuesTest, SpecializedEquals) {
1802 std::vector<Value> values;
1803 values.emplace_back(false);
1804 values.emplace_back(true);
1805 values.emplace_back(0);
1806 values.emplace_back(1);
1807 values.emplace_back(1.0);
1808 values.emplace_back(2.0);
1809 values.emplace_back("hello");
1810 values.emplace_back("world");
1811 base::Value::Dict dict;
1812 dict.Set("hello", "world");
1813 values.emplace_back(std::move(dict));
1814 base::Value::Dict dict2;
1815 dict2.Set("world", "hello");
1816 values.emplace_back(std::move(dict2));
1817 base::Value::List list;
1818 list.Append("hello");
1819 list.Append("world");
1820 values.emplace_back(std::move(list));
1821 base::Value::List list2;
1822 list2.Append("world");
1823 list2.Append("hello");
1824 values.emplace_back(std::move(list2));
1826 for (const Value& outer_value : values) {
1827 for (const Value& inner_value : values) {
1828 SCOPED_TRACE(::testing::Message()
1829 << "Outer: " << outer_value << "Inner: " << inner_value);
1830 const bool should_be_equal = &outer_value == &inner_value;
1831 if (should_be_equal) {
1832 EXPECT_EQ(outer_value, inner_value);
1833 EXPECT_EQ(inner_value, outer_value);
1834 EXPECT_FALSE(outer_value != inner_value);
1835 EXPECT_FALSE(inner_value != outer_value);
1837 EXPECT_NE(outer_value, inner_value);
1838 EXPECT_NE(inner_value, outer_value);
1839 EXPECT_FALSE(outer_value == inner_value);
1840 EXPECT_FALSE(inner_value == outer_value);
1842 // Also test the various overloads for operator== against concrete
1844 outer_value.Visit([&](const auto& outer_member) {
1845 using T = std::decay_t<decltype(outer_member)>;
1846 if constexpr (!std::is_same_v<T, absl::monostate> &&
1847 !std::is_same_v<T, Value::BlobStorage>) {
1848 if (should_be_equal) {
1849 EXPECT_EQ(outer_member, inner_value);
1850 EXPECT_EQ(inner_value, outer_member);
1851 EXPECT_FALSE(outer_member != inner_value);
1852 EXPECT_FALSE(inner_value != outer_member);
1854 EXPECT_NE(outer_member, inner_value);
1855 EXPECT_NE(inner_value, outer_member);
1856 EXPECT_FALSE(outer_member == inner_value);
1857 EXPECT_FALSE(inner_value == outer_member);
1863 // A copy of a Value should also compare equal to itself.
1864 Value copied_value = outer_value.Clone();
1865 EXPECT_EQ(outer_value, copied_value);
1866 EXPECT_EQ(copied_value, outer_value);
1867 EXPECT_FALSE(outer_value != copied_value);
1868 EXPECT_FALSE(copied_value != outer_value);
1872 // Test that a literal string comparison does not end up using the bool (!!)
1874 TEST(ValuesTest, LiteralStringEquals) {
1875 EXPECT_EQ("hello world", base::Value("hello world"));
1876 EXPECT_EQ(base::Value("hello world"), "hello world");
1877 EXPECT_NE("hello world", base::Value(true));
1878 EXPECT_NE(base::Value(true), "hello world");
1881 TEST(ValuesTest, Equals) {
1882 auto null1 = std::make_unique<Value>();
1883 auto null2 = std::make_unique<Value>();
1884 EXPECT_NE(null1.get(), null2.get());
1885 EXPECT_EQ(*null1, *null2);
1887 Value boolean(false);
1888 EXPECT_NE(*null1, boolean);
1894 dv.Set("d1", "string");
1895 dv.Set("d2", u"http://google.com");
1896 dv.Set("e", Value());
1898 Value::Dict copy = dv.Clone();
1899 EXPECT_EQ(dv, copy);
1902 list.Append(Value());
1903 list.Append(Value(Value::Type::DICTIONARY));
1904 Value::List list_copy(list.Clone());
1906 Value* list_weak = dv.Set("f", std::move(list));
1907 EXPECT_NE(dv, copy);
1908 copy.Set("f", std::move(list_copy));
1909 EXPECT_EQ(dv, copy);
1911 list_weak->GetList().Append(true);
1912 EXPECT_NE(dv, copy);
1914 // Check if Equals detects differences in only the keys.
1916 EXPECT_EQ(dv, copy);
1918 copy.Set("aa", false);
1919 EXPECT_NE(dv, copy);
1922 TEST(ValuesTest, Comparisons) {
1923 // Test None Values.
1926 EXPECT_EQ(null1, null2);
1927 EXPECT_FALSE(null1 != null2);
1928 EXPECT_FALSE(null1 < null2);
1929 EXPECT_FALSE(null1 > null2);
1930 EXPECT_LE(null1, null2);
1931 EXPECT_GE(null1, null2);
1933 // Test Bool Values.
1936 EXPECT_FALSE(bool1 == bool2);
1937 EXPECT_NE(bool1, bool2);
1938 EXPECT_LT(bool1, bool2);
1939 EXPECT_FALSE(bool1 > bool2);
1940 EXPECT_LE(bool1, bool2);
1941 EXPECT_FALSE(bool1 >= bool2);
1946 EXPECT_FALSE(int1 == int2);
1947 EXPECT_NE(int1, int2);
1948 EXPECT_LT(int1, int2);
1949 EXPECT_FALSE(int1 > int2);
1950 EXPECT_LE(int1, int2);
1951 EXPECT_FALSE(int1 >= int2);
1953 // Test Double Values.
1956 EXPECT_FALSE(double1 == double2);
1957 EXPECT_NE(double1, double2);
1958 EXPECT_LT(double1, double2);
1959 EXPECT_FALSE(double1 > double2);
1960 EXPECT_LE(double1, double2);
1961 EXPECT_FALSE(double1 >= double2);
1963 // Test String Values.
1966 EXPECT_FALSE(string1 == string2);
1967 EXPECT_NE(string1, string2);
1968 EXPECT_LT(string1, string2);
1969 EXPECT_FALSE(string1 > string2);
1970 EXPECT_LE(string1, string2);
1971 EXPECT_FALSE(string1 >= string2);
1973 // Test Binary Values.
1974 Value binary1(Value::BlobStorage{0x01});
1975 Value binary2(Value::BlobStorage{0x02});
1976 EXPECT_FALSE(binary1 == binary2);
1977 EXPECT_NE(binary1, binary2);
1978 EXPECT_LT(binary1, binary2);
1979 EXPECT_FALSE(binary1 > binary2);
1980 EXPECT_LE(binary1, binary2);
1981 EXPECT_FALSE(binary1 >= binary2);
1983 // Test Empty List Values.
1984 ListValue null_list1;
1985 ListValue null_list2;
1986 EXPECT_EQ(null_list1, null_list2);
1987 EXPECT_FALSE(null_list1 != null_list2);
1988 EXPECT_FALSE(null_list1 < null_list2);
1989 EXPECT_FALSE(null_list1 > null_list2);
1990 EXPECT_LE(null_list1, null_list2);
1991 EXPECT_GE(null_list1, null_list2);
1993 // Test Non Empty List Values.
1994 ListValue int_list1;
1995 ListValue int_list2;
1996 int_list1.Append(1);
1997 int_list2.Append(2);
1998 EXPECT_FALSE(int_list1 == int_list2);
1999 EXPECT_NE(int_list1, int_list2);
2000 EXPECT_LT(int_list1, int_list2);
2001 EXPECT_FALSE(int_list1 > int_list2);
2002 EXPECT_LE(int_list1, int_list2);
2003 EXPECT_FALSE(int_list1 >= int_list2);
2005 // Test Empty Dict Values.
2006 Value::Dict null_dict1;
2007 Value::Dict null_dict2;
2008 EXPECT_EQ(null_dict1, null_dict2);
2009 EXPECT_FALSE(null_dict1 != null_dict2);
2010 EXPECT_FALSE(null_dict1 < null_dict2);
2011 EXPECT_FALSE(null_dict1 > null_dict2);
2012 EXPECT_LE(null_dict1, null_dict2);
2013 EXPECT_GE(null_dict1, null_dict2);
2015 // Test Non Empty Dict Values.
2016 Value::Dict int_dict1;
2017 Value::Dict int_dict2;
2018 int_dict1.Set("key", 1);
2019 int_dict2.Set("key", 2);
2020 EXPECT_FALSE(int_dict1 == int_dict2);
2021 EXPECT_NE(int_dict1, int_dict2);
2022 EXPECT_LT(int_dict1, int_dict2);
2023 EXPECT_FALSE(int_dict1 > int_dict2);
2024 EXPECT_LE(int_dict1, int_dict2);
2025 EXPECT_FALSE(int_dict1 >= int_dict2);
2027 // Test Values of different types.
2028 std::vector<Value> values;
2029 values.emplace_back(std::move(null1));
2030 values.emplace_back(std::move(bool1));
2031 values.emplace_back(std::move(int1));
2032 values.emplace_back(std::move(double1));
2033 values.emplace_back(std::move(string1));
2034 values.emplace_back(std::move(binary1));
2035 values.emplace_back(std::move(int_dict1));
2036 values.emplace_back(std::move(int_list1));
2037 for (size_t i = 0; i < values.size(); ++i) {
2038 for (size_t j = i + 1; j < values.size(); ++j) {
2039 EXPECT_FALSE(values[i] == values[j]);
2040 EXPECT_NE(values[i], values[j]);
2041 EXPECT_LT(values[i], values[j]);
2042 EXPECT_FALSE(values[i] > values[j]);
2043 EXPECT_LE(values[i], values[j]);
2044 EXPECT_FALSE(values[i] >= values[j]);
2049 TEST(ValuesTest, DeepCopyCovariantReturnTypes) {
2050 DictionaryValue original_dict;
2051 Value* null_weak = original_dict.SetKey("null", Value());
2052 Value* bool_weak = original_dict.SetKey("bool", Value(true));
2053 Value* int_weak = original_dict.SetKey("int", Value(42));
2054 Value* double_weak = original_dict.SetKey("double", Value(3.14));
2055 Value* string_weak = original_dict.SetKey("string", Value("hello"));
2056 Value* string16_weak = original_dict.SetKey("string16", Value(u"hello16"));
2057 Value* binary_weak =
2058 original_dict.SetKey("binary", Value(Value::BlobStorage(42, '!')));
2063 Value* list_weak = original_dict.SetKey("list", Value(std::move(list)));
2065 auto copy_dict = std::make_unique<Value>(original_dict.Clone());
2066 auto copy_null = std::make_unique<Value>(null_weak->Clone());
2067 auto copy_bool = std::make_unique<Value>(bool_weak->Clone());
2068 auto copy_int = std::make_unique<Value>(int_weak->Clone());
2069 auto copy_double = std::make_unique<Value>(double_weak->Clone());
2070 auto copy_string = std::make_unique<Value>(string_weak->Clone());
2071 auto copy_string16 = std::make_unique<Value>(string16_weak->Clone());
2072 auto copy_binary = std::make_unique<Value>(binary_weak->Clone());
2073 auto copy_list = std::make_unique<Value>(list_weak->Clone());
2075 EXPECT_EQ(original_dict, *copy_dict);
2076 EXPECT_EQ(*null_weak, *copy_null);
2077 EXPECT_EQ(*bool_weak, *copy_bool);
2078 EXPECT_EQ(*int_weak, *copy_int);
2079 EXPECT_EQ(*double_weak, *copy_double);
2080 EXPECT_EQ(*string_weak, *copy_string);
2081 EXPECT_EQ(*string16_weak, *copy_string16);
2082 EXPECT_EQ(*binary_weak, *copy_binary);
2083 EXPECT_EQ(*list_weak, *copy_list);
2086 TEST(ValuesTest, Merge) {
2088 base.Set("base_key", "base_key_value_base");
2089 base.Set("collide_key", "collide_key_value_base");
2090 Value::Dict base_sub_dict;
2091 base_sub_dict.Set("sub_base_key", "sub_base_key_value_base");
2092 base_sub_dict.Set("sub_collide_key", "sub_collide_key_value_base");
2093 base.Set("sub_dict_key", std::move(base_sub_dict));
2096 merge.Set("merge_key", "merge_key_value_merge");
2097 merge.Set("collide_key", "collide_key_value_merge");
2098 Value::Dict merge_sub_dict;
2099 merge_sub_dict.Set("sub_merge_key", "sub_merge_key_value_merge");
2100 merge_sub_dict.Set("sub_collide_key", "sub_collide_key_value_merge");
2101 merge.Set("sub_dict_key", std::move(merge_sub_dict));
2103 base.Merge(std::move(merge));
2105 EXPECT_EQ(4U, base.size());
2106 const std::string* base_key_value = base.FindString("base_key");
2107 ASSERT_TRUE(base_key_value);
2108 EXPECT_EQ("base_key_value_base", *base_key_value); // Base value preserved.
2109 const std::string* collide_key_value = base.FindString("collide_key");
2110 ASSERT_TRUE(collide_key_value);
2111 EXPECT_EQ("collide_key_value_merge", *collide_key_value); // Replaced.
2112 const std::string* merge_key_value = base.FindString("merge_key");
2113 ASSERT_TRUE(merge_key_value);
2114 EXPECT_EQ("merge_key_value_merge", *merge_key_value); // Merged in.
2116 Value::Dict* res_sub_dict = base.FindDict("sub_dict_key");
2117 ASSERT_TRUE(res_sub_dict);
2118 EXPECT_EQ(3U, res_sub_dict->size());
2119 const std::string* sub_base_key_value =
2120 res_sub_dict->FindString("sub_base_key");
2121 ASSERT_TRUE(sub_base_key_value);
2122 EXPECT_EQ("sub_base_key_value_base", *sub_base_key_value); // Preserved.
2123 const std::string* sub_collide_key_value =
2124 res_sub_dict->FindString("sub_collide_key");
2125 ASSERT_TRUE(sub_collide_key_value);
2126 EXPECT_EQ("sub_collide_key_value_merge",
2127 *sub_collide_key_value); // Replaced.
2128 const std::string* sub_merge_key_value =
2129 res_sub_dict->FindString("sub_merge_key");
2130 ASSERT_TRUE(sub_merge_key_value);
2131 EXPECT_EQ("sub_merge_key_value_merge", *sub_merge_key_value); // Merged in.
2134 TEST(ValuesTest, MergeDictionaryDeepCopy) {
2135 // Note: This test still uses the old and deprecated MergeDictionary() API, as
2136 // the new API doesn't support what this test expects. The test expects that
2137 // the dictionary passed as an argument to MergeDictionary() be left unchanged
2138 // (which is pretty much implied anyway, by the constness). However, the new
2139 // API, Value::Dict::Merge(), will std::move() any values from the dict
2142 // Just remove this test when the old API is removed.
2144 std::unique_ptr<DictionaryValue> child(new DictionaryValue);
2145 DictionaryValue* original_child = child.get();
2146 child->SetStringKey("test", "value");
2147 EXPECT_EQ(1U, child->DictSize());
2150 EXPECT_TRUE(child->GetString("test", &value));
2151 EXPECT_EQ("value", value);
2153 std::unique_ptr<DictionaryValue> base(new DictionaryValue);
2154 base->Set("dict", std::move(child));
2155 EXPECT_EQ(1U, base->DictSize());
2157 DictionaryValue* ptr;
2158 EXPECT_TRUE(base->GetDictionary("dict", &ptr));
2159 EXPECT_EQ(original_child, ptr);
2161 std::unique_ptr<DictionaryValue> merged(new DictionaryValue);
2162 merged->MergeDictionary(base.get());
2163 EXPECT_EQ(1U, merged->DictSize());
2164 EXPECT_TRUE(merged->GetDictionary("dict", &ptr));
2165 EXPECT_NE(original_child, ptr);
2166 EXPECT_TRUE(ptr->GetString("test", &value));
2167 EXPECT_EQ("value", value);
2169 original_child->SetStringKey("test", "overwrite");
2171 EXPECT_TRUE(ptr->GetString("test", &value));
2172 EXPECT_EQ("value", value);
2175 TEST(ValuesTest, DictionaryIterator) {
2177 for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
2181 Value value1("value1");
2182 dict.Set("key1", value1.Clone());
2184 for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
2185 EXPECT_FALSE(seen1);
2186 EXPECT_EQ("key1", it->first);
2187 EXPECT_EQ(value1, it->second);
2192 Value value2("value2");
2193 dict.Set("key2", value2.Clone());
2194 bool seen2 = seen1 = false;
2195 for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
2196 if (it->first == "key1") {
2197 EXPECT_FALSE(seen1);
2198 EXPECT_EQ(value1, it->second);
2200 } else if (it->first == "key2") {
2201 EXPECT_FALSE(seen2);
2202 EXPECT_EQ(value2, it->second);
2212 TEST(ValuesTest, MutatingCopiedPairsInDictItemsMutatesUnderlyingValues) {
2214 dict.Set("key", Value("initial value"));
2216 // Because the non-const dict iterates over <const std::string&, Value&>
2217 // pairs, it's possible to alter iterated-over values in place even when
2218 // "copying" the key-value pair:
2219 for (auto kv : dict)
2220 kv.second.GetString() = "replacement";
2222 std::string* found = dict.FindString("key");
2224 EXPECT_EQ(*found, "replacement");
2227 TEST(ValuesTest, StdDictionaryIterator) {
2229 for (auto it = dict.begin(); it != dict.end(); ++it) {
2233 Value value1("value1");
2234 dict.Set("key1", value1.Clone());
2236 for (auto it : dict) {
2237 EXPECT_FALSE(seen1);
2238 EXPECT_EQ("key1", it.first);
2239 EXPECT_EQ(value1, it.second);
2244 Value value2("value2");
2245 dict.Set("key2", value2.Clone());
2246 bool seen2 = seen1 = false;
2247 for (auto it : dict) {
2248 if (it.first == "key1") {
2249 EXPECT_FALSE(seen1);
2250 EXPECT_EQ(value1, it.second);
2252 } else if (it.first == "key2") {
2253 EXPECT_FALSE(seen2);
2254 EXPECT_EQ(value2, it.second);
2264 // DictionaryValue/ListValue's Get*() methods should accept NULL as an out-value
2265 // and still return true/false based on success.
2266 TEST(ValuesTest, GetWithNullOutValue) {
2267 DictionaryValue main_dict;
2268 ListValue main_list;
2270 Value bool_value(false);
2271 Value int_value(1234);
2272 Value double_value(12.34567);
2273 Value string_value("foo");
2274 Value binary_value(Value::Type::BINARY);
2275 DictionaryValue dict_value;
2276 ListValue list_value;
2278 main_dict.SetKey("bool", bool_value.Clone());
2279 main_dict.SetKey("int", int_value.Clone());
2280 main_dict.SetKey("double", double_value.Clone());
2281 main_dict.SetKey("string", string_value.Clone());
2282 main_dict.SetKey("binary", binary_value.Clone());
2283 main_dict.SetKey("dict", dict_value.Clone());
2284 main_dict.SetKey("list", list_value.Clone());
2286 main_list.Append(bool_value.Clone());
2287 main_list.Append(int_value.Clone());
2288 main_list.Append(double_value.Clone());
2289 main_list.Append(string_value.Clone());
2290 main_list.Append(binary_value.Clone());
2291 main_list.Append(dict_value.Clone());
2292 main_list.Append(list_value.Clone());
2294 EXPECT_TRUE(main_dict.Get("bool", nullptr));
2295 EXPECT_TRUE(main_dict.Get("int", nullptr));
2296 EXPECT_TRUE(main_dict.Get("double", nullptr));
2297 EXPECT_TRUE(main_dict.Get("string", nullptr));
2298 EXPECT_TRUE(main_dict.Get("binary", nullptr));
2299 EXPECT_TRUE(main_dict.Get("dict", nullptr));
2300 EXPECT_TRUE(main_dict.Get("list", nullptr));
2301 EXPECT_FALSE(main_dict.Get("DNE", nullptr));
2303 EXPECT_FALSE(main_dict.GetInteger("bool", nullptr));
2304 EXPECT_TRUE(main_dict.GetInteger("int", nullptr));
2305 EXPECT_FALSE(main_dict.GetInteger("double", nullptr));
2306 EXPECT_FALSE(main_dict.GetInteger("string", nullptr));
2307 EXPECT_FALSE(main_dict.GetInteger("binary", nullptr));
2308 EXPECT_FALSE(main_dict.GetInteger("dict", nullptr));
2309 EXPECT_FALSE(main_dict.GetInteger("list", nullptr));
2310 EXPECT_FALSE(main_dict.GetInteger("DNE", nullptr));
2312 EXPECT_FALSE(main_dict.GetString("bool", static_cast<std::string*>(nullptr)));
2313 EXPECT_FALSE(main_dict.GetString("int", static_cast<std::string*>(nullptr)));
2315 main_dict.GetString("double", static_cast<std::string*>(nullptr)));
2317 main_dict.GetString("string", static_cast<std::string*>(nullptr)));
2319 main_dict.GetString("binary", static_cast<std::string*>(nullptr)));
2320 EXPECT_FALSE(main_dict.GetString("dict", static_cast<std::string*>(nullptr)));
2321 EXPECT_FALSE(main_dict.GetString("list", static_cast<std::string*>(nullptr)));
2322 EXPECT_FALSE(main_dict.GetString("DNE", static_cast<std::string*>(nullptr)));
2324 EXPECT_FALSE(main_dict.GetDictionary("bool", nullptr));
2325 EXPECT_FALSE(main_dict.GetDictionary("int", nullptr));
2326 EXPECT_FALSE(main_dict.GetDictionary("double", nullptr));
2327 EXPECT_FALSE(main_dict.GetDictionary("string", nullptr));
2328 EXPECT_FALSE(main_dict.GetDictionary("binary", nullptr));
2329 EXPECT_TRUE(main_dict.GetDictionary("dict", nullptr));
2330 EXPECT_FALSE(main_dict.GetDictionary("list", nullptr));
2331 EXPECT_FALSE(main_dict.GetDictionary("DNE", nullptr));
2333 EXPECT_FALSE(main_dict.GetList("bool", nullptr));
2334 EXPECT_FALSE(main_dict.GetList("int", nullptr));
2335 EXPECT_FALSE(main_dict.GetList("double", nullptr));
2336 EXPECT_FALSE(main_dict.GetList("string", nullptr));
2337 EXPECT_FALSE(main_dict.GetList("binary", nullptr));
2338 EXPECT_FALSE(main_dict.GetList("dict", nullptr));
2339 EXPECT_TRUE(main_dict.GetList("list", nullptr));
2340 EXPECT_FALSE(main_dict.GetList("DNE", nullptr));
2343 TEST(ValuesTest, SelfSwap) {
2344 base::Value test(1);
2345 std::swap(test, test);
2346 EXPECT_EQ(1, test.GetInt());
2349 TEST(ValuesTest, FromToUniquePtrValue) {
2350 std::unique_ptr<DictionaryValue> dict = std::make_unique<DictionaryValue>();
2351 dict->SetStringKey("name", "Froogle");
2352 dict->SetStringKey("url", "http://froogle.com");
2353 Value dict_copy = dict->Clone();
2355 Value dict_converted = Value::FromUniquePtrValue(std::move(dict));
2356 EXPECT_EQ(dict_copy, dict_converted);
2358 std::unique_ptr<Value> val =
2359 Value::ToUniquePtrValue(std::move(dict_converted));
2360 EXPECT_EQ(dict_copy, *val);
2363 TEST(ValuesTest, MutableFindStringPath) {
2365 dict.SetByDottedPath("foo.bar", "value");
2367 *(dict.FindStringByDottedPath("foo.bar")) = "new_value";
2369 Value::Dict expected_dict;
2370 expected_dict.SetByDottedPath("foo.bar", "new_value");
2372 EXPECT_EQ(expected_dict, dict);
2375 TEST(ValuesTest, MutableGetString) {
2376 Value value("value");
2377 value.GetString() = "new_value";
2378 EXPECT_EQ("new_value", value.GetString());
2381 #if BUILDFLAG(ENABLE_BASE_TRACING)
2382 TEST(ValuesTest, TracingSupport) {
2383 EXPECT_EQ(perfetto::TracedValueToString(Value(false)), "false");
2384 EXPECT_EQ(perfetto::TracedValueToString(Value(1)), "1");
2385 EXPECT_EQ(perfetto::TracedValueToString(Value(1.5)), "1.5");
2386 EXPECT_EQ(perfetto::TracedValueToString(Value("value")), "value");
2387 EXPECT_EQ(perfetto::TracedValueToString(Value(Value::Type::NONE)), "<none>");
2390 EXPECT_EQ(perfetto::TracedValueToString(list), "{}");
2393 EXPECT_EQ(perfetto::TracedValueToString(list), "[2,3]");
2394 EXPECT_EQ(perfetto::TracedValueToString(Value(std::move(list))), "[2,3]");
2398 EXPECT_EQ(perfetto::TracedValueToString(dict), "{}");
2399 dict.Set("key", "value");
2400 EXPECT_EQ(perfetto::TracedValueToString(dict), "{key:value}");
2401 EXPECT_EQ(perfetto::TracedValueToString(Value(std::move(dict))),
2405 #endif // BUILDFLAG(ENABLE_BASE_TRACING)
2407 TEST(DictAdapterForMigrationTest, ImplicitConstruction) {
2410 dict.Set("hello", "world");
2411 DictAdapterForMigration a = dict;
2412 EXPECT_EQ(&dict, &a.dict_for_test());
2415 DictionaryValue dict;
2416 dict.SetString("hello", "world");
2417 DictAdapterForMigration v = dict;
2418 EXPECT_EQ(&dict.GetDict(), &v.dict_for_test());
2422 TEST(DictAdapterForMigrationTest, BasicFunctions) {
2424 DictAdapterForMigration a = dict;
2426 EXPECT_TRUE(a.empty());
2427 EXPECT_EQ(a.size(), 0u);
2429 dict.Set("hello", "world");
2430 EXPECT_FALSE(a.empty());
2431 EXPECT_EQ(a.size(), 1u);
2433 EXPECT_EQ(dict.cbegin(), a.begin());
2434 EXPECT_EQ(dict.cend(), a.end());
2435 EXPECT_EQ(dict.cbegin(), a.cbegin());
2436 EXPECT_EQ(dict.cend(), a.cend());
2438 EXPECT_TRUE(a.contains("hello"));
2439 EXPECT_FALSE(a.contains("world"));
2441 EXPECT_EQ(a.Clone(), dict);
2443 EXPECT_EQ(a.DebugString(), dict.DebugString());
2446 TEST(DictAdapterForMigrationTest, Find) {
2448 dict.Set("null", Value());
2449 dict.Set("bool", true);
2451 dict.Set("double", 3.0);
2452 dict.Set("string", std::string("4"));
2453 dict.Set("blob", Value(Value::BlobStorage()));
2454 dict.Set("list", Value::List());
2455 dict.Set("dict", Value::Dict());
2456 DictAdapterForMigration a = dict;
2458 EXPECT_EQ(a.Find("n/a"), nullptr);
2459 EXPECT_EQ(*a.Find("null"), Value());
2460 EXPECT_EQ(a.FindBool("bool"), true);
2461 EXPECT_EQ(a.FindInt("int"), 2);
2462 EXPECT_EQ(a.FindDouble("double"), 3.0);
2463 EXPECT_EQ(*a.FindString("string"), "4");
2464 EXPECT_EQ(*a.FindBlob("blob"), Value::BlobStorage());
2465 EXPECT_EQ(*a.FindList("list"), Value::List());
2466 EXPECT_EQ(*a.FindDict("dict"), Value::Dict());
2468 EXPECT_EQ(a.FindByDottedPath("n/a"), nullptr);
2469 EXPECT_EQ(*a.FindByDottedPath("null"), Value());
2470 EXPECT_EQ(a.FindBoolByDottedPath("bool"), true);
2471 EXPECT_EQ(a.FindIntByDottedPath("int"), 2);
2472 EXPECT_EQ(a.FindDoubleByDottedPath("double"), 3.0);
2473 EXPECT_EQ(*a.FindStringByDottedPath("string"), "4");
2474 EXPECT_EQ(*a.FindBlobByDottedPath("blob"), Value::BlobStorage());
2475 EXPECT_EQ(*a.FindListByDottedPath("list"), Value::List());
2476 EXPECT_EQ(*a.FindDictByDottedPath("dict"), Value::Dict());
2479 TEST(ValueViewTest, BasicConstruction) {
2482 EXPECT_EQ(true, absl::get<bool>(v.data_view_for_test()));
2486 EXPECT_EQ(25, absl::get<int>(v.data_view_for_test()));
2490 EXPECT_DOUBLE_EQ(3.14, absl::get<ValueView::DoubleStorageForTest>(
2491 v.data_view_for_test()));
2494 ValueView v = StringPiece("hello world");
2495 EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2498 ValueView v = "hello world";
2499 EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2502 std::string str = "hello world";
2504 EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2508 dict.Set("hello", "world");
2510 EXPECT_EQ(dict, absl::get<std::reference_wrapper<const Value::Dict>>(
2511 v.data_view_for_test()));
2515 list.Append("hello");
2516 list.Append("world");
2518 EXPECT_EQ(list, absl::get<std::reference_wrapper<const Value::List>>(
2519 v.data_view_for_test()));
2523 TEST(ValueViewTest, ValueConstruction) {
2527 EXPECT_EQ(true, absl::get<bool>(v.data_view_for_test()));
2532 EXPECT_EQ(25, absl::get<int>(v.data_view_for_test()));
2537 EXPECT_DOUBLE_EQ(3.14, absl::get<ValueView::DoubleStorageForTest>(
2538 v.data_view_for_test()));
2541 Value val("hello world");
2543 EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2547 dict.Set("hello", "world");
2548 Value val(dict.Clone());
2550 EXPECT_EQ(dict, absl::get<std::reference_wrapper<const Value::Dict>>(
2551 v.data_view_for_test()));
2555 list.Append("hello");
2556 list.Append("world");
2557 Value val(list.Clone());
2559 EXPECT_EQ(list, absl::get<std::reference_wrapper<const Value::List>>(
2560 v.data_view_for_test()));
2564 TEST(ValueViewTest, ToValue) {
2567 Value to_val = ValueView(val).ToValue();
2568 EXPECT_EQ(val, to_val);
2572 Value to_val = ValueView(val).ToValue();
2573 EXPECT_EQ(val, to_val);
2577 Value to_val = ValueView(val).ToValue();
2578 EXPECT_EQ(val, to_val);
2581 Value val("hello world");
2582 Value to_val = ValueView(val).ToValue();
2583 EXPECT_EQ(val, to_val);
2587 dict.Set("hello", "world");
2588 Value val(dict.Clone());
2589 Value to_val = ValueView(val).ToValue();
2590 EXPECT_EQ(val, to_val);
2594 list.Append("hello");
2595 list.Append("world");
2596 Value val(list.Clone());
2597 Value to_val = ValueView(val).ToValue();
2598 EXPECT_EQ(val, to_val);