123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "base/value_iterators.h"
- #include <type_traits>
- #include "base/memory/ptr_util.h"
- #include "base/values.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace base {
- namespace detail {
- namespace {
- // Implementation of std::equal variant that is missing in C++11.
- template <class BinaryPredicate, class InputIterator1, class InputIterator2>
- bool are_equal(InputIterator1 first1,
- InputIterator1 last1,
- InputIterator2 first2,
- InputIterator2 last2,
- BinaryPredicate pred) {
- for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
- if (!pred(*first1, *first2))
- return false;
- }
- return first1 == last1 && first2 == last2;
- }
- } // namespace
- TEST(ValueIteratorsTest, IsAssignable) {
- static_assert(
- !std::is_assignable<dict_iterator::reference::first_type, std::string>(),
- "Can assign strings to dict_iterator");
- static_assert(
- std::is_assignable<dict_iterator::reference::second_type, Value>(),
- "Can't assign Values to dict_iterator");
- static_assert(!std::is_assignable<const_dict_iterator::reference::first_type,
- std::string>(),
- "Can assign strings to const_dict_iterator");
- static_assert(
- !std::is_assignable<const_dict_iterator::reference::second_type, Value>(),
- "Can assign Values to const_dict_iterator");
- }
- TEST(ValueIteratorsTest, DictIteratorOperatorStar) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- using iterator = dict_iterator;
- iterator iter(storage.begin());
- EXPECT_EQ("0", (*iter).first);
- EXPECT_EQ(Value(0), (*iter).second);
- (*iter).second = Value(1);
- EXPECT_EQ(Value(1), *storage["0"]);
- }
- TEST(ValueIteratorsTest, DictIteratorOperatorArrow) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- using iterator = dict_iterator;
- iterator iter(storage.begin());
- EXPECT_EQ("0", iter->first);
- EXPECT_EQ(Value(0), iter->second);
- iter->second = Value(1);
- EXPECT_EQ(Value(1), *storage["0"]);
- }
- TEST(ValueIteratorsTest, DictIteratorPreIncrement) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- storage.emplace("1", std::make_unique<Value>(1));
- using iterator = dict_iterator;
- iterator iter(storage.begin());
- EXPECT_EQ("0", iter->first);
- EXPECT_EQ(Value(0), iter->second);
- iterator& iter_ref = ++iter;
- EXPECT_EQ(&iter, &iter_ref);
- EXPECT_EQ("1", iter_ref->first);
- EXPECT_EQ(Value(1), iter_ref->second);
- }
- TEST(ValueIteratorsTest, DictIteratorPostIncrement) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- storage.emplace("1", std::make_unique<Value>(1));
- using iterator = dict_iterator;
- iterator iter(storage.begin());
- iterator iter_old = iter++;
- EXPECT_EQ("0", iter_old->first);
- EXPECT_EQ(Value(0), iter_old->second);
- EXPECT_EQ("1", iter->first);
- EXPECT_EQ(Value(1), iter->second);
- }
- TEST(ValueIteratorsTest, DictIteratorPreDecrement) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- storage.emplace("1", std::make_unique<Value>(1));
- using iterator = dict_iterator;
- iterator iter(++storage.begin());
- EXPECT_EQ("1", iter->first);
- EXPECT_EQ(Value(1), iter->second);
- iterator& iter_ref = --iter;
- EXPECT_EQ(&iter, &iter_ref);
- EXPECT_EQ("0", iter_ref->first);
- EXPECT_EQ(Value(0), iter_ref->second);
- }
- TEST(ValueIteratorsTest, DictIteratorPostDecrement) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- storage.emplace("1", std::make_unique<Value>(1));
- using iterator = dict_iterator;
- iterator iter(++storage.begin());
- iterator iter_old = iter--;
- EXPECT_EQ("1", iter_old->first);
- EXPECT_EQ(Value(1), iter_old->second);
- EXPECT_EQ("0", iter->first);
- EXPECT_EQ(Value(0), iter->second);
- }
- TEST(ValueIteratorsTest, DictIteratorOperatorEQ) {
- DictStorage storage;
- using iterator = dict_iterator;
- EXPECT_EQ(iterator(storage.begin()), iterator(storage.begin()));
- EXPECT_EQ(iterator(storage.end()), iterator(storage.end()));
- }
- TEST(ValueIteratorsTest, DictIteratorOperatorNE) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- using iterator = dict_iterator;
- EXPECT_NE(iterator(storage.begin()), iterator(storage.end()));
- }
- TEST(ValueIteratorsTest, ConstDictIteratorOperatorStar) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- using iterator = const_dict_iterator;
- iterator iter(storage.begin());
- EXPECT_EQ("0", (*iter).first);
- EXPECT_EQ(Value(0), (*iter).second);
- }
- TEST(ValueIteratorsTest, ConstDictIteratorOperatorArrow) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- using iterator = const_dict_iterator;
- iterator iter(storage.begin());
- EXPECT_EQ("0", iter->first);
- EXPECT_EQ(Value(0), iter->second);
- }
- TEST(ValueIteratorsTest, ConstDictIteratorPreIncrement) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- storage.emplace("1", std::make_unique<Value>(1));
- using iterator = const_dict_iterator;
- iterator iter(storage.begin());
- EXPECT_EQ("0", iter->first);
- EXPECT_EQ(Value(0), iter->second);
- iterator& iter_ref = ++iter;
- EXPECT_EQ(&iter, &iter_ref);
- EXPECT_EQ("1", iter_ref->first);
- EXPECT_EQ(Value(1), iter_ref->second);
- }
- TEST(ValueIteratorsTest, ConstDictIteratorPostIncrement) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- storage.emplace("1", std::make_unique<Value>(1));
- using iterator = const_dict_iterator;
- iterator iter(storage.begin());
- iterator iter_old = iter++;
- EXPECT_EQ("0", iter_old->first);
- EXPECT_EQ(Value(0), iter_old->second);
- EXPECT_EQ("1", iter->first);
- EXPECT_EQ(Value(1), iter->second);
- }
- TEST(ValueIteratorsTest, ConstDictIteratorPreDecrement) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- storage.emplace("1", std::make_unique<Value>(1));
- using iterator = const_dict_iterator;
- iterator iter(++storage.begin());
- EXPECT_EQ("1", iter->first);
- EXPECT_EQ(Value(1), iter->second);
- iterator& iter_ref = --iter;
- EXPECT_EQ(&iter, &iter_ref);
- EXPECT_EQ("0", iter_ref->first);
- EXPECT_EQ(Value(0), iter_ref->second);
- }
- TEST(ValueIteratorsTest, ConstDictIteratorPostDecrement) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- storage.emplace("1", std::make_unique<Value>(1));
- using iterator = const_dict_iterator;
- iterator iter(++storage.begin());
- iterator iter_old = iter--;
- EXPECT_EQ("1", iter_old->first);
- EXPECT_EQ(Value(1), iter_old->second);
- EXPECT_EQ("0", iter->first);
- EXPECT_EQ(Value(0), iter->second);
- }
- TEST(ValueIteratorsTest, ConstDictIteratorOperatorEQ) {
- DictStorage storage;
- using iterator = const_dict_iterator;
- EXPECT_EQ(iterator(storage.begin()), iterator(storage.begin()));
- EXPECT_EQ(iterator(storage.end()), iterator(storage.end()));
- }
- TEST(ValueIteratorsTest, ConstDictIteratorOperatorNE) {
- DictStorage storage;
- storage.emplace("0", std::make_unique<Value>(0));
- using iterator = const_dict_iterator;
- EXPECT_NE(iterator(storage.begin()), iterator(storage.end()));
- }
- TEST(ValueIteratorsTest, DictIteratorProxy) {
- DictStorage storage;
- storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
- storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
- storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
- storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
- storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
- storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
- storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
- storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
- using iterator = const_dict_iterator;
- using iterator_proxy = dict_iterator_proxy;
- iterator_proxy proxy(&storage);
- auto equal_to = [](const DictStorage::value_type& lhs,
- const iterator::reference& rhs) {
- return std::tie(lhs.first, *lhs.second) == std::tie(rhs.first, rhs.second);
- };
- EXPECT_TRUE(are_equal(storage.begin(), storage.end(), proxy.begin(),
- proxy.end(), equal_to));
- EXPECT_TRUE(are_equal(storage.rbegin(), storage.rend(), proxy.rbegin(),
- proxy.rend(), equal_to));
- EXPECT_TRUE(are_equal(storage.cbegin(), storage.cend(), proxy.cbegin(),
- proxy.cend(), equal_to));
- EXPECT_TRUE(are_equal(storage.crbegin(), storage.crend(), proxy.crbegin(),
- proxy.crend(), equal_to));
- }
- TEST(ValueIteratorsTest, ConstDictIteratorProxy) {
- DictStorage storage;
- storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
- storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
- storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
- storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
- storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
- storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
- storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
- storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
- using iterator = const_dict_iterator;
- using iterator_proxy = const_dict_iterator_proxy;
- iterator_proxy proxy(&storage);
- auto equal_to = [](const DictStorage::value_type& lhs,
- const iterator::reference& rhs) {
- return std::tie(lhs.first, *lhs.second) == std::tie(rhs.first, rhs.second);
- };
- EXPECT_TRUE(are_equal(storage.begin(), storage.end(), proxy.begin(),
- proxy.end(), equal_to));
- EXPECT_TRUE(are_equal(storage.rbegin(), storage.rend(), proxy.rbegin(),
- proxy.rend(), equal_to));
- EXPECT_TRUE(are_equal(storage.cbegin(), storage.cend(), proxy.cbegin(),
- proxy.cend(), equal_to));
- EXPECT_TRUE(are_equal(storage.crbegin(), storage.crend(), proxy.crbegin(),
- proxy.crend(), equal_to));
- }
- } // namespace detail
- } // namespace base
|