blob: 34c5af81cf749065bb612cf504b39e542108dbd7 [file] [log] [blame]
[email protected]1dea7572012-12-05 21:40:271// Copyright 2012 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
5#include "base/stl_util.h"
6
dyaroshev5f0ff7982017-03-08 01:24:497#include <deque>
8#include <forward_list>
9#include <functional>
10#include <iterator>
11#include <list>
12#include <map>
[email protected]1dea7572012-12-05 21:40:2713#include <set>
dyaroshev5f0ff7982017-03-08 01:24:4914#include <string>
15#include <unordered_map>
16#include <unordered_set>
17#include <vector>
[email protected]1dea7572012-12-05 21:40:2718
dyaroshev5f0ff7982017-03-08 01:24:4919#include "base/strings/string16.h"
20#include "base/strings/utf_string_conversions.h"
[email protected]1dea7572012-12-05 21:40:2721#include "testing/gtest/include/gtest/gtest.h"
22
[email protected]9a53ade2014-01-29 17:13:2723namespace {
24
25// Used as test case to ensure the various base::STLXxx functions don't require
26// more than operators "<" and "==" on values stored in containers.
27class ComparableValue {
28 public:
29 explicit ComparableValue(int value) : value_(value) {}
30
31 bool operator==(const ComparableValue& rhs) const {
32 return value_ == rhs.value_;
33 }
34
35 bool operator<(const ComparableValue& rhs) const {
36 return value_ < rhs.value_;
37 }
38
39 private:
40 int value_;
41};
42
dyaroshev5f0ff7982017-03-08 01:24:4943template <typename Container>
44void RunEraseTest() {
45 const std::pair<Container, Container> test_data[] = {
46 {Container(), Container()}, {{1, 2, 3}, {1, 3}}, {{1, 2, 3, 2}, {1, 3}}};
47
48 for (auto test_case : test_data) {
49 base::Erase(test_case.first, 2);
50 EXPECT_EQ(test_case.second, test_case.first);
51 }
52}
53
54// This test is written for containers of std::pair<int, int> to support maps.
55template <typename Container>
56void RunEraseIfTest() {
57 struct {
58 Container input;
59 Container erase_even;
60 Container erase_odd;
61 } test_data[] = {
62 {Container(), Container(), Container()},
63 {{{1, 1}, {2, 2}, {3, 3}}, {{1, 1}, {3, 3}}, {{2, 2}}},
64 {{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, {{1, 1}, {3, 3}}, {{2, 2}, {4, 4}}},
65 };
66
67 for (auto test_case : test_data) {
68 base::EraseIf(test_case.input, [](const std::pair<int, int>& elem) {
69 return !(elem.first & 1);
70 });
71 EXPECT_EQ(test_case.erase_even, test_case.input);
72 }
73
74 for (auto test_case : test_data) {
75 base::EraseIf(test_case.input, [](const std::pair<int, int>& elem) {
76 return elem.first & 1;
77 });
78 EXPECT_EQ(test_case.erase_odd, test_case.input);
79 }
80}
81
82struct HashByFirst {
83 size_t operator()(const std::pair<int, int>& elem) const {
84 return std::hash<int>()(elem.first);
85 }
86};
87
danakjc3762b92015-03-07 01:51:4288} // namespace
[email protected]9a53ade2014-01-29 17:13:2789
[email protected]1dea7572012-12-05 21:40:2790namespace base {
91namespace {
92
93TEST(STLUtilTest, STLIsSorted) {
94 {
95 std::set<int> set;
96 set.insert(24);
97 set.insert(1);
98 set.insert(12);
99 EXPECT_TRUE(STLIsSorted(set));
100 }
101
102 {
[email protected]9a53ade2014-01-29 17:13:27103 std::set<ComparableValue> set;
104 set.insert(ComparableValue(24));
105 set.insert(ComparableValue(1));
106 set.insert(ComparableValue(12));
107 EXPECT_TRUE(STLIsSorted(set));
108 }
109
110 {
[email protected]1dea7572012-12-05 21:40:27111 std::vector<int> vector;
112 vector.push_back(1);
113 vector.push_back(1);
114 vector.push_back(4);
115 vector.push_back(64);
116 vector.push_back(12432);
117 EXPECT_TRUE(STLIsSorted(vector));
118 vector.back() = 1;
119 EXPECT_FALSE(STLIsSorted(vector));
120 }
121}
122
123TEST(STLUtilTest, STLSetDifference) {
124 std::set<int> a1;
125 a1.insert(1);
126 a1.insert(2);
127 a1.insert(3);
128 a1.insert(4);
129
130 std::set<int> a2;
131 a2.insert(3);
132 a2.insert(4);
133 a2.insert(5);
134 a2.insert(6);
135 a2.insert(7);
136
137 {
138 std::set<int> difference;
139 difference.insert(1);
140 difference.insert(2);
141 EXPECT_EQ(difference, STLSetDifference<std::set<int> >(a1, a2));
142 }
143
144 {
145 std::set<int> difference;
146 difference.insert(5);
147 difference.insert(6);
148 difference.insert(7);
149 EXPECT_EQ(difference, STLSetDifference<std::set<int> >(a2, a1));
150 }
151
152 {
153 std::vector<int> difference;
154 difference.push_back(1);
155 difference.push_back(2);
156 EXPECT_EQ(difference, STLSetDifference<std::vector<int> >(a1, a2));
157 }
158
159 {
160 std::vector<int> difference;
161 difference.push_back(5);
162 difference.push_back(6);
163 difference.push_back(7);
164 EXPECT_EQ(difference, STLSetDifference<std::vector<int> >(a2, a1));
165 }
166}
167
[email protected]9a53ade2014-01-29 17:13:27168TEST(STLUtilTest, STLSetUnion) {
169 std::set<int> a1;
170 a1.insert(1);
171 a1.insert(2);
172 a1.insert(3);
173 a1.insert(4);
174
175 std::set<int> a2;
176 a2.insert(3);
177 a2.insert(4);
178 a2.insert(5);
179 a2.insert(6);
180 a2.insert(7);
181
182 {
183 std::set<int> result;
184 result.insert(1);
185 result.insert(2);
186 result.insert(3);
187 result.insert(4);
188 result.insert(5);
189 result.insert(6);
190 result.insert(7);
191 EXPECT_EQ(result, STLSetUnion<std::set<int> >(a1, a2));
192 }
193
194 {
195 std::set<int> result;
196 result.insert(1);
197 result.insert(2);
198 result.insert(3);
199 result.insert(4);
200 result.insert(5);
201 result.insert(6);
202 result.insert(7);
203 EXPECT_EQ(result, STLSetUnion<std::set<int> >(a2, a1));
204 }
205
206 {
207 std::vector<int> result;
208 result.push_back(1);
209 result.push_back(2);
210 result.push_back(3);
211 result.push_back(4);
212 result.push_back(5);
213 result.push_back(6);
214 result.push_back(7);
215 EXPECT_EQ(result, STLSetUnion<std::vector<int> >(a1, a2));
216 }
217
218 {
219 std::vector<int> result;
220 result.push_back(1);
221 result.push_back(2);
222 result.push_back(3);
223 result.push_back(4);
224 result.push_back(5);
225 result.push_back(6);
226 result.push_back(7);
227 EXPECT_EQ(result, STLSetUnion<std::vector<int> >(a2, a1));
228 }
229}
230
231TEST(STLUtilTest, STLSetIntersection) {
232 std::set<int> a1;
233 a1.insert(1);
234 a1.insert(2);
235 a1.insert(3);
236 a1.insert(4);
237
238 std::set<int> a2;
239 a2.insert(3);
240 a2.insert(4);
241 a2.insert(5);
242 a2.insert(6);
243 a2.insert(7);
244
245 {
246 std::set<int> result;
247 result.insert(3);
248 result.insert(4);
249 EXPECT_EQ(result, STLSetIntersection<std::set<int> >(a1, a2));
250 }
251
252 {
253 std::set<int> result;
254 result.insert(3);
255 result.insert(4);
256 EXPECT_EQ(result, STLSetIntersection<std::set<int> >(a2, a1));
257 }
258
259 {
260 std::vector<int> result;
261 result.push_back(3);
262 result.push_back(4);
263 EXPECT_EQ(result, STLSetIntersection<std::vector<int> >(a1, a2));
264 }
265
266 {
267 std::vector<int> result;
268 result.push_back(3);
269 result.push_back(4);
270 EXPECT_EQ(result, STLSetIntersection<std::vector<int> >(a2, a1));
271 }
272}
273
274TEST(STLUtilTest, STLIncludes) {
275 std::set<int> a1;
276 a1.insert(1);
277 a1.insert(2);
278 a1.insert(3);
279 a1.insert(4);
280
281 std::set<int> a2;
282 a2.insert(3);
283 a2.insert(4);
284
285 std::set<int> a3;
286 a3.insert(3);
287 a3.insert(4);
288 a3.insert(5);
289
290 EXPECT_TRUE(STLIncludes<std::set<int> >(a1, a2));
291 EXPECT_FALSE(STLIncludes<std::set<int> >(a1, a3));
292 EXPECT_FALSE(STLIncludes<std::set<int> >(a2, a1));
293 EXPECT_FALSE(STLIncludes<std::set<int> >(a2, a3));
294 EXPECT_FALSE(STLIncludes<std::set<int> >(a3, a1));
295 EXPECT_TRUE(STLIncludes<std::set<int> >(a3, a2));
296}
297
thestigb277ef602015-01-14 03:41:38298TEST(StringAsArrayTest, Empty) {
299 std::string empty;
300 EXPECT_EQ(nullptr, string_as_array(&empty));
301}
302
303TEST(StringAsArrayTest, NullTerminated) {
304 // If any std::string implementation is not null-terminated, this should
305 // fail. All compilers we use return a null-terminated buffer, but please do
306 // not rely on this fact in your code.
307 std::string str("abcde");
308 str.resize(3);
309 EXPECT_STREQ("abc", string_as_array(&str));
310}
311
312TEST(StringAsArrayTest, WriteCopy) {
313 // With a COW implementation, this test will fail if
314 // string_as_array(&str) is implemented as
315 // const_cast<char*>(str->data()).
316 std::string s1("abc");
317 const std::string s2(s1);
318 string_as_array(&s1)[1] = 'x';
319 EXPECT_EQ("axc", s1);
320 EXPECT_EQ("abc", s2);
321}
322
dyaroshev5f0ff7982017-03-08 01:24:49323TEST(Erase, String) {
324 const std::pair<std::string, std::string> test_data[] = {
325 {"", ""}, {"abc", "bc"}, {"abca", "bc"},
326 };
327
328 for (auto test_case : test_data) {
329 Erase(test_case.first, 'a');
330 EXPECT_EQ(test_case.second, test_case.first);
331 }
332
333 for (auto test_case : test_data) {
334 EraseIf(test_case.first, [](char elem) { return elem < 'b'; });
335 EXPECT_EQ(test_case.second, test_case.first);
336 }
337}
338
339TEST(Erase, String16) {
340 std::pair<base::string16, base::string16> test_data[] = {
341 {base::string16(), base::string16()},
342 {UTF8ToUTF16("abc"), UTF8ToUTF16("bc")},
343 {UTF8ToUTF16("abca"), UTF8ToUTF16("bc")},
344 };
345
346 const base::string16 letters = UTF8ToUTF16("ab");
347 for (auto test_case : test_data) {
348 Erase(test_case.first, letters[0]);
349 EXPECT_EQ(test_case.second, test_case.first);
350 }
351
352 for (auto test_case : test_data) {
353 EraseIf(test_case.first, [&](short elem) { return elem < letters[1]; });
354 EXPECT_EQ(test_case.second, test_case.first);
355 }
356}
357
358TEST(Erase, Deque) {
359 RunEraseTest<std::deque<int>>();
360 RunEraseIfTest<std::deque<std::pair<int, int>>>();
361}
362
363TEST(Erase, Vector) {
364 RunEraseTest<std::vector<int>>();
365 RunEraseIfTest<std::vector<std::pair<int, int>>>();
366}
367
368TEST(Erase, ForwardList) {
369 RunEraseTest<std::forward_list<int>>();
370 RunEraseIfTest<std::forward_list<std::pair<int, int>>>();
371}
372
373TEST(Erase, List) {
374 RunEraseTest<std::list<int>>();
375 RunEraseIfTest<std::list<std::pair<int, int>>>();
376}
377
378TEST(Erase, Map) {
379 RunEraseIfTest<std::map<int, int>>();
380}
381
382TEST(Erase, Multimap) {
383 RunEraseIfTest<std::multimap<int, int>>();
384}
385
386TEST(Erase, Set) {
387 RunEraseIfTest<std::set<std::pair<int, int>>>();
388}
389
390TEST(Erase, Multiset) {
391 RunEraseIfTest<std::multiset<std::pair<int, int>>>();
392}
393
394TEST(Erase, UnorderedMap) {
395 RunEraseIfTest<std::unordered_map<int, int>>();
396}
397
398TEST(Erase, UnorderedMultimap) {
399 RunEraseIfTest<std::unordered_multimap<int, int>>();
400}
401
402TEST(Erase, UnorderedSet) {
403 RunEraseIfTest<std::unordered_set<std::pair<int, int>, HashByFirst>>();
404}
405
406TEST(Erase, UnorderedMultiset) {
407 RunEraseIfTest<std::unordered_multiset<std::pair<int, int>, HashByFirst>>();
408}
409
[email protected]1dea7572012-12-05 21:40:27410} // namespace
411} // namespace base