value_iterators_unittest.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/value_iterators.h"
  5. #include <type_traits>
  6. #include "base/memory/ptr_util.h"
  7. #include "base/values.h"
  8. #include "testing/gmock/include/gmock/gmock.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. namespace base {
  11. namespace detail {
  12. namespace {
  13. // Implementation of std::equal variant that is missing in C++11.
  14. template <class BinaryPredicate, class InputIterator1, class InputIterator2>
  15. bool are_equal(InputIterator1 first1,
  16. InputIterator1 last1,
  17. InputIterator2 first2,
  18. InputIterator2 last2,
  19. BinaryPredicate pred) {
  20. for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
  21. if (!pred(*first1, *first2))
  22. return false;
  23. }
  24. return first1 == last1 && first2 == last2;
  25. }
  26. } // namespace
  27. TEST(ValueIteratorsTest, IsAssignable) {
  28. static_assert(
  29. !std::is_assignable<dict_iterator::reference::first_type, std::string>(),
  30. "Can assign strings to dict_iterator");
  31. static_assert(
  32. std::is_assignable<dict_iterator::reference::second_type, Value>(),
  33. "Can't assign Values to dict_iterator");
  34. static_assert(!std::is_assignable<const_dict_iterator::reference::first_type,
  35. std::string>(),
  36. "Can assign strings to const_dict_iterator");
  37. static_assert(
  38. !std::is_assignable<const_dict_iterator::reference::second_type, Value>(),
  39. "Can assign Values to const_dict_iterator");
  40. }
  41. TEST(ValueIteratorsTest, DictIteratorOperatorStar) {
  42. DictStorage storage;
  43. storage.emplace("0", std::make_unique<Value>(0));
  44. using iterator = dict_iterator;
  45. iterator iter(storage.begin());
  46. EXPECT_EQ("0", (*iter).first);
  47. EXPECT_EQ(Value(0), (*iter).second);
  48. (*iter).second = Value(1);
  49. EXPECT_EQ(Value(1), *storage["0"]);
  50. }
  51. TEST(ValueIteratorsTest, DictIteratorOperatorArrow) {
  52. DictStorage storage;
  53. storage.emplace("0", std::make_unique<Value>(0));
  54. using iterator = dict_iterator;
  55. iterator iter(storage.begin());
  56. EXPECT_EQ("0", iter->first);
  57. EXPECT_EQ(Value(0), iter->second);
  58. iter->second = Value(1);
  59. EXPECT_EQ(Value(1), *storage["0"]);
  60. }
  61. TEST(ValueIteratorsTest, DictIteratorPreIncrement) {
  62. DictStorage storage;
  63. storage.emplace("0", std::make_unique<Value>(0));
  64. storage.emplace("1", std::make_unique<Value>(1));
  65. using iterator = dict_iterator;
  66. iterator iter(storage.begin());
  67. EXPECT_EQ("0", iter->first);
  68. EXPECT_EQ(Value(0), iter->second);
  69. iterator& iter_ref = ++iter;
  70. EXPECT_EQ(&iter, &iter_ref);
  71. EXPECT_EQ("1", iter_ref->first);
  72. EXPECT_EQ(Value(1), iter_ref->second);
  73. }
  74. TEST(ValueIteratorsTest, DictIteratorPostIncrement) {
  75. DictStorage storage;
  76. storage.emplace("0", std::make_unique<Value>(0));
  77. storage.emplace("1", std::make_unique<Value>(1));
  78. using iterator = dict_iterator;
  79. iterator iter(storage.begin());
  80. iterator iter_old = iter++;
  81. EXPECT_EQ("0", iter_old->first);
  82. EXPECT_EQ(Value(0), iter_old->second);
  83. EXPECT_EQ("1", iter->first);
  84. EXPECT_EQ(Value(1), iter->second);
  85. }
  86. TEST(ValueIteratorsTest, DictIteratorPreDecrement) {
  87. DictStorage storage;
  88. storage.emplace("0", std::make_unique<Value>(0));
  89. storage.emplace("1", std::make_unique<Value>(1));
  90. using iterator = dict_iterator;
  91. iterator iter(++storage.begin());
  92. EXPECT_EQ("1", iter->first);
  93. EXPECT_EQ(Value(1), iter->second);
  94. iterator& iter_ref = --iter;
  95. EXPECT_EQ(&iter, &iter_ref);
  96. EXPECT_EQ("0", iter_ref->first);
  97. EXPECT_EQ(Value(0), iter_ref->second);
  98. }
  99. TEST(ValueIteratorsTest, DictIteratorPostDecrement) {
  100. DictStorage storage;
  101. storage.emplace("0", std::make_unique<Value>(0));
  102. storage.emplace("1", std::make_unique<Value>(1));
  103. using iterator = dict_iterator;
  104. iterator iter(++storage.begin());
  105. iterator iter_old = iter--;
  106. EXPECT_EQ("1", iter_old->first);
  107. EXPECT_EQ(Value(1), iter_old->second);
  108. EXPECT_EQ("0", iter->first);
  109. EXPECT_EQ(Value(0), iter->second);
  110. }
  111. TEST(ValueIteratorsTest, DictIteratorOperatorEQ) {
  112. DictStorage storage;
  113. using iterator = dict_iterator;
  114. EXPECT_EQ(iterator(storage.begin()), iterator(storage.begin()));
  115. EXPECT_EQ(iterator(storage.end()), iterator(storage.end()));
  116. }
  117. TEST(ValueIteratorsTest, DictIteratorOperatorNE) {
  118. DictStorage storage;
  119. storage.emplace("0", std::make_unique<Value>(0));
  120. using iterator = dict_iterator;
  121. EXPECT_NE(iterator(storage.begin()), iterator(storage.end()));
  122. }
  123. TEST(ValueIteratorsTest, ConstDictIteratorOperatorStar) {
  124. DictStorage storage;
  125. storage.emplace("0", std::make_unique<Value>(0));
  126. using iterator = const_dict_iterator;
  127. iterator iter(storage.begin());
  128. EXPECT_EQ("0", (*iter).first);
  129. EXPECT_EQ(Value(0), (*iter).second);
  130. }
  131. TEST(ValueIteratorsTest, ConstDictIteratorOperatorArrow) {
  132. DictStorage storage;
  133. storage.emplace("0", std::make_unique<Value>(0));
  134. using iterator = const_dict_iterator;
  135. iterator iter(storage.begin());
  136. EXPECT_EQ("0", iter->first);
  137. EXPECT_EQ(Value(0), iter->second);
  138. }
  139. TEST(ValueIteratorsTest, ConstDictIteratorPreIncrement) {
  140. DictStorage storage;
  141. storage.emplace("0", std::make_unique<Value>(0));
  142. storage.emplace("1", std::make_unique<Value>(1));
  143. using iterator = const_dict_iterator;
  144. iterator iter(storage.begin());
  145. EXPECT_EQ("0", iter->first);
  146. EXPECT_EQ(Value(0), iter->second);
  147. iterator& iter_ref = ++iter;
  148. EXPECT_EQ(&iter, &iter_ref);
  149. EXPECT_EQ("1", iter_ref->first);
  150. EXPECT_EQ(Value(1), iter_ref->second);
  151. }
  152. TEST(ValueIteratorsTest, ConstDictIteratorPostIncrement) {
  153. DictStorage storage;
  154. storage.emplace("0", std::make_unique<Value>(0));
  155. storage.emplace("1", std::make_unique<Value>(1));
  156. using iterator = const_dict_iterator;
  157. iterator iter(storage.begin());
  158. iterator iter_old = iter++;
  159. EXPECT_EQ("0", iter_old->first);
  160. EXPECT_EQ(Value(0), iter_old->second);
  161. EXPECT_EQ("1", iter->first);
  162. EXPECT_EQ(Value(1), iter->second);
  163. }
  164. TEST(ValueIteratorsTest, ConstDictIteratorPreDecrement) {
  165. DictStorage storage;
  166. storage.emplace("0", std::make_unique<Value>(0));
  167. storage.emplace("1", std::make_unique<Value>(1));
  168. using iterator = const_dict_iterator;
  169. iterator iter(++storage.begin());
  170. EXPECT_EQ("1", iter->first);
  171. EXPECT_EQ(Value(1), iter->second);
  172. iterator& iter_ref = --iter;
  173. EXPECT_EQ(&iter, &iter_ref);
  174. EXPECT_EQ("0", iter_ref->first);
  175. EXPECT_EQ(Value(0), iter_ref->second);
  176. }
  177. TEST(ValueIteratorsTest, ConstDictIteratorPostDecrement) {
  178. DictStorage storage;
  179. storage.emplace("0", std::make_unique<Value>(0));
  180. storage.emplace("1", std::make_unique<Value>(1));
  181. using iterator = const_dict_iterator;
  182. iterator iter(++storage.begin());
  183. iterator iter_old = iter--;
  184. EXPECT_EQ("1", iter_old->first);
  185. EXPECT_EQ(Value(1), iter_old->second);
  186. EXPECT_EQ("0", iter->first);
  187. EXPECT_EQ(Value(0), iter->second);
  188. }
  189. TEST(ValueIteratorsTest, ConstDictIteratorOperatorEQ) {
  190. DictStorage storage;
  191. using iterator = const_dict_iterator;
  192. EXPECT_EQ(iterator(storage.begin()), iterator(storage.begin()));
  193. EXPECT_EQ(iterator(storage.end()), iterator(storage.end()));
  194. }
  195. TEST(ValueIteratorsTest, ConstDictIteratorOperatorNE) {
  196. DictStorage storage;
  197. storage.emplace("0", std::make_unique<Value>(0));
  198. using iterator = const_dict_iterator;
  199. EXPECT_NE(iterator(storage.begin()), iterator(storage.end()));
  200. }
  201. TEST(ValueIteratorsTest, DictIteratorProxy) {
  202. DictStorage storage;
  203. storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
  204. storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
  205. storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
  206. storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
  207. storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
  208. storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
  209. storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
  210. storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
  211. using iterator = const_dict_iterator;
  212. using iterator_proxy = dict_iterator_proxy;
  213. iterator_proxy proxy(&storage);
  214. auto equal_to = [](const DictStorage::value_type& lhs,
  215. const iterator::reference& rhs) {
  216. return std::tie(lhs.first, *lhs.second) == std::tie(rhs.first, rhs.second);
  217. };
  218. EXPECT_TRUE(are_equal(storage.begin(), storage.end(), proxy.begin(),
  219. proxy.end(), equal_to));
  220. EXPECT_TRUE(are_equal(storage.rbegin(), storage.rend(), proxy.rbegin(),
  221. proxy.rend(), equal_to));
  222. EXPECT_TRUE(are_equal(storage.cbegin(), storage.cend(), proxy.cbegin(),
  223. proxy.cend(), equal_to));
  224. EXPECT_TRUE(are_equal(storage.crbegin(), storage.crend(), proxy.crbegin(),
  225. proxy.crend(), equal_to));
  226. }
  227. TEST(ValueIteratorsTest, ConstDictIteratorProxy) {
  228. DictStorage storage;
  229. storage.emplace("null", std::make_unique<Value>(Value::Type::NONE));
  230. storage.emplace("bool", std::make_unique<Value>(Value::Type::BOOLEAN));
  231. storage.emplace("int", std::make_unique<Value>(Value::Type::INTEGER));
  232. storage.emplace("double", std::make_unique<Value>(Value::Type::DOUBLE));
  233. storage.emplace("string", std::make_unique<Value>(Value::Type::STRING));
  234. storage.emplace("blob", std::make_unique<Value>(Value::Type::BINARY));
  235. storage.emplace("dict", std::make_unique<Value>(Value::Type::DICTIONARY));
  236. storage.emplace("list", std::make_unique<Value>(Value::Type::LIST));
  237. using iterator = const_dict_iterator;
  238. using iterator_proxy = const_dict_iterator_proxy;
  239. iterator_proxy proxy(&storage);
  240. auto equal_to = [](const DictStorage::value_type& lhs,
  241. const iterator::reference& rhs) {
  242. return std::tie(lhs.first, *lhs.second) == std::tie(rhs.first, rhs.second);
  243. };
  244. EXPECT_TRUE(are_equal(storage.begin(), storage.end(), proxy.begin(),
  245. proxy.end(), equal_to));
  246. EXPECT_TRUE(are_equal(storage.rbegin(), storage.rend(), proxy.rbegin(),
  247. proxy.rend(), equal_to));
  248. EXPECT_TRUE(are_equal(storage.cbegin(), storage.cend(), proxy.cbegin(),
  249. proxy.cend(), equal_to));
  250. EXPECT_TRUE(are_equal(storage.crbegin(), storage.crend(), proxy.crbegin(),
  251. proxy.crend(), equal_to));
  252. }
  253. } // namespace detail
  254. } // namespace base