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