[M73 Dev][Tizen] Fix compilation errors for TV profile
[platform/framework/web/chromium-efl.git] / base / scoped_generic_unittest.cc
1 // Copyright 2014 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/scoped_generic.h"
6
7 #include <memory>
8 #include <unordered_map>
9 #include <unordered_set>
10 #include <utility>
11 #include <vector>
12
13 #include "base/stl_util.h"
14 #include "build/build_config.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace base {
18
19 namespace {
20
21 struct IntTraits {
22   IntTraits(std::vector<int>* freed) : freed_ints(freed) {}
23
24   static int InvalidValue() {
25     return -1;
26   }
27   void Free(int value) {
28     freed_ints->push_back(value);
29   }
30
31   std::vector<int>* freed_ints;
32 };
33
34 using ScopedInt = ScopedGeneric<int, IntTraits>;
35
36 }  // namespace
37
38 TEST(ScopedGenericTest, ScopedGeneric) {
39   std::vector<int> values_freed;
40   IntTraits traits(&values_freed);
41
42   // Invalid case, delete should not be called.
43   {
44     ScopedInt a(IntTraits::InvalidValue(), traits);
45   }
46   EXPECT_TRUE(values_freed.empty());
47
48   // Simple deleting case.
49   static const int kFirst = 0;
50   {
51     ScopedInt a(kFirst, traits);
52   }
53   ASSERT_EQ(1u, values_freed.size());
54   ASSERT_EQ(kFirst, values_freed[0]);
55   values_freed.clear();
56
57   // Release should return the right value and leave the object empty.
58   {
59     ScopedInt a(kFirst, traits);
60     EXPECT_EQ(kFirst, a.release());
61
62     ScopedInt b(IntTraits::InvalidValue(), traits);
63     EXPECT_EQ(IntTraits::InvalidValue(), b.release());
64   }
65   ASSERT_TRUE(values_freed.empty());
66
67   // Reset should free the old value, then the new one should go away when
68   // it goes out of scope.
69   static const int kSecond = 1;
70   {
71     ScopedInt b(kFirst, traits);
72     b.reset(kSecond);
73     ASSERT_EQ(1u, values_freed.size());
74     ASSERT_EQ(kFirst, values_freed[0]);
75   }
76   ASSERT_EQ(2u, values_freed.size());
77   ASSERT_EQ(kSecond, values_freed[1]);
78   values_freed.clear();
79
80   // Swap.
81   {
82     ScopedInt a(kFirst, traits);
83     ScopedInt b(kSecond, traits);
84     a.swap(b);
85     EXPECT_TRUE(values_freed.empty());  // Nothing should be freed.
86     EXPECT_EQ(kSecond, a.get());
87     EXPECT_EQ(kFirst, b.get());
88   }
89   // Values should be deleted in the opposite order.
90   ASSERT_EQ(2u, values_freed.size());
91   EXPECT_EQ(kFirst, values_freed[0]);
92   EXPECT_EQ(kSecond, values_freed[1]);
93   values_freed.clear();
94
95   // Move constructor.
96   {
97     ScopedInt a(kFirst, traits);
98     ScopedInt b(std::move(a));
99     EXPECT_TRUE(values_freed.empty());  // Nothing should be freed.
100     ASSERT_EQ(IntTraits::InvalidValue(), a.get());
101     ASSERT_EQ(kFirst, b.get());
102   }
103
104   ASSERT_EQ(1u, values_freed.size());
105   ASSERT_EQ(kFirst, values_freed[0]);
106   values_freed.clear();
107
108   // Move assign.
109   {
110     ScopedInt a(kFirst, traits);
111     ScopedInt b(kSecond, traits);
112     b = std::move(a);
113     ASSERT_EQ(1u, values_freed.size());
114     EXPECT_EQ(kSecond, values_freed[0]);
115     ASSERT_EQ(IntTraits::InvalidValue(), a.get());
116     ASSERT_EQ(kFirst, b.get());
117   }
118
119   ASSERT_EQ(2u, values_freed.size());
120   EXPECT_EQ(kFirst, values_freed[1]);
121   values_freed.clear();
122 }
123
124 TEST(ScopedGenericTest, Operators) {
125   std::vector<int> values_freed;
126   IntTraits traits(&values_freed);
127
128   static const int kFirst = 0;
129   static const int kSecond = 1;
130   {
131     ScopedInt a(kFirst, traits);
132     EXPECT_TRUE(a == kFirst);
133     EXPECT_FALSE(a != kFirst);
134     EXPECT_FALSE(a == kSecond);
135     EXPECT_TRUE(a != kSecond);
136
137     EXPECT_TRUE(kFirst == a);
138     EXPECT_FALSE(kFirst != a);
139     EXPECT_FALSE(kSecond == a);
140     EXPECT_TRUE(kSecond != a);
141   }
142
143   // is_valid().
144   {
145     ScopedInt a(kFirst, traits);
146     EXPECT_TRUE(a.is_valid());
147     a.reset();
148     EXPECT_FALSE(a.is_valid());
149   }
150 }
151
152 TEST(ScopedGenericTest, Receive) {
153   std::vector<int> values_freed;
154   IntTraits traits(&values_freed);
155   auto a = std::make_unique<ScopedInt>(123, traits);
156
157   EXPECT_EQ(123, a->get());
158
159   {
160     ScopedInt::Receiver r(*a);
161     EXPECT_EQ(123, a->get());
162     *r.get() = 456;
163     EXPECT_EQ(123, a->get());
164   }
165
166   EXPECT_EQ(456, a->get());
167
168   {
169     ScopedInt::Receiver r(*a);
170     EXPECT_DEATH_IF_SUPPORTED(a.reset(), "");
171     EXPECT_DEATH_IF_SUPPORTED(ScopedInt::Receiver(*a).get(), "");
172   }
173 }
174
175 namespace {
176
177 struct TrackedIntTraits : public ScopedGenericOwnershipTracking {
178   using OwnerMap =
179       std::unordered_map<int, const ScopedGeneric<int, TrackedIntTraits>*>;
180   TrackedIntTraits(std::unordered_set<int>* freed, OwnerMap* owners)
181       : freed(freed), owners(owners) {}
182
183   static int InvalidValue() { return -1; }
184
185   void Free(int value) {
186     auto it = owners->find(value);
187     ASSERT_EQ(owners->end(), it);
188
189     ASSERT_EQ(0U, freed->count(value));
190     freed->insert(value);
191   }
192
193   void Acquire(const ScopedGeneric<int, TrackedIntTraits>& owner, int value) {
194     auto it = owners->find(value);
195     ASSERT_EQ(owners->end(), it);
196     (*owners)[value] = &owner;
197   }
198
199   void Release(const ScopedGeneric<int, TrackedIntTraits>& owner, int value) {
200     auto it = owners->find(value);
201     ASSERT_NE(owners->end(), it);
202     owners->erase(it);
203   }
204
205   std::unordered_set<int>* freed;
206   OwnerMap* owners;
207 };
208
209 using ScopedTrackedInt = ScopedGeneric<int, TrackedIntTraits>;
210
211 }  // namespace
212
213 TEST(ScopedGenericTest, OwnershipTracking) {
214   TrackedIntTraits::OwnerMap owners;
215   std::unordered_set<int> freed;
216   TrackedIntTraits traits(&freed, &owners);
217
218 #define ASSERT_OWNED(value, owner)               \
219   ASSERT_TRUE(base::ContainsKey(owners, value)); \
220   ASSERT_EQ(&owner, owners[value]);              \
221   ASSERT_FALSE(base::ContainsKey(freed, value))
222
223 #define ASSERT_UNOWNED(value)                     \
224   ASSERT_FALSE(base::ContainsKey(owners, value)); \
225   ASSERT_FALSE(base::ContainsKey(freed, value))
226
227 #define ASSERT_FREED(value)                       \
228   ASSERT_FALSE(base::ContainsKey(owners, value)); \
229   ASSERT_TRUE(base::ContainsKey(freed, value))
230
231   // Constructor.
232   {
233     {
234       ScopedTrackedInt a(0, traits);
235       ASSERT_OWNED(0, a);
236     }
237     ASSERT_FREED(0);
238   }
239
240   owners.clear();
241   freed.clear();
242
243   // Reset.
244   {
245     ScopedTrackedInt a(0, traits);
246     ASSERT_OWNED(0, a);
247     a.reset(1);
248     ASSERT_FREED(0);
249     ASSERT_OWNED(1, a);
250     a.reset();
251     ASSERT_FREED(0);
252     ASSERT_FREED(1);
253   }
254
255   owners.clear();
256   freed.clear();
257
258   // Release.
259   {
260     {
261       ScopedTrackedInt a(0, traits);
262       ASSERT_OWNED(0, a);
263       int released = a.release();
264       ASSERT_EQ(0, released);
265       ASSERT_UNOWNED(0);
266     }
267     ASSERT_UNOWNED(0);
268   }
269
270   owners.clear();
271   freed.clear();
272
273   // Move constructor.
274   {
275     ScopedTrackedInt a(0, traits);
276     ASSERT_OWNED(0, a);
277     {
278       ScopedTrackedInt b(std::move(a));
279       ASSERT_OWNED(0, b);
280     }
281     ASSERT_FREED(0);
282   }
283
284   owners.clear();
285   freed.clear();
286
287   // Move assignment.
288   {
289     {
290       ScopedTrackedInt a(0, traits);
291       ScopedTrackedInt b(1, traits);
292       ASSERT_OWNED(0, a);
293       ASSERT_OWNED(1, b);
294       a = std::move(b);
295       ASSERT_OWNED(1, a);
296       ASSERT_FREED(0);
297     }
298     ASSERT_FREED(1);
299   }
300
301   owners.clear();
302   freed.clear();
303
304   // Swap.
305   {
306     {
307       ScopedTrackedInt a(0, traits);
308       ScopedTrackedInt b(1, traits);
309       ASSERT_OWNED(0, a);
310       ASSERT_OWNED(1, b);
311       a.swap(b);
312       ASSERT_OWNED(1, a);
313       ASSERT_OWNED(0, b);
314     }
315     ASSERT_FREED(0);
316     ASSERT_FREED(1);
317   }
318
319   owners.clear();
320   freed.clear();
321
322 #undef ASSERT_OWNED
323 #undef ASSERT_UNOWNED
324 #undef ASSERT_FREED
325 }
326
327 // Cheesy manual "no compile" test for manually validating changes.
328 #if 0
329 TEST(ScopedGenericTest, NoCompile) {
330   // Assignment shouldn't work.
331   /*{
332     ScopedInt a(kFirst, traits);
333     ScopedInt b(a);
334   }*/
335
336   // Comparison shouldn't work.
337   /*{
338     ScopedInt a(kFirst, traits);
339     ScopedInt b(kFirst, traits);
340     if (a == b) {
341     }
342   }*/
343
344   // Implicit conversion to bool shouldn't work.
345   /*{
346     ScopedInt a(kFirst, traits);
347     bool result = a;
348   }*/
349 }
350 #endif
351
352 }  // namespace base