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_v<Value>,
73 "IsNothrowMoveConstructible");
74 static_assert(std::is_nothrow_default_constructible_v<Value>,
75 "IsNothrowDefaultConstructible");
76 static_assert(std::is_nothrow_constructible_v<Value, std::string&&>,
77 "IsNothrowMoveConstructibleFromString");
78 static_assert(std::is_nothrow_constructible_v<Value, Value::BlobStorage&&>,
79 "IsNothrowMoveConstructibleFromBlob");
80 static_assert(std::is_nothrow_move_assignable_v<Value>,
81 "IsNothrowMoveAssignable");
84 TEST(ValuesTest, EmptyValue) {
86 EXPECT_EQ(Value::Type::NONE, value.type());
87 EXPECT_EQ(absl::nullopt, value.GetIfBool());
88 EXPECT_EQ(absl::nullopt, value.GetIfInt());
89 EXPECT_EQ(absl::nullopt, value.GetIfDouble());
90 EXPECT_EQ(nullptr, value.GetIfString());
91 EXPECT_EQ(nullptr, value.GetIfBlob());
94 // Group of tests for the value constructors.
95 TEST(ValuesTest, ConstructBool) {
96 Value true_value(true);
97 EXPECT_EQ(Value::Type::BOOLEAN, true_value.type());
98 EXPECT_THAT(true_value.GetIfBool(), testing::Optional(true));
99 EXPECT_TRUE(true_value.GetBool());
101 Value false_value(false);
102 EXPECT_EQ(Value::Type::BOOLEAN, false_value.type());
103 EXPECT_THAT(false_value.GetIfBool(), testing::Optional(false));
104 EXPECT_FALSE(false_value.GetBool());
107 TEST(ValuesTest, ConstructFromPtrs) {
108 static_assert(!std::is_constructible_v<Value, int*>, "");
109 static_assert(!std::is_constructible_v<Value, const int*>, "");
110 static_assert(!std::is_constructible_v<Value, wchar_t*>, "");
111 static_assert(!std::is_constructible_v<Value, const wchar_t*>, "");
113 static_assert(std::is_constructible_v<Value, char*>, "");
114 static_assert(std::is_constructible_v<Value, const char*>, "");
115 static_assert(std::is_constructible_v<Value, char16_t*>, "");
116 static_assert(std::is_constructible_v<Value, const char16_t*>, "");
119 TEST(ValuesTest, ConstructInt) {
121 EXPECT_EQ(Value::Type::INTEGER, value.type());
122 EXPECT_THAT(value.GetIfInt(), testing::Optional(-37));
123 EXPECT_EQ(-37, value.GetInt());
125 EXPECT_THAT(value.GetIfDouble(), testing::Optional(-37.0));
126 EXPECT_EQ(-37.0, value.GetDouble());
129 TEST(ValuesTest, ConstructDouble) {
131 EXPECT_EQ(Value::Type::DOUBLE, value.type());
132 EXPECT_THAT(value.GetIfDouble(), testing::Optional(-4.655));
133 EXPECT_EQ(-4.655, value.GetDouble());
136 TEST(ValuesTest, ConstructStringFromConstCharPtr) {
137 const char* str = "foobar";
139 EXPECT_EQ(Value::Type::STRING, value.type());
140 EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
141 EXPECT_EQ("foobar", value.GetString());
144 TEST(ValuesTest, ConstructStringFromStringPiece) {
145 std::string str = "foobar";
146 Value value{StringPiece(str)};
147 EXPECT_EQ(Value::Type::STRING, value.type());
148 EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
149 EXPECT_EQ("foobar", value.GetString());
152 TEST(ValuesTest, ConstructStringFromStdStringRRef) {
153 std::string str = "foobar";
154 Value value(std::move(str));
155 EXPECT_EQ(Value::Type::STRING, value.type());
156 EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
157 EXPECT_EQ("foobar", value.GetString());
160 TEST(ValuesTest, ConstructStringFromConstChar16Ptr) {
161 std::u16string str = u"foobar";
162 Value value(str.c_str());
163 EXPECT_EQ(Value::Type::STRING, value.type());
164 EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
165 EXPECT_EQ("foobar", value.GetString());
168 TEST(ValuesTest, ConstructStringFromStringPiece16) {
169 std::u16string str = u"foobar";
170 Value value{StringPiece16(str)};
171 EXPECT_EQ(Value::Type::STRING, value.type());
172 EXPECT_THAT(value.GetIfString(), testing::Pointee(std::string("foobar")));
173 EXPECT_EQ("foobar", value.GetString());
176 TEST(ValuesTest, ConstructBinary) {
177 Value::BlobStorage blob = {0xF, 0x0, 0x0, 0xB, 0xA, 0x2};
179 EXPECT_EQ(Value::Type::BINARY, value.type());
180 EXPECT_THAT(value.GetIfBlob(), testing::Pointee(blob));
181 EXPECT_EQ(blob, value.GetBlob());
184 TEST(ValuesTest, ConstructDict) {
186 EXPECT_EQ(Value::Type::DICT, Value(std::move(value)).type());
189 TEST(ValuesTest, ConstructDictFromValueDict) {
191 dict.Set("foo", "bar");
193 Value value(dict.Clone());
194 EXPECT_EQ(Value::Type::DICT, value.type());
195 EXPECT_TRUE(value.GetIfDict());
196 EXPECT_TRUE(value.GetDict().FindString("foo"));
197 EXPECT_EQ("bar", *value.GetDict().FindString("foo"));
200 dict.Set("foo", "baz");
202 Value value(std::move(dict));
203 EXPECT_EQ(Value::Type::DICT, value.type());
204 EXPECT_TRUE(value.GetIfDict());
205 EXPECT_TRUE(value.GetDict().FindString("foo"));
206 EXPECT_EQ("baz", *value.GetDict().FindString("foo"));
210 TEST(ValuesTest, ConstructList) {
211 Value value(Value::List{});
212 EXPECT_EQ(Value::Type::LIST, value.type());
215 TEST(ValuesTest, UseTestingEachOnValueList) {
220 // This will only work if `Value::List::value_type` is defined.
221 EXPECT_THAT(list, testing::Each(testing::ResultOf(
222 [](const Value& value) { return value.GetBool(); },
223 testing::Eq(true))));
226 TEST(ValuesTest, ConstructListFromValueList) {
230 Value value(list.Clone());
231 EXPECT_EQ(Value::Type::LIST, value.type());
232 EXPECT_EQ(1u, value.GetList().size());
233 EXPECT_EQ(Value::Type::STRING, value.GetList()[0].type());
234 EXPECT_EQ("foo", value.GetList()[0].GetString());
237 list.back() = base::Value("bar");
239 Value value(std::move(list));
240 EXPECT_EQ(Value::Type::LIST, value.type());
241 EXPECT_EQ(1u, value.GetList().size());
242 EXPECT_EQ(Value::Type::STRING, value.GetList()[0].type());
243 EXPECT_EQ("bar", value.GetList()[0].GetString());
247 TEST(ValuesTest, HardenTests) {
249 ASSERT_EQ(value.type(), Value::Type::NONE);
250 EXPECT_DEATH_IF_SUPPORTED(value.GetBool(), "");
251 EXPECT_DEATH_IF_SUPPORTED(value.GetInt(), "");
252 EXPECT_DEATH_IF_SUPPORTED(value.GetDouble(), "");
253 EXPECT_DEATH_IF_SUPPORTED(value.GetString(), "");
254 EXPECT_DEATH_IF_SUPPORTED(value.GetBlob(), "");
257 // Group of tests for the copy constructors and copy-assigmnent. For equality
258 // checks comparisons of the interesting fields are done instead of relying on
259 // Equals being correct.
260 TEST(ValuesTest, CopyBool) {
261 Value true_value(true);
262 Value copied_true_value(true_value.Clone());
263 EXPECT_EQ(true_value.type(), copied_true_value.type());
264 EXPECT_EQ(true_value.GetBool(), copied_true_value.GetBool());
266 Value false_value(false);
267 Value copied_false_value(false_value.Clone());
268 EXPECT_EQ(false_value.type(), copied_false_value.type());
269 EXPECT_EQ(false_value.GetBool(), copied_false_value.GetBool());
273 blank = true_value.Clone();
274 EXPECT_EQ(true_value.type(), blank.type());
275 EXPECT_EQ(true_value.GetBool(), blank.GetBool());
277 blank = false_value.Clone();
278 EXPECT_EQ(false_value.type(), blank.type());
279 EXPECT_EQ(false_value.GetBool(), blank.GetBool());
282 TEST(ValuesTest, CopyInt) {
284 Value copied_value(value.Clone());
285 EXPECT_EQ(value.type(), copied_value.type());
286 EXPECT_EQ(value.GetInt(), copied_value.GetInt());
290 blank = value.Clone();
291 EXPECT_EQ(value.type(), blank.type());
292 EXPECT_EQ(value.GetInt(), blank.GetInt());
295 TEST(ValuesTest, CopyDouble) {
297 Value copied_value(value.Clone());
298 EXPECT_EQ(value.type(), copied_value.type());
299 EXPECT_EQ(value.GetDouble(), copied_value.GetDouble());
303 blank = value.Clone();
304 EXPECT_EQ(value.type(), blank.type());
305 EXPECT_EQ(value.GetDouble(), blank.GetDouble());
308 TEST(ValuesTest, CopyString) {
309 Value value("foobar");
310 Value copied_value(value.Clone());
311 EXPECT_EQ(value.type(), copied_value.type());
312 EXPECT_EQ(value.GetString(), copied_value.GetString());
316 blank = value.Clone();
317 EXPECT_EQ(value.type(), blank.type());
318 EXPECT_EQ(value.GetString(), blank.GetString());
321 TEST(ValuesTest, CopyBinary) {
322 Value value(Value::BlobStorage({0xF, 0x0, 0x0, 0xB, 0xA, 0x2}));
323 Value copied_value(value.Clone());
324 EXPECT_EQ(value.type(), copied_value.type());
325 EXPECT_EQ(value.GetBlob(), copied_value.GetBlob());
329 blank = value.Clone();
330 EXPECT_EQ(value.type(), blank.type());
331 EXPECT_EQ(value.GetBlob(), blank.GetBlob());
334 TEST(ValuesTest, CopyDictionary) {
336 dict.Set("Int", 123);
337 Value value(std::move(dict));
339 Value copied_value(value.Clone());
340 EXPECT_EQ(value, copied_value);
343 blank = value.Clone();
344 EXPECT_EQ(value, blank);
347 TEST(ValuesTest, CopyList) {
350 Value value(std::move(list));
352 Value copied_value(value.Clone());
353 EXPECT_EQ(value, copied_value);
356 blank = value.Clone();
357 EXPECT_EQ(value, blank);
360 // Group of tests for the move constructors and move-assigmnent.
361 TEST(ValuesTest, MoveBool) {
362 Value true_value(true);
363 Value moved_true_value(std::move(true_value));
364 EXPECT_EQ(Value::Type::BOOLEAN, moved_true_value.type());
365 EXPECT_TRUE(moved_true_value.GetBool());
367 Value false_value(false);
368 Value moved_false_value(std::move(false_value));
369 EXPECT_EQ(Value::Type::BOOLEAN, moved_false_value.type());
370 EXPECT_FALSE(moved_false_value.GetBool());
375 EXPECT_EQ(Value::Type::BOOLEAN, blank.type());
376 EXPECT_TRUE(blank.GetBool());
378 blank = Value(false);
379 EXPECT_EQ(Value::Type::BOOLEAN, blank.type());
380 EXPECT_FALSE(blank.GetBool());
383 TEST(ValuesTest, MoveInt) {
385 Value moved_value(std::move(value));
386 EXPECT_EQ(Value::Type::INTEGER, moved_value.type());
387 EXPECT_EQ(74, moved_value.GetInt());
392 EXPECT_EQ(Value::Type::INTEGER, blank.type());
393 EXPECT_EQ(47, blank.GetInt());
396 TEST(ValuesTest, MoveDouble) {
398 Value moved_value(std::move(value));
399 EXPECT_EQ(Value::Type::DOUBLE, moved_value.type());
400 EXPECT_EQ(74.896, moved_value.GetDouble());
404 blank = Value(654.38);
405 EXPECT_EQ(Value::Type::DOUBLE, blank.type());
406 EXPECT_EQ(654.38, blank.GetDouble());
409 TEST(ValuesTest, MoveString) {
410 Value value("foobar");
411 Value moved_value(std::move(value));
412 EXPECT_EQ(Value::Type::STRING, moved_value.type());
413 EXPECT_EQ("foobar", moved_value.GetString());
417 blank = Value("foobar");
418 EXPECT_EQ(Value::Type::STRING, blank.type());
419 EXPECT_EQ("foobar", blank.GetString());
422 TEST(ValuesTest, MoveBinary) {
423 const Value::BlobStorage buffer = {0xF, 0x0, 0x0, 0xB, 0xA, 0x2};
425 Value moved_value(std::move(value));
426 EXPECT_EQ(Value::Type::BINARY, moved_value.type());
427 EXPECT_EQ(buffer, moved_value.GetBlob());
431 blank = Value(buffer);
432 EXPECT_EQ(Value::Type::BINARY, blank.type());
433 EXPECT_EQ(buffer, blank.GetBlob());
436 TEST(ValuesTest, MoveConstructDictionary) {
438 dict.Set("Int", 123);
440 Value value(std::move(dict));
441 Value moved_value(std::move(value));
442 EXPECT_EQ(Value::Type::DICT, moved_value.type());
443 EXPECT_EQ(123, moved_value.GetDict().Find("Int")->GetInt());
446 TEST(ValuesTest, MoveAssignDictionary) {
448 dict.Set("Int", 123);
451 blank = Value(std::move(dict));
452 EXPECT_EQ(Value::Type::DICT, blank.type());
453 EXPECT_EQ(123, blank.GetDict().Find("Int")->GetInt());
456 TEST(ValuesTest, ConstructDictWithIterators) {
457 std::vector<std::pair<std::string, Value>> values;
458 values.emplace_back(std::make_pair("Int", 123));
461 blank = Value(Value::Dict(std::make_move_iterator(values.begin()),
462 std::make_move_iterator(values.end())));
463 EXPECT_EQ(Value::Type::DICT, blank.type());
464 EXPECT_EQ(123, blank.GetDict().Find("Int")->GetInt());
467 TEST(ValuesTest, MoveList) {
470 Value value(list.Clone());
471 Value moved_value(std::move(value));
472 EXPECT_EQ(Value::Type::LIST, moved_value.type());
473 EXPECT_EQ(123, moved_value.GetList().back().GetInt());
476 blank = Value(std::move(list));
477 EXPECT_EQ(Value::Type::LIST, blank.type());
478 EXPECT_EQ(123, blank.GetList().back().GetInt());
481 TEST(ValuesTest, Append) {
484 EXPECT_TRUE(list.back().is_bool());
487 EXPECT_TRUE(list.back().is_int());
490 EXPECT_TRUE(list.back().is_double());
492 std::string str = "foo";
493 list.Append(str.c_str());
494 EXPECT_TRUE(list.back().is_string());
496 list.Append(StringPiece(str));
497 EXPECT_TRUE(list.back().is_string());
499 list.Append(std::move(str));
500 EXPECT_TRUE(list.back().is_string());
502 std::u16string str16 = u"bar";
503 list.Append(str16.c_str());
504 EXPECT_TRUE(list.back().is_string());
506 list.Append(base::StringPiece16(str16));
507 EXPECT_TRUE(list.back().is_string());
509 list.Append(Value());
510 EXPECT_TRUE(list.back().is_none());
512 list.Append(Value::Dict());
513 EXPECT_TRUE(list.back().is_dict());
515 list.Append(Value::List());
516 EXPECT_TRUE(list.back().is_list());
519 TEST(ValuesTest, ListInsert) {
521 const Value::List& const_list = list;
523 auto iter = list.Insert(list.end(), Value(true));
524 EXPECT_TRUE(list.begin() == iter);
525 EXPECT_EQ(*iter, true);
527 iter = list.Insert(const_list.begin(), Value(123));
528 EXPECT_TRUE(const_list.begin() == iter);
529 EXPECT_EQ(*iter, 123);
531 iter = list.Insert(list.begin() + 1, Value("Hello world!"));
532 EXPECT_TRUE(list.begin() + 1 == iter);
533 EXPECT_EQ(*iter, "Hello world!");
536 TEST(ValuesTest, ListResize) {
537 auto list = base::Value::List().Append("Hello world!");
538 EXPECT_EQ(list.size(), 1U);
541 // Adds an empty entry to the back to match the size.
542 EXPECT_EQ(list.size(), 2U);
543 EXPECT_TRUE(list[0].is_string());
544 EXPECT_TRUE(list[1].is_none());
547 // Shrinks the list and kicks the new entry out.
548 EXPECT_EQ(list.size(), 1U);
549 EXPECT_TRUE(list[0].is_string());
552 // Removes the remaining entry too.
553 EXPECT_EQ(list.size(), 0U);
556 TEST(ValuesTest, ReverseIter) {
558 const Value::List& const_list = list;
560 list.Append(Value(true));
561 list.Append(Value(123));
562 list.Append(Value("Hello world!"));
564 auto iter = list.rbegin();
565 EXPECT_TRUE(const_list.rbegin() == iter);
566 EXPECT_EQ(*iter, "Hello world!");
569 EXPECT_EQ(*iter, 123);
572 EXPECT_EQ(*iter, true);
575 EXPECT_TRUE(list.rend() == iter);
576 EXPECT_TRUE(const_list.rend() == iter);
579 // Test all three behaviors of EnsureDict() (Create a new dict where no
580 // matchining values exist, return an existing dict, create a dict overwriting
581 // a value of another type).
582 TEST(ValuesTest, DictEnsureDict) {
585 // This call should create a new nested dictionary.
586 Value::Dict* foo_dict = root.EnsureDict("foo");
587 EXPECT_TRUE(foo_dict->empty());
588 foo_dict->Set("a", "b");
590 // This call should retrieve the dictionary created above, rather than
591 // creating a new one.
592 std::string* a_string = root.EnsureDict("foo")->FindString("a");
593 ASSERT_NE(nullptr, a_string);
594 EXPECT_EQ(*a_string, "b");
596 // Use EnsureDict() to overwrite an existing non-dictionary value.
598 Value::Dict* bar_dict = root.EnsureDict("bar");
599 EXPECT_TRUE(bar_dict->empty());
600 bar_dict->Set("b", "c");
602 // Test that the above call created a "bar" entry.
603 bar_dict = root.FindDict("bar");
604 ASSERT_NE(nullptr, bar_dict);
605 std::string* b_string = bar_dict->FindString("b");
606 ASSERT_NE(nullptr, b_string);
607 EXPECT_EQ(*b_string, "c");
610 // Test all three behaviors of EnsureList() (Create a new list where no
611 // matchining value exists, return an existing list, create a list overwriting
612 // a value of another type).
613 TEST(ValuesTest, DictEnsureList) {
616 // This call should create a new list.
617 Value::List* foo_list = root.EnsureList("foo");
618 EXPECT_TRUE(foo_list->empty());
619 foo_list->Append("a");
621 // This call should retrieve the list created above, rather than creating a
623 foo_list = root.EnsureList("foo");
624 ASSERT_EQ(1u, foo_list->size());
625 EXPECT_EQ((*foo_list)[0], Value("a"));
627 // Use EnsureList() to overwrite an existing non-list value.
629 Value::List* bar_list = root.EnsureList("bar");
630 EXPECT_TRUE(bar_list->empty());
631 bar_list->Append("b");
633 // Test that the above call created a "bar" entry.
634 bar_list = root.FindList("bar");
635 ASSERT_NE(nullptr, bar_list);
636 ASSERT_EQ(1u, bar_list->size());
637 EXPECT_EQ((*bar_list)[0], Value("b"));
640 // TODO(dcheng): Add more tests directly exercising the updated dictionary and
641 // list APIs. For now, most of the updated APIs are tested indirectly via the
642 // legacy APIs that are largely backed by the updated APIs.
643 TEST(ValuesTest, DictFindByDottedPath) {
646 EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
648 Value::Dict& a_dict = dict.Set("a", Value::Dict())->GetDict();
649 EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
651 Value::Dict& b_dict = a_dict.Set("b", Value::Dict())->GetDict();
652 EXPECT_EQ(nullptr, dict.FindByDottedPath("a.b.c"));
654 b_dict.Set("c", true);
655 const Value* value = dict.FindByDottedPath("a.b.c");
656 ASSERT_NE(nullptr, value);
657 EXPECT_TRUE(value->GetBool());
660 TEST(ValuesTest, DictSetByDottedPath) {
663 Value* c = dict.SetByDottedPath("a.b.c", Value());
666 Value::Dict* a = dict.FindDict("a");
668 EXPECT_EQ(1U, a->size());
670 Value::Dict* b = a->FindDict("b");
672 EXPECT_EQ(1U, b->size());
674 EXPECT_EQ(c, b->Find("c"));
677 TEST(ValuesTest, RvalueDictSetByDottedPath) {
680 .SetByDottedPath("nested.dictionary.null", Value())
681 .SetByDottedPath("nested.dictionary.bool", false)
682 .SetByDottedPath("nested.dictionary.int", 42)
683 .SetByDottedPath("nested.dictionary.double", 1.2)
684 .SetByDottedPath("nested.dictionary.string", "value")
685 .SetByDottedPath("nested.dictionary.u16-string", u"u16-value")
686 .SetByDottedPath("nested.dictionary.std-string",
687 std::string("std-value"))
688 .SetByDottedPath("nested.dictionary.blob", Value::BlobStorage({1, 2}))
689 .SetByDottedPath("nested.dictionary.list",
690 Value::List().Append("value in list"))
691 .SetByDottedPath("nested.dictionary.dict",
692 Value::Dict().Set("key", "value"));
694 Value::Dict expected =
697 base::Value::Dict() //
700 .Set("null", Value())
704 .Set("string", "value")
705 .Set("u16-string", u"u16-value")
706 .Set("std-string", std::string("std-value"))
707 .Set("blob", Value::BlobStorage({1, 2}))
708 .Set("list", Value::List().Append("value in list"))
709 .Set("dict", Value::Dict().Set("key", "value"))));
711 EXPECT_EQ(dict, expected);
714 TEST(ValuesTest, DictSetWithDottedKey) {
717 Value* abc = dict.Set("a.b.c", Value());
720 EXPECT_FALSE(dict.FindByDottedPath("a"));
721 EXPECT_FALSE(dict.FindByDottedPath("a.b"));
722 EXPECT_FALSE(dict.FindByDottedPath("a.b.c"));
724 EXPECT_EQ(abc, dict.Find("a.b.c"));
727 TEST(ValuesTest, ListFront) {
729 const Value::List& const_list = list;
735 EXPECT_EQ(Value(1), list.front());
736 EXPECT_EQ(Value(1), const_list.front());
739 TEST(ValuesTest, ListFrontWhenEmpty) {
741 const Value::List& const_list = list;
743 EXPECT_CHECK_DEATH(list.front());
744 EXPECT_CHECK_DEATH(const_list.front());
747 TEST(ValuesTest, ListBack) {
749 const Value::List& const_list = list;
755 EXPECT_EQ(Value(3), list.back());
756 EXPECT_EQ(Value(3), const_list.back());
759 TEST(ValuesTest, ListBackWhenEmpty) {
761 const Value::List& const_list = list;
763 EXPECT_CHECK_DEATH(list.back());
764 EXPECT_CHECK_DEATH(const_list.back());
767 TEST(ValuesTest, ListErase) {
773 auto next_it = list.erase(list.begin() + 1);
774 ASSERT_EQ(2u, list.size());
775 EXPECT_EQ(list[0], Value(1));
776 EXPECT_EQ(list[1], Value(3));
777 EXPECT_EQ(*next_it, Value(3));
778 EXPECT_EQ(next_it + 1, list.end());
781 TEST(ValuesTest, ListEraseRange) {
788 auto next_it = list.erase(list.begin() + 1, list.begin() + 3);
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());
795 next_it = list.erase(list.begin() + 1, list.begin() + 1);
796 ASSERT_EQ(2u, list.size());
797 EXPECT_EQ(list[0], Value(1));
798 EXPECT_EQ(list[1], Value(4));
799 EXPECT_EQ(*next_it, Value(4));
800 EXPECT_EQ(next_it + 1, list.end());
802 next_it = list.erase(list.begin() + 1, list.end());
803 ASSERT_EQ(1u, list.size());
804 EXPECT_EQ(list[0], Value(1));
805 EXPECT_EQ(next_it, list.end());
808 next_it = list.erase(list.begin(), list.begin());
809 ASSERT_EQ(0u, list.size());
810 EXPECT_EQ(next_it, list.begin());
811 EXPECT_EQ(next_it, list.end());
814 TEST(ValuesTest, ListEraseValue) {
821 EXPECT_EQ(2u, list.EraseValue(Value(2)));
822 EXPECT_EQ(2u, list.size());
823 EXPECT_EQ(1, list[0]);
824 EXPECT_EQ(3, list[1]);
826 EXPECT_EQ(1u, list.EraseValue(Value(1)));
827 EXPECT_EQ(1u, list.size());
828 EXPECT_EQ(3, list[0]);
830 EXPECT_EQ(1u, list.EraseValue(Value(3)));
831 EXPECT_TRUE(list.empty());
833 EXPECT_EQ(0u, list.EraseValue(Value(3)));
836 TEST(ValuesTest, ListEraseIf) {
843 EXPECT_EQ(3u, list.EraseIf([](const auto& val) { return val >= Value(2); }));
844 EXPECT_EQ(1u, list.size());
845 EXPECT_EQ(1, list[0]);
847 EXPECT_EQ(1u, list.EraseIf([](const auto& val) { return true; }));
848 EXPECT_TRUE(list.empty());
850 EXPECT_EQ(0u, list.EraseIf([](const auto& val) { return true; }));
853 TEST(ValuesTest, ClearList) {
858 EXPECT_EQ(3u, list.size());
859 EXPECT_FALSE(list.empty());
862 EXPECT_EQ(0u, list.size());
863 EXPECT_TRUE(list.empty());
865 // list.clear() should be idempotent.
867 EXPECT_EQ(0u, list.size());
868 EXPECT_TRUE(list.empty());
871 TEST(ValuesTest, FindKey) {
873 dict.Set("foo", "bar");
874 Value value(std::move(dict));
875 EXPECT_NE(nullptr, value.GetDict().Find("foo"));
876 EXPECT_EQ(nullptr, value.GetDict().Find("baz"));
879 TEST(ValuesTest, FindKeyChangeValue) {
881 dict.Set("foo", "bar");
882 Value* found = dict.Find("foo");
883 ASSERT_NE(nullptr, found);
884 EXPECT_EQ("bar", found->GetString());
887 EXPECT_EQ(123, dict.Find("foo")->GetInt());
890 TEST(ValuesTest, FindKeyConst) {
892 dict.Set("foo", "bar");
893 const Value value(std::move(dict));
894 EXPECT_NE(nullptr, value.GetDict().Find("foo"));
895 EXPECT_EQ(nullptr, value.GetDict().Find("baz"));
898 TEST(ValuesTest, FindBoolKey) {
900 dict.Set("null", Value());
901 dict.Set("bool", false);
903 dict.Set("double", 0.0);
904 dict.Set("string", std::string());
905 dict.Set("blob", Value(Value::BlobStorage()));
906 dict.Set("list", Value::List());
907 dict.Set("dict", Value::Dict());
909 EXPECT_EQ(absl::nullopt, dict.FindBool("null"));
910 EXPECT_NE(absl::nullopt, dict.FindBool("bool"));
911 EXPECT_EQ(absl::nullopt, dict.FindBool("int"));
912 EXPECT_EQ(absl::nullopt, dict.FindBool("double"));
913 EXPECT_EQ(absl::nullopt, dict.FindBool("string"));
914 EXPECT_EQ(absl::nullopt, dict.FindBool("blob"));
915 EXPECT_EQ(absl::nullopt, dict.FindBool("list"));
916 EXPECT_EQ(absl::nullopt, dict.FindBool("dict"));
919 TEST(ValuesTest, FindIntKey) {
921 dict.Set("null", Value());
922 dict.Set("bool", false);
924 dict.Set("double", 0.0);
925 dict.Set("string", std::string());
926 dict.Set("blob", Value(Value::BlobStorage()));
927 dict.Set("list", Value::List());
928 dict.Set("dict", Value::Dict());
930 EXPECT_EQ(absl::nullopt, dict.FindInt("null"));
931 EXPECT_EQ(absl::nullopt, dict.FindInt("bool"));
932 EXPECT_NE(absl::nullopt, dict.FindInt("int"));
933 EXPECT_EQ(absl::nullopt, dict.FindInt("double"));
934 EXPECT_EQ(absl::nullopt, dict.FindInt("string"));
935 EXPECT_EQ(absl::nullopt, dict.FindInt("blob"));
936 EXPECT_EQ(absl::nullopt, dict.FindInt("list"));
937 EXPECT_EQ(absl::nullopt, dict.FindInt("dict"));
940 TEST(ValuesTest, FindStringKey) {
942 dict.Set("null", Value());
943 dict.Set("bool", false);
945 dict.Set("double", 0.0);
946 dict.Set("string", std::string());
947 dict.Set("blob", Value(Value::BlobStorage()));
948 dict.Set("list", Value::List());
949 dict.Set("dict", Value::Dict());
951 EXPECT_EQ(nullptr, dict.FindString("null"));
952 EXPECT_EQ(nullptr, dict.FindString("bool"));
953 EXPECT_EQ(nullptr, dict.FindString("int"));
954 EXPECT_EQ(nullptr, dict.FindString("double"));
955 EXPECT_NE(nullptr, dict.FindString("string"));
956 EXPECT_EQ(nullptr, dict.FindString("blob"));
957 EXPECT_EQ(nullptr, dict.FindString("list"));
958 EXPECT_EQ(nullptr, dict.FindString("dict"));
961 TEST(ValuesTest, MutableFindStringKey) {
963 dict.Set("string", "foo");
965 *(dict.FindString("string")) = "bar";
967 Value::Dict expected_dict;
968 expected_dict.Set("string", "bar");
970 EXPECT_EQ(expected_dict, dict);
972 Value value(std::move(dict));
973 Value expected_value(std::move(expected_dict));
974 EXPECT_EQ(expected_value, value);
977 TEST(ValuesTest, FindDictKey) {
979 dict.Set("null", Value());
980 dict.Set("bool", false);
982 dict.Set("double", 0.0);
983 dict.Set("string", std::string());
984 dict.Set("blob", Value(Value::BlobStorage()));
985 dict.Set("list", Value::List());
986 dict.Set("dict", Value::Dict());
988 EXPECT_EQ(nullptr, dict.FindDict("null"));
989 EXPECT_EQ(nullptr, dict.FindDict("bool"));
990 EXPECT_EQ(nullptr, dict.FindDict("int"));
991 EXPECT_EQ(nullptr, dict.FindDict("double"));
992 EXPECT_EQ(nullptr, dict.FindDict("string"));
993 EXPECT_EQ(nullptr, dict.FindDict("blob"));
994 EXPECT_EQ(nullptr, dict.FindDict("list"));
995 EXPECT_NE(nullptr, dict.FindDict("dict"));
998 TEST(ValuesTest, FindListKey) {
1000 dict.Set("null", Value());
1001 dict.Set("bool", false);
1003 dict.Set("double", 0.0);
1004 dict.Set("string", std::string());
1005 dict.Set("blob", Value(Value::BlobStorage()));
1006 dict.Set("list", Value::List());
1007 dict.Set("dict", Value::Dict());
1009 EXPECT_EQ(nullptr, dict.FindList("null"));
1010 EXPECT_EQ(nullptr, dict.FindList("bool"));
1011 EXPECT_EQ(nullptr, dict.FindList("int"));
1012 EXPECT_EQ(nullptr, dict.FindList("double"));
1013 EXPECT_EQ(nullptr, dict.FindList("string"));
1014 EXPECT_EQ(nullptr, dict.FindList("blob"));
1015 EXPECT_NE(nullptr, dict.FindList("list"));
1016 EXPECT_EQ(nullptr, dict.FindList("dict"));
1019 TEST(ValuesTest, FindBlob) {
1021 dict.Set("null", Value());
1022 dict.Set("bool", false);
1024 dict.Set("double", 0.0);
1025 dict.Set("string", std::string());
1026 dict.Set("blob", Value(Value::BlobStorage()));
1027 dict.Set("list", Value::List());
1028 dict.Set("dict", Value::Dict());
1030 EXPECT_EQ(nullptr, dict.FindBlob("null"));
1031 EXPECT_EQ(nullptr, dict.FindBlob("bool"));
1032 EXPECT_EQ(nullptr, dict.FindBlob("int"));
1033 EXPECT_EQ(nullptr, dict.FindBlob("double"));
1034 EXPECT_EQ(nullptr, dict.FindBlob("string"));
1035 EXPECT_NE(nullptr, dict.FindBlob("blob"));
1036 EXPECT_EQ(nullptr, dict.FindBlob("list"));
1037 EXPECT_EQ(nullptr, dict.FindBlob("dict"));
1040 TEST(ValuesTest, SetKey) {
1042 dict.Set("null", Value());
1043 dict.Set("bool", false);
1045 dict.Set("double", 0.0);
1046 dict.Set("string", std::string());
1047 dict.Set("blob", Value(Value::BlobStorage()));
1048 dict.Set("list", Value::List());
1049 dict.Set("dict", Value::Dict());
1052 dict2.Set(StringPiece("null"), Value(Value::Type::NONE));
1053 dict2.Set(StringPiece("bool"), Value(Value::Type::BOOLEAN));
1054 dict2.Set(std::string("int"), Value(Value::Type::INTEGER));
1055 dict2.Set(std::string("double"), Value(Value::Type::DOUBLE));
1056 dict2.Set(std::string("string"), Value(Value::Type::STRING));
1057 dict2.Set("blob", Value(Value::Type::BINARY));
1058 dict2.Set("list", Value(Value::Type::LIST));
1059 dict2.Set("dict", Value(Value::Type::DICT));
1061 EXPECT_EQ(dict, dict2);
1062 EXPECT_EQ(Value(std::move(dict)), Value(std::move(dict2)));
1065 TEST(ValuesTest, SetBoolKey) {
1066 absl::optional<bool> value;
1069 dict.Set("true_key", true);
1070 dict.Set("false_key", false);
1072 value = dict.FindBool("true_key");
1074 ASSERT_TRUE(*value);
1076 value = dict.FindBool("false_key");
1078 ASSERT_FALSE(*value);
1080 value = dict.FindBool("missing_key");
1081 ASSERT_FALSE(value);
1084 TEST(ValuesTest, SetIntKey) {
1085 absl::optional<int> value;
1088 dict.Set("one_key", 1);
1089 dict.Set("minus_one_key", -1);
1091 value = dict.FindInt("one_key");
1093 ASSERT_EQ(1, *value);
1095 value = dict.FindInt("minus_one_key");
1097 ASSERT_EQ(-1, *value);
1099 value = dict.FindInt("missing_key");
1100 ASSERT_FALSE(value);
1103 TEST(ValuesTest, SetDoubleKey) {
1105 dict.Set("one_key", 1.0);
1106 dict.Set("minus_one_key", -1.0);
1107 dict.Set("pi_key", 3.1415);
1111 value = dict.Find("one_key");
1113 EXPECT_TRUE(value->is_double());
1114 EXPECT_EQ(1.0, value->GetDouble());
1116 value = dict.Find("minus_one_key");
1118 EXPECT_TRUE(value->is_double());
1119 EXPECT_EQ(-1.0, value->GetDouble());
1121 value = dict.Find("pi_key");
1123 EXPECT_TRUE(value->is_double());
1124 EXPECT_EQ(3.1415, value->GetDouble());
1127 TEST(ValuesTest, SetStringKey) {
1129 dict.Set("one_key", "one");
1130 dict.Set("hello_key", "hello world");
1132 std::string movable_value("movable_value");
1133 dict.Set("movable_key", std::move(movable_value));
1134 ASSERT_TRUE(movable_value.empty());
1136 const std::string* value;
1138 value = dict.FindString("one_key");
1140 ASSERT_EQ("one", *value);
1142 value = dict.FindString("hello_key");
1144 ASSERT_EQ("hello world", *value);
1146 value = dict.FindString("movable_key");
1148 ASSERT_EQ("movable_value", *value);
1150 value = dict.FindString("missing_key");
1151 ASSERT_FALSE(value);
1154 TEST(ValuesTest, RvalueSet) {
1155 Value::Dict dict = Value::Dict()
1156 .Set("null", Value())
1160 .Set("string", "value")
1161 .Set("u16-string", u"u16-value")
1162 .Set("std-string", std::string("std-value"))
1163 .Set("blob", Value::BlobStorage({1, 2}))
1164 .Set("list", Value::List().Append("value in list"))
1165 .Set("dict", Value::Dict().Set("key", "value"));
1167 Value::Dict expected;
1168 expected.Set("null", Value());
1169 expected.Set("bool", false);
1170 expected.Set("int", 42);
1171 expected.Set("double", 1.2);
1172 expected.Set("string", "value");
1173 expected.Set("u16-string", u"u16-value");
1174 expected.Set("std-string", std::string("std-value"));
1175 expected.Set("blob", Value::BlobStorage({1, 2}));
1176 Value::List nested_list;
1177 nested_list.Append("value in list");
1178 expected.Set("list", std::move(nested_list));
1179 Value::Dict nested_dict;
1180 nested_dict.Set("key", "value");
1181 expected.Set("dict", std::move(nested_dict));
1183 EXPECT_EQ(dict, expected);
1186 TEST(ValuesTest, FindPath) {
1187 // Construct a dictionary path {root}.foo.bar = 123
1189 foo.Set("bar", Value(123));
1192 root.Set("foo", std::move(foo));
1194 // Double key, second not found.
1195 Value* found = root.FindByDottedPath("foo.notfound");
1196 EXPECT_FALSE(found);
1198 // Double key, found.
1199 found = root.FindByDottedPath("foo.bar");
1201 EXPECT_TRUE(found->is_int());
1202 EXPECT_EQ(123, found->GetInt());
1205 TEST(ValuesTest, SetByDottedPath) {
1208 Value* inserted = root.SetByDottedPath("one.two", Value(123));
1209 Value* found = root.FindByDottedPath("one.two");
1211 EXPECT_EQ(found->type(), Value::Type::INTEGER);
1212 EXPECT_EQ(inserted, found);
1213 EXPECT_EQ(123, found->GetInt());
1215 inserted = root.SetByDottedPath("foo.bar", Value(123));
1216 found = root.FindByDottedPath("foo.bar");
1218 EXPECT_EQ(found->type(), Value::Type::INTEGER);
1219 EXPECT_EQ(inserted, found);
1220 EXPECT_EQ(123, found->GetInt());
1222 // Overwrite with a different value.
1223 root.SetByDottedPath("foo.bar", Value("hello"));
1224 found = root.FindByDottedPath("foo.bar");
1226 EXPECT_EQ(found->type(), Value::Type::STRING);
1227 EXPECT_EQ("hello", found->GetString());
1229 // Can't change existing non-dictionary keys to dictionaries.
1230 found = root.SetByDottedPath("foo.bar.baz", Value(123));
1231 EXPECT_FALSE(found);
1234 TEST(ValuesTest, SetBoolPath) {
1236 Value* inserted = root.SetByDottedPath("foo.bar", true);
1237 Value* found = root.FindByDottedPath("foo.bar");
1239 EXPECT_EQ(inserted, found);
1240 ASSERT_TRUE(found->is_bool());
1241 EXPECT_TRUE(found->GetBool());
1243 // Overwrite with a different value.
1244 root.SetByDottedPath("foo.bar", false);
1245 found = root.FindByDottedPath("foo.bar");
1247 ASSERT_TRUE(found->is_bool());
1248 EXPECT_FALSE(found->GetBool());
1250 // Can't change existing non-dictionary keys.
1251 ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", true));
1254 TEST(ValuesTest, SetIntPath) {
1256 Value* inserted = root.SetByDottedPath("foo.bar", 123);
1257 Value* found = root.FindByDottedPath("foo.bar");
1259 EXPECT_EQ(inserted, found);
1260 ASSERT_TRUE(found->is_int());
1261 EXPECT_EQ(123, found->GetInt());
1263 // Overwrite with a different value.
1264 root.SetByDottedPath("foo.bar", 234);
1265 found = root.FindByDottedPath("foo.bar");
1267 ASSERT_TRUE(found->is_int());
1268 EXPECT_EQ(234, found->GetInt());
1270 // Can't change existing non-dictionary keys.
1271 ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", 567));
1274 TEST(ValuesTest, SetDoublePath) {
1276 Value* inserted = root.SetByDottedPath("foo.bar", 1.23);
1277 Value* found = root.FindByDottedPath("foo.bar");
1279 EXPECT_EQ(inserted, found);
1280 ASSERT_TRUE(found->is_double());
1281 EXPECT_EQ(1.23, found->GetDouble());
1283 // Overwrite with a different value.
1284 root.SetByDottedPath("foo.bar", 2.34);
1285 found = root.FindByDottedPath("foo.bar");
1287 ASSERT_TRUE(found->is_double());
1288 EXPECT_EQ(2.34, found->GetDouble());
1290 // Can't change existing non-dictionary keys.
1291 ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", 5.67));
1294 TEST(ValuesTest, SetStringPath) {
1296 Value* inserted = root.SetByDottedPath("foo.bar", "hello world");
1297 Value* found = root.FindByDottedPath("foo.bar");
1299 EXPECT_EQ(inserted, found);
1300 ASSERT_TRUE(found->is_string());
1301 EXPECT_EQ("hello world", found->GetString());
1303 // Overwrite with a different value.
1304 root.SetByDottedPath("foo.bar", "bonjour monde");
1305 found = root.FindByDottedPath("foo.bar");
1307 ASSERT_TRUE(found->is_string());
1308 EXPECT_EQ("bonjour monde", found->GetString());
1310 ASSERT_TRUE(root.SetByDottedPath("foo.bar", StringPiece("rah rah")));
1311 ASSERT_TRUE(root.SetByDottedPath("foo.bar", std::string("temp string")));
1312 ASSERT_TRUE(root.SetByDottedPath("foo.bar", u"temp string"));
1314 // Can't change existing non-dictionary keys.
1315 ASSERT_FALSE(root.SetByDottedPath("foo.bar.zoo", "ola mundo"));
1318 TEST(ValuesTest, Remove) {
1320 root.Set("one", Value(123));
1322 // Removal of missing key should fail.
1323 EXPECT_FALSE(root.Remove("two"));
1325 // Removal of existing key should succeed.
1326 EXPECT_TRUE(root.Remove("one"));
1328 // Second removal of previously existing key should fail.
1329 EXPECT_FALSE(root.Remove("one"));
1332 TEST(ValuesTest, Extract) {
1334 root.Set("one", Value(123));
1336 // Extraction of missing key should fail.
1337 EXPECT_EQ(absl::nullopt, root.Extract("two"));
1339 // Extraction of existing key should succeed.
1340 EXPECT_EQ(Value(123), root.Extract("one"));
1342 // Second extraction of previously existing key should fail.
1343 EXPECT_EQ(absl::nullopt, root.Extract("one"));
1346 TEST(ValuesTest, RemoveByDottedPath) {
1348 root.SetByDottedPath("one.two.three", Value(123));
1350 // Removal of missing key should fail.
1351 EXPECT_FALSE(root.RemoveByDottedPath("one.two.four"));
1353 // Removal of existing key should succeed.
1354 EXPECT_TRUE(root.RemoveByDottedPath("one.two.three"));
1356 // Second removal of previously existing key should fail.
1357 EXPECT_FALSE(root.RemoveByDottedPath("one.two.three"));
1359 // Intermediate empty dictionaries should be cleared.
1360 EXPECT_EQ(nullptr, root.Find("one"));
1362 root.SetByDottedPath("one.two.three", Value(123));
1363 root.SetByDottedPath("one.two.four", Value(124));
1365 EXPECT_TRUE(root.RemoveByDottedPath("one.two.three"));
1366 // Intermediate non-empty dictionaries should be kept.
1367 EXPECT_NE(nullptr, root.Find("one"));
1368 EXPECT_NE(nullptr, root.FindByDottedPath("one.two"));
1369 EXPECT_NE(nullptr, root.FindByDottedPath("one.two.four"));
1372 TEST(ValuesTest, ExtractByDottedPath) {
1374 root.SetByDottedPath("one.two.three", Value(123));
1376 // Extraction of missing key should fail.
1377 EXPECT_EQ(absl::nullopt, root.ExtractByDottedPath("one.two.four"));
1379 // Extraction of existing key should succeed.
1380 EXPECT_EQ(Value(123), root.ExtractByDottedPath("one.two.three"));
1382 // Second extraction of previously existing key should fail.
1383 EXPECT_EQ(absl::nullopt, root.ExtractByDottedPath("one.two.three"));
1385 // Intermediate empty dictionaries should be cleared.
1386 EXPECT_EQ(nullptr, root.Find("one"));
1388 root.SetByDottedPath("one.two.three", Value(123));
1389 root.SetByDottedPath("one.two.four", Value(124));
1391 EXPECT_EQ(Value(123), root.ExtractByDottedPath("one.two.three"));
1392 // Intermediate non-empty dictionaries should be kept.
1393 EXPECT_NE(nullptr, root.Find("one"));
1394 EXPECT_NE(nullptr, root.FindByDottedPath("one.two"));
1395 EXPECT_NE(nullptr, root.FindByDottedPath("one.two.four"));
1398 TEST(ValuesTest, Basic) {
1399 // Test basic dictionary getting/setting
1400 Value::Dict settings;
1401 ASSERT_FALSE(settings.FindByDottedPath("global.homepage"));
1403 ASSERT_FALSE(settings.Find("global"));
1404 settings.Set("global", Value(true));
1405 ASSERT_TRUE(settings.Find("global"));
1406 settings.Remove("global");
1407 settings.SetByDottedPath("global.homepage", Value("http://scurvy.com"));
1408 ASSERT_TRUE(settings.Find("global"));
1409 const std::string* homepage =
1410 settings.FindStringByDottedPath("global.homepage");
1411 ASSERT_TRUE(homepage);
1412 ASSERT_EQ(std::string("http://scurvy.com"), *homepage);
1414 // Test storing a dictionary in a list.
1415 ASSERT_FALSE(settings.FindByDottedPath("global.toolbar.bookmarks"));
1417 Value::List new_toolbar_bookmarks;
1418 settings.SetByDottedPath("global.toolbar.bookmarks",
1419 std::move(new_toolbar_bookmarks));
1420 Value::List* toolbar_bookmarks =
1421 settings.FindListByDottedPath("global.toolbar.bookmarks");
1422 ASSERT_TRUE(toolbar_bookmarks);
1424 Value::Dict new_bookmark;
1425 new_bookmark.Set("name", Value("Froogle"));
1426 new_bookmark.Set("url", Value("http://froogle.com"));
1427 toolbar_bookmarks->Append(std::move(new_bookmark));
1429 Value* bookmark_list = settings.FindByDottedPath("global.toolbar.bookmarks");
1430 ASSERT_TRUE(bookmark_list);
1431 ASSERT_EQ(1U, bookmark_list->GetList().size());
1432 Value* bookmark = &bookmark_list->GetList()[0];
1433 ASSERT_TRUE(bookmark);
1434 ASSERT_TRUE(bookmark->is_dict());
1435 const std::string* bookmark_name = bookmark->GetDict().FindString("name");
1436 ASSERT_TRUE(bookmark_name);
1437 ASSERT_EQ(std::string("Froogle"), *bookmark_name);
1438 const std::string* bookmark_url = bookmark->GetDict().FindString("url");
1439 ASSERT_TRUE(bookmark_url);
1440 ASSERT_EQ(std::string("http://froogle.com"), *bookmark_url);
1443 TEST(ValuesTest, List) {
1444 Value::List mixed_list;
1445 mixed_list.Append(true);
1446 mixed_list.Append(42);
1447 mixed_list.Append(88.8);
1448 mixed_list.Append("foo");
1450 ASSERT_EQ(4u, mixed_list.size());
1452 EXPECT_EQ(true, mixed_list[0]);
1453 EXPECT_EQ(42, mixed_list[1]);
1454 EXPECT_EQ(88.8, mixed_list[2]);
1455 EXPECT_EQ("foo", mixed_list[3]);
1457 // Try searching in the mixed list.
1458 ASSERT_TRUE(Contains(mixed_list, 42));
1459 ASSERT_FALSE(Contains(mixed_list, false));
1462 TEST(ValuesTest, RvalueAppend) {
1463 Value::List list = Value::List()
1469 .Append(u"u16-value")
1470 .Append(std::string("std-value"))
1471 .Append(Value::BlobStorage({1, 2}))
1472 .Append(Value::List().Append("value in list"))
1473 .Append(Value::Dict().Set("key", "value"));
1475 Value::List expected;
1476 expected.Append(Value());
1477 expected.Append(false);
1478 expected.Append(42);
1479 expected.Append(1.2);
1480 expected.Append("value");
1481 expected.Append(u"u16-value");
1482 expected.Append(std::string("std-value"));
1483 expected.Append(Value::BlobStorage({1, 2}));
1484 Value::List nested_list;
1485 nested_list.Append("value in list");
1486 expected.Append(std::move(nested_list));
1487 Value::Dict nested_dict;
1488 nested_dict.Set("key", "value");
1489 expected.Append(std::move(nested_dict));
1491 EXPECT_EQ(list, expected);
1494 TEST(ValuesTest, ListWithCapacity) {
1495 Value::List list_with_capacity =
1496 Value::List::with_capacity(3).Append(true).Append(42).Append(88.8);
1498 ASSERT_EQ(3u, list_with_capacity.size());
1501 TEST(ValuesTest, BinaryValue) {
1502 // Default constructor creates a BinaryValue with a buffer of size 0.
1503 Value binary(Value::Type::BINARY);
1504 ASSERT_TRUE(binary.GetBlob().empty());
1506 // Test the common case of a non-empty buffer
1507 Value::BlobStorage buffer(15);
1508 uint8_t* original_buffer = buffer.data();
1509 binary = Value(std::move(buffer));
1510 ASSERT_TRUE(binary.GetBlob().data());
1511 ASSERT_EQ(original_buffer, binary.GetBlob().data());
1512 ASSERT_EQ(15U, binary.GetBlob().size());
1514 char stack_buffer[42];
1515 memset(stack_buffer, '!', 42);
1516 binary = Value(Value::BlobStorage(stack_buffer, stack_buffer + 42));
1517 ASSERT_TRUE(binary.GetBlob().data());
1518 ASSERT_NE(stack_buffer,
1519 reinterpret_cast<const char*>(binary.GetBlob().data()));
1520 ASSERT_EQ(42U, binary.GetBlob().size());
1521 ASSERT_EQ(0, memcmp(stack_buffer, binary.GetBlob().data(),
1522 binary.GetBlob().size()));
1525 TEST(ValuesTest, StringValue) {
1526 // Test overloaded StringValue constructor.
1527 std::unique_ptr<Value> narrow_value(new Value("narrow"));
1528 ASSERT_TRUE(narrow_value.get());
1529 ASSERT_TRUE(narrow_value->is_string());
1530 std::unique_ptr<Value> utf16_value(new Value(u"utf16"));
1531 ASSERT_TRUE(utf16_value.get());
1532 ASSERT_TRUE(utf16_value->is_string());
1534 ASSERT_TRUE(narrow_value->is_string());
1535 ASSERT_EQ(std::string("narrow"), narrow_value->GetString());
1537 ASSERT_TRUE(utf16_value->is_string());
1538 ASSERT_EQ(std::string("utf16"), utf16_value->GetString());
1541 TEST(ValuesTest, DictionaryDeletion) {
1542 std::string key = "test";
1544 dict.Set(key, Value());
1545 EXPECT_FALSE(dict.empty());
1546 EXPECT_EQ(1U, dict.size());
1548 EXPECT_TRUE(dict.empty());
1549 EXPECT_TRUE(dict.empty());
1550 EXPECT_EQ(0U, dict.size());
1553 TEST(ValuesTest, DictionarySetReturnsPointer) {
1556 Value* blank_ptr = dict.Set("foo.bar", Value());
1557 EXPECT_EQ(Value::Type::NONE, blank_ptr->type());
1562 Value* blank_ptr = dict.Set("foo.bar", Value());
1563 EXPECT_EQ(Value::Type::NONE, blank_ptr->type());
1568 Value* int_ptr = dict.Set("foo.bar", 42);
1569 EXPECT_EQ(Value::Type::INTEGER, int_ptr->type());
1570 EXPECT_EQ(42, int_ptr->GetInt());
1575 Value* string_ptr = dict.Set("foo.bar", "foo");
1576 EXPECT_EQ(Value::Type::STRING, string_ptr->type());
1577 EXPECT_EQ("foo", string_ptr->GetString());
1582 Value* string16_ptr = dict.Set("foo.bar", u"baz");
1583 EXPECT_EQ(Value::Type::STRING, string16_ptr->type());
1584 EXPECT_EQ("baz", string16_ptr->GetString());
1589 Value* dict_ptr = dict.Set("foo.bar", Value::Dict());
1590 EXPECT_EQ(Value::Type::DICT, dict_ptr->type());
1595 Value* list_ptr = dict.Set("foo.bar", Value::List());
1596 EXPECT_EQ(Value::Type::LIST, list_ptr->type());
1600 TEST(ValuesTest, Clone) {
1601 Value original_null;
1602 Value original_bool(true);
1603 Value original_int(42);
1604 Value original_double(3.14);
1605 Value original_string("hello");
1606 Value original_string16(u"hello16");
1607 Value original_binary(Value::BlobStorage(42, '!'));
1612 Value original_list(std::move(list));
1614 Value original_dict(Value::Dict()
1615 .Set("null", original_null.Clone())
1616 .Set("bool", original_bool.Clone())
1617 .Set("int", original_int.Clone())
1618 .Set("double", original_double.Clone())
1619 .Set("string", original_string.Clone())
1620 .Set("string16", original_string16.Clone())
1621 .Set("binary", original_binary.Clone())
1622 .Set("list", original_list.Clone()));
1624 Value copy_value = original_dict.Clone();
1625 const Value::Dict& copy_dict = copy_value.GetDict();
1626 EXPECT_EQ(original_dict, copy_dict);
1627 EXPECT_EQ(original_null, *copy_dict.Find("null"));
1628 EXPECT_EQ(original_bool, *copy_dict.Find("bool"));
1629 EXPECT_EQ(original_int, *copy_dict.Find("int"));
1630 EXPECT_EQ(original_double, *copy_dict.Find("double"));
1631 EXPECT_EQ(original_string, *copy_dict.Find("string"));
1632 EXPECT_EQ(original_string16, *copy_dict.Find("string16"));
1633 EXPECT_EQ(original_binary, *copy_dict.Find("binary"));
1634 EXPECT_EQ(original_list, *copy_dict.Find("list"));
1637 TEST(ValuesTest, TakeString) {
1639 std::string taken = std::move(value).TakeString();
1640 EXPECT_EQ(taken, "foo");
1643 // Check that the value can still be used after `TakeString()` was called, as
1644 // long as a new value was assigned to it.
1645 TEST(ValuesTest, PopulateAfterTakeString) {
1647 std::string taken = std::move(value).TakeString();
1649 value = Value(false);
1650 EXPECT_EQ(value, Value(false));
1653 TEST(ValuesTest, TakeDict) {
1655 dict.Set("foo", 123);
1656 Value value(std::move(dict));
1657 Value clone = value.Clone();
1659 Value::Dict taken = std::move(value).TakeDict();
1660 EXPECT_EQ(taken, clone);
1663 // Check that the value can still be used after `TakeDict()` was called, as long
1664 // as a new value was assigned to it.
1665 TEST(ValuesTest, PopulateAfterTakeDict) {
1667 dict.Set("foo", 123);
1668 Value value(std::move(dict));
1669 Value::Dict taken = std::move(value).TakeDict();
1671 value = Value(false);
1672 EXPECT_EQ(value, Value(false));
1675 TEST(ValuesTest, TakeList) {
1679 Value value(std::move(list));
1680 Value clone = value.Clone();
1682 Value::List taken = std::move(value).TakeList();
1683 EXPECT_EQ(taken, clone);
1686 // Check that the value can still be used after `TakeList()` was called, as long
1687 // as a new value was assigned to it.
1688 TEST(ValuesTest, PopulateAfterTakeList) {
1690 list.Append("hello");
1691 Value value(std::move(list));
1692 Value::List taken = std::move(value).TakeList();
1694 value = Value(false);
1695 EXPECT_EQ(value, Value(false));
1698 TEST(ValuesTest, SpecializedEquals) {
1699 std::vector<Value> values;
1700 values.emplace_back(false);
1701 values.emplace_back(true);
1702 values.emplace_back(0);
1703 values.emplace_back(1);
1704 values.emplace_back(1.0);
1705 values.emplace_back(2.0);
1706 values.emplace_back("hello");
1707 values.emplace_back("world");
1708 base::Value::Dict dict;
1709 dict.Set("hello", "world");
1710 values.emplace_back(std::move(dict));
1711 base::Value::Dict dict2;
1712 dict2.Set("world", "hello");
1713 values.emplace_back(std::move(dict2));
1714 base::Value::List list;
1715 list.Append("hello");
1716 list.Append("world");
1717 values.emplace_back(std::move(list));
1718 base::Value::List list2;
1719 list2.Append("world");
1720 list2.Append("hello");
1721 values.emplace_back(std::move(list2));
1723 for (const Value& outer_value : values) {
1724 for (const Value& inner_value : values) {
1725 SCOPED_TRACE(::testing::Message()
1726 << "Outer: " << outer_value << "Inner: " << inner_value);
1727 const bool should_be_equal = &outer_value == &inner_value;
1728 if (should_be_equal) {
1729 EXPECT_EQ(outer_value, inner_value);
1730 EXPECT_EQ(inner_value, outer_value);
1731 EXPECT_FALSE(outer_value != inner_value);
1732 EXPECT_FALSE(inner_value != outer_value);
1734 EXPECT_NE(outer_value, inner_value);
1735 EXPECT_NE(inner_value, outer_value);
1736 EXPECT_FALSE(outer_value == inner_value);
1737 EXPECT_FALSE(inner_value == outer_value);
1739 // Also test the various overloads for operator== against concrete
1741 outer_value.Visit([&](const auto& outer_member) {
1742 using T = std::decay_t<decltype(outer_member)>;
1743 if constexpr (!std::is_same_v<T, absl::monostate> &&
1744 !std::is_same_v<T, Value::BlobStorage>) {
1745 if (should_be_equal) {
1746 EXPECT_EQ(outer_member, inner_value);
1747 EXPECT_EQ(inner_value, outer_member);
1748 EXPECT_FALSE(outer_member != inner_value);
1749 EXPECT_FALSE(inner_value != outer_member);
1751 EXPECT_NE(outer_member, inner_value);
1752 EXPECT_NE(inner_value, outer_member);
1753 EXPECT_FALSE(outer_member == inner_value);
1754 EXPECT_FALSE(inner_value == outer_member);
1760 // A copy of a Value should also compare equal to itself.
1761 Value copied_value = outer_value.Clone();
1762 EXPECT_EQ(outer_value, copied_value);
1763 EXPECT_EQ(copied_value, outer_value);
1764 EXPECT_FALSE(outer_value != copied_value);
1765 EXPECT_FALSE(copied_value != outer_value);
1769 // Test that a literal string comparison does not end up using the bool (!!)
1771 TEST(ValuesTest, LiteralStringEquals) {
1772 EXPECT_EQ("hello world", base::Value("hello world"));
1773 EXPECT_EQ(base::Value("hello world"), "hello world");
1774 EXPECT_NE("hello world", base::Value(true));
1775 EXPECT_NE(base::Value(true), "hello world");
1778 TEST(ValuesTest, Equals) {
1779 auto null1 = std::make_unique<Value>();
1780 auto null2 = std::make_unique<Value>();
1781 EXPECT_NE(null1.get(), null2.get());
1782 EXPECT_EQ(*null1, *null2);
1784 Value boolean(false);
1785 EXPECT_NE(*null1, boolean);
1791 dv.Set("d1", "string");
1792 dv.Set("d2", u"http://google.com");
1793 dv.Set("e", Value());
1795 Value::Dict copy = dv.Clone();
1796 EXPECT_EQ(dv, copy);
1799 list.Append(Value());
1800 list.Append(Value(Value::Type::DICT));
1801 Value::List list_copy(list.Clone());
1803 Value* list_weak = dv.Set("f", std::move(list));
1804 EXPECT_NE(dv, copy);
1805 copy.Set("f", std::move(list_copy));
1806 EXPECT_EQ(dv, copy);
1808 list_weak->GetList().Append(true);
1809 EXPECT_NE(dv, copy);
1811 // Check if Equals detects differences in only the keys.
1813 EXPECT_EQ(dv, copy);
1815 copy.Set("aa", false);
1816 EXPECT_NE(dv, copy);
1819 TEST(ValuesTest, Comparisons) {
1820 // Test None Values.
1823 EXPECT_EQ(null1, null2);
1824 EXPECT_FALSE(null1 != null2);
1825 EXPECT_FALSE(null1 < null2);
1826 EXPECT_FALSE(null1 > null2);
1827 EXPECT_LE(null1, null2);
1828 EXPECT_GE(null1, null2);
1830 // Test Bool Values.
1833 EXPECT_FALSE(bool1 == bool2);
1834 EXPECT_NE(bool1, bool2);
1835 EXPECT_LT(bool1, bool2);
1836 EXPECT_FALSE(bool1 > bool2);
1837 EXPECT_LE(bool1, bool2);
1838 EXPECT_FALSE(bool1 >= bool2);
1843 EXPECT_FALSE(int1 == int2);
1844 EXPECT_NE(int1, int2);
1845 EXPECT_LT(int1, int2);
1846 EXPECT_FALSE(int1 > int2);
1847 EXPECT_LE(int1, int2);
1848 EXPECT_FALSE(int1 >= int2);
1850 // Test Double Values.
1853 EXPECT_FALSE(double1 == double2);
1854 EXPECT_NE(double1, double2);
1855 EXPECT_LT(double1, double2);
1856 EXPECT_FALSE(double1 > double2);
1857 EXPECT_LE(double1, double2);
1858 EXPECT_FALSE(double1 >= double2);
1860 // Test String Values.
1863 EXPECT_FALSE(string1 == string2);
1864 EXPECT_NE(string1, string2);
1865 EXPECT_LT(string1, string2);
1866 EXPECT_FALSE(string1 > string2);
1867 EXPECT_LE(string1, string2);
1868 EXPECT_FALSE(string1 >= string2);
1870 // Test Binary Values.
1871 Value binary1(Value::BlobStorage{0x01});
1872 Value binary2(Value::BlobStorage{0x02});
1873 EXPECT_FALSE(binary1 == binary2);
1874 EXPECT_NE(binary1, binary2);
1875 EXPECT_LT(binary1, binary2);
1876 EXPECT_FALSE(binary1 > binary2);
1877 EXPECT_LE(binary1, binary2);
1878 EXPECT_FALSE(binary1 >= binary2);
1880 // Test Empty List Values.
1881 Value::List null_list1;
1882 Value::List null_list2;
1883 EXPECT_EQ(null_list1, null_list2);
1884 EXPECT_FALSE(null_list1 != null_list2);
1885 EXPECT_FALSE(null_list1 < null_list2);
1886 EXPECT_FALSE(null_list1 > null_list2);
1887 EXPECT_LE(null_list1, null_list2);
1888 EXPECT_GE(null_list1, null_list2);
1890 // Test Non Empty List Values.
1891 Value::List int_list1;
1892 Value::List int_list2;
1893 int_list1.Append(1);
1894 int_list2.Append(2);
1895 EXPECT_FALSE(int_list1 == int_list2);
1896 EXPECT_NE(int_list1, int_list2);
1897 EXPECT_LT(int_list1, int_list2);
1898 EXPECT_FALSE(int_list1 > int_list2);
1899 EXPECT_LE(int_list1, int_list2);
1900 EXPECT_FALSE(int_list1 >= int_list2);
1902 // Test Empty Dict Values.
1903 Value::Dict null_dict1;
1904 Value::Dict null_dict2;
1905 EXPECT_EQ(null_dict1, null_dict2);
1906 EXPECT_FALSE(null_dict1 != null_dict2);
1907 EXPECT_FALSE(null_dict1 < null_dict2);
1908 EXPECT_FALSE(null_dict1 > null_dict2);
1909 EXPECT_LE(null_dict1, null_dict2);
1910 EXPECT_GE(null_dict1, null_dict2);
1912 // Test Non Empty Dict Values.
1913 Value::Dict int_dict1;
1914 Value::Dict int_dict2;
1915 int_dict1.Set("key", 1);
1916 int_dict2.Set("key", 2);
1917 EXPECT_FALSE(int_dict1 == int_dict2);
1918 EXPECT_NE(int_dict1, int_dict2);
1919 EXPECT_LT(int_dict1, int_dict2);
1920 EXPECT_FALSE(int_dict1 > int_dict2);
1921 EXPECT_LE(int_dict1, int_dict2);
1922 EXPECT_FALSE(int_dict1 >= int_dict2);
1924 // Test Values of different types.
1925 std::vector<Value> values;
1926 values.emplace_back(std::move(null1));
1927 values.emplace_back(std::move(bool1));
1928 values.emplace_back(std::move(int1));
1929 values.emplace_back(std::move(double1));
1930 values.emplace_back(std::move(string1));
1931 values.emplace_back(std::move(binary1));
1932 values.emplace_back(std::move(int_dict1));
1933 values.emplace_back(std::move(int_list1));
1934 for (size_t i = 0; i < values.size(); ++i) {
1935 for (size_t j = i + 1; j < values.size(); ++j) {
1936 EXPECT_FALSE(values[i] == values[j]);
1937 EXPECT_NE(values[i], values[j]);
1938 EXPECT_LT(values[i], values[j]);
1939 EXPECT_FALSE(values[i] > values[j]);
1940 EXPECT_LE(values[i], values[j]);
1941 EXPECT_FALSE(values[i] >= values[j]);
1946 TEST(ValuesTest, Merge) {
1948 base.Set("base_key", "base_key_value_base");
1949 base.Set("collide_key", "collide_key_value_base");
1950 Value::Dict base_sub_dict;
1951 base_sub_dict.Set("sub_base_key", "sub_base_key_value_base");
1952 base_sub_dict.Set("sub_collide_key", "sub_collide_key_value_base");
1953 base.Set("sub_dict_key", std::move(base_sub_dict));
1956 merge.Set("merge_key", "merge_key_value_merge");
1957 merge.Set("collide_key", "collide_key_value_merge");
1958 Value::Dict merge_sub_dict;
1959 merge_sub_dict.Set("sub_merge_key", "sub_merge_key_value_merge");
1960 merge_sub_dict.Set("sub_collide_key", "sub_collide_key_value_merge");
1961 merge.Set("sub_dict_key", std::move(merge_sub_dict));
1963 base.Merge(std::move(merge));
1965 EXPECT_EQ(4U, base.size());
1966 const std::string* base_key_value = base.FindString("base_key");
1967 ASSERT_TRUE(base_key_value);
1968 EXPECT_EQ("base_key_value_base", *base_key_value); // Base value preserved.
1969 const std::string* collide_key_value = base.FindString("collide_key");
1970 ASSERT_TRUE(collide_key_value);
1971 EXPECT_EQ("collide_key_value_merge", *collide_key_value); // Replaced.
1972 const std::string* merge_key_value = base.FindString("merge_key");
1973 ASSERT_TRUE(merge_key_value);
1974 EXPECT_EQ("merge_key_value_merge", *merge_key_value); // Merged in.
1976 Value::Dict* res_sub_dict = base.FindDict("sub_dict_key");
1977 ASSERT_TRUE(res_sub_dict);
1978 EXPECT_EQ(3U, res_sub_dict->size());
1979 const std::string* sub_base_key_value =
1980 res_sub_dict->FindString("sub_base_key");
1981 ASSERT_TRUE(sub_base_key_value);
1982 EXPECT_EQ("sub_base_key_value_base", *sub_base_key_value); // Preserved.
1983 const std::string* sub_collide_key_value =
1984 res_sub_dict->FindString("sub_collide_key");
1985 ASSERT_TRUE(sub_collide_key_value);
1986 EXPECT_EQ("sub_collide_key_value_merge",
1987 *sub_collide_key_value); // Replaced.
1988 const std::string* sub_merge_key_value =
1989 res_sub_dict->FindString("sub_merge_key");
1990 ASSERT_TRUE(sub_merge_key_value);
1991 EXPECT_EQ("sub_merge_key_value_merge", *sub_merge_key_value); // Merged in.
1994 TEST(ValuesTest, DictionaryIterator) {
1996 for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
2000 Value value1("value1");
2001 dict.Set("key1", value1.Clone());
2003 for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
2004 EXPECT_FALSE(seen1);
2005 EXPECT_EQ("key1", it->first);
2006 EXPECT_EQ(value1, it->second);
2011 Value value2("value2");
2012 dict.Set("key2", value2.Clone());
2013 bool seen2 = seen1 = false;
2014 for (Value::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
2015 if (it->first == "key1") {
2016 EXPECT_FALSE(seen1);
2017 EXPECT_EQ(value1, it->second);
2019 } else if (it->first == "key2") {
2020 EXPECT_FALSE(seen2);
2021 EXPECT_EQ(value2, it->second);
2031 TEST(ValuesTest, MutatingCopiedPairsInDictMutatesUnderlyingValues) {
2033 dict.Set("key", Value("initial value"));
2035 // Because the non-const dict iterates over <const std::string&, Value&>
2036 // pairs, it's possible to alter iterated-over values in place even when
2037 // "copying" the key-value pair:
2038 for (auto kv : dict) {
2039 kv.second.GetString() = "replacement";
2042 std::string* found = dict.FindString("key");
2044 EXPECT_EQ(*found, "replacement");
2047 TEST(ValuesTest, StdDictionaryIterator) {
2049 for (auto it = dict.begin(); it != dict.end(); ++it) {
2053 Value value1("value1");
2054 dict.Set("key1", value1.Clone());
2056 for (auto it : dict) {
2057 EXPECT_FALSE(seen1);
2058 EXPECT_EQ("key1", it.first);
2059 EXPECT_EQ(value1, it.second);
2064 Value value2("value2");
2065 dict.Set("key2", value2.Clone());
2066 bool seen2 = seen1 = false;
2067 for (auto it : dict) {
2068 if (it.first == "key1") {
2069 EXPECT_FALSE(seen1);
2070 EXPECT_EQ(value1, it.second);
2072 } else if (it.first == "key2") {
2073 EXPECT_FALSE(seen2);
2074 EXPECT_EQ(value2, it.second);
2084 TEST(ValuesTest, SelfSwap) {
2085 base::Value test(1);
2086 std::swap(test, test);
2087 EXPECT_EQ(1, test.GetInt());
2090 TEST(ValuesTest, FromToUniquePtrValue) {
2091 std::unique_ptr<Value> dict = std::make_unique<Value>(Value::Type::DICT);
2092 dict->GetDict().Set("name", "Froogle");
2093 dict->GetDict().Set("url", "http://froogle.com");
2094 Value dict_copy = dict->Clone();
2096 Value dict_converted = Value::FromUniquePtrValue(std::move(dict));
2097 EXPECT_EQ(dict_copy, dict_converted);
2099 std::unique_ptr<Value> val =
2100 Value::ToUniquePtrValue(std::move(dict_converted));
2101 EXPECT_EQ(dict_copy, *val);
2104 TEST(ValuesTest, MutableFindStringPath) {
2106 dict.SetByDottedPath("foo.bar", "value");
2108 *(dict.FindStringByDottedPath("foo.bar")) = "new_value";
2110 Value::Dict expected_dict;
2111 expected_dict.SetByDottedPath("foo.bar", "new_value");
2113 EXPECT_EQ(expected_dict, dict);
2116 TEST(ValuesTest, MutableGetString) {
2117 Value value("value");
2118 value.GetString() = "new_value";
2119 EXPECT_EQ("new_value", value.GetString());
2122 #if BUILDFLAG(ENABLE_BASE_TRACING)
2123 TEST(ValuesTest, TracingSupport) {
2124 EXPECT_EQ(perfetto::TracedValueToString(Value(false)), "false");
2125 EXPECT_EQ(perfetto::TracedValueToString(Value(1)), "1");
2126 EXPECT_EQ(perfetto::TracedValueToString(Value(1.5)), "1.5");
2127 EXPECT_EQ(perfetto::TracedValueToString(Value("value")), "value");
2128 EXPECT_EQ(perfetto::TracedValueToString(Value(Value::Type::NONE)), "<none>");
2131 EXPECT_EQ(perfetto::TracedValueToString(list), "{}");
2134 EXPECT_EQ(perfetto::TracedValueToString(list), "[2,3]");
2135 EXPECT_EQ(perfetto::TracedValueToString(Value(std::move(list))), "[2,3]");
2139 EXPECT_EQ(perfetto::TracedValueToString(dict), "{}");
2140 dict.Set("key", "value");
2141 EXPECT_EQ(perfetto::TracedValueToString(dict), "{key:value}");
2142 EXPECT_EQ(perfetto::TracedValueToString(Value(std::move(dict))),
2146 #endif // BUILDFLAG(ENABLE_BASE_TRACING)
2148 TEST(ValueViewTest, BasicConstruction) {
2151 EXPECT_EQ(true, absl::get<bool>(v.data_view_for_test()));
2155 EXPECT_EQ(25, absl::get<int>(v.data_view_for_test()));
2159 EXPECT_DOUBLE_EQ(3.14, absl::get<ValueView::DoubleStorageForTest>(
2160 v.data_view_for_test()));
2163 ValueView v = StringPiece("hello world");
2164 EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2167 ValueView v = "hello world";
2168 EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2171 std::string str = "hello world";
2173 EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2177 dict.Set("hello", "world");
2179 EXPECT_EQ(dict, absl::get<std::reference_wrapper<const Value::Dict>>(
2180 v.data_view_for_test()));
2184 list.Append("hello");
2185 list.Append("world");
2187 EXPECT_EQ(list, absl::get<std::reference_wrapper<const Value::List>>(
2188 v.data_view_for_test()));
2192 TEST(ValueViewTest, ValueConstruction) {
2196 EXPECT_EQ(true, absl::get<bool>(v.data_view_for_test()));
2201 EXPECT_EQ(25, absl::get<int>(v.data_view_for_test()));
2206 EXPECT_DOUBLE_EQ(3.14, absl::get<ValueView::DoubleStorageForTest>(
2207 v.data_view_for_test()));
2210 Value val("hello world");
2212 EXPECT_EQ("hello world", absl::get<StringPiece>(v.data_view_for_test()));
2216 dict.Set("hello", "world");
2217 Value val(dict.Clone());
2219 EXPECT_EQ(dict, absl::get<std::reference_wrapper<const Value::Dict>>(
2220 v.data_view_for_test()));
2224 list.Append("hello");
2225 list.Append("world");
2226 Value val(list.Clone());
2228 EXPECT_EQ(list, absl::get<std::reference_wrapper<const Value::List>>(
2229 v.data_view_for_test()));
2233 TEST(ValueViewTest, ToValue) {
2236 Value to_val = ValueView(val).ToValue();
2237 EXPECT_EQ(val, to_val);
2241 Value to_val = ValueView(val).ToValue();
2242 EXPECT_EQ(val, to_val);
2246 Value to_val = ValueView(val).ToValue();
2247 EXPECT_EQ(val, to_val);
2250 Value val("hello world");
2251 Value to_val = ValueView(val).ToValue();
2252 EXPECT_EQ(val, to_val);
2256 dict.Set("hello", "world");
2257 Value val(dict.Clone());
2258 Value to_val = ValueView(val).ToValue();
2259 EXPECT_EQ(val, to_val);
2263 list.Append("hello");
2264 list.Append("world");
2265 Value val(list.Clone());
2266 Value to_val = ValueView(val).ToValue();
2267 EXPECT_EQ(val, to_val);