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