Remove wpr.archive_info dependancy on page to avoid circular dependancies.
[chromium-blink-merge.git] / base / memory / ref_counted_unittest.cc
blob6f8e599cbdc970728d4a035528f68a4eb69acd9c
1 // Copyright (c) 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.
5 #include "base/memory/ref_counted.h"
7 #include "base/test/opaque_ref_counted.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 namespace {
12 class SelfAssign : public base::RefCounted<SelfAssign> {
13 protected:
14 virtual ~SelfAssign() {}
16 private:
17 friend class base::RefCounted<SelfAssign>;
20 class Derived : public SelfAssign {
21 protected:
22 ~Derived() override {}
24 private:
25 friend class base::RefCounted<Derived>;
28 class CheckDerivedMemberAccess : public scoped_refptr<SelfAssign> {
29 public:
30 CheckDerivedMemberAccess() {
31 // This shouldn't compile if we don't have access to the member variable.
32 SelfAssign** pptr = &ptr_;
33 EXPECT_EQ(*pptr, ptr_);
37 class ScopedRefPtrToSelf : public base::RefCounted<ScopedRefPtrToSelf> {
38 public:
39 ScopedRefPtrToSelf() : self_ptr_(this) {}
41 static bool was_destroyed() { return was_destroyed_; }
43 static void reset_was_destroyed() { was_destroyed_ = false; }
45 scoped_refptr<ScopedRefPtrToSelf> self_ptr_;
47 private:
48 friend class base::RefCounted<ScopedRefPtrToSelf>;
49 ~ScopedRefPtrToSelf() { was_destroyed_ = true; }
51 static bool was_destroyed_;
54 bool ScopedRefPtrToSelf::was_destroyed_ = false;
56 class ScopedRefPtrCountBase : public base::RefCounted<ScopedRefPtrCountBase> {
57 public:
58 ScopedRefPtrCountBase() { ++constructor_count_; }
60 static int constructor_count() { return constructor_count_; }
62 static int destructor_count() { return destructor_count_; }
64 static void reset_count() {
65 constructor_count_ = 0;
66 destructor_count_ = 0;
69 protected:
70 virtual ~ScopedRefPtrCountBase() { ++destructor_count_; }
72 private:
73 friend class base::RefCounted<ScopedRefPtrCountBase>;
75 static int constructor_count_;
76 static int destructor_count_;
79 int ScopedRefPtrCountBase::constructor_count_ = 0;
80 int ScopedRefPtrCountBase::destructor_count_ = 0;
82 class ScopedRefPtrCountDerived : public ScopedRefPtrCountBase {
83 public:
84 ScopedRefPtrCountDerived() { ++constructor_count_; }
86 static int constructor_count() { return constructor_count_; }
88 static int destructor_count() { return destructor_count_; }
90 static void reset_count() {
91 constructor_count_ = 0;
92 destructor_count_ = 0;
95 protected:
96 ~ScopedRefPtrCountDerived() override { ++destructor_count_; }
98 private:
99 friend class base::RefCounted<ScopedRefPtrCountDerived>;
101 static int constructor_count_;
102 static int destructor_count_;
105 int ScopedRefPtrCountDerived::constructor_count_ = 0;
106 int ScopedRefPtrCountDerived::destructor_count_ = 0;
108 } // end namespace
110 TEST(RefCountedUnitTest, TestSelfAssignment) {
111 SelfAssign* p = new SelfAssign;
112 scoped_refptr<SelfAssign> var(p);
113 var = var;
114 EXPECT_EQ(var.get(), p);
117 TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) {
118 CheckDerivedMemberAccess check;
121 TEST(RefCountedUnitTest, ScopedRefPtrToSelfPointerAssignment) {
122 ScopedRefPtrToSelf::reset_was_destroyed();
124 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
125 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
126 check->self_ptr_ = nullptr;
127 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
130 TEST(RefCountedUnitTest, ScopedRefPtrToSelfMoveAssignment) {
131 ScopedRefPtrToSelf::reset_was_destroyed();
133 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
134 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
135 // Releasing |check->self_ptr_| will delete |check|.
136 // The move assignment operator must assign |check->self_ptr_| first then
137 // release |check->self_ptr_|.
138 check->self_ptr_ = scoped_refptr<ScopedRefPtrToSelf>();
139 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
142 TEST(RefCountedUnitTest, ScopedRefPtrToOpaque) {
143 scoped_refptr<base::OpaqueRefCounted> p = base::MakeOpaqueRefCounted();
144 base::TestOpaqueRefCounted(p);
146 scoped_refptr<base::OpaqueRefCounted> q;
147 q = p;
148 base::TestOpaqueRefCounted(p);
149 base::TestOpaqueRefCounted(q);
152 TEST(RefCountedUnitTest, BooleanTesting) {
153 scoped_refptr<SelfAssign> p;
154 EXPECT_FALSE(p);
155 p = new SelfAssign;
156 EXPECT_TRUE(p);
159 TEST(RefCountedUnitTest, Equality) {
160 scoped_refptr<SelfAssign> p1(new SelfAssign);
161 scoped_refptr<SelfAssign> p2(new SelfAssign);
163 EXPECT_EQ(p1, p1);
164 EXPECT_EQ(p2, p2);
166 EXPECT_NE(p1, p2);
167 EXPECT_NE(p2, p1);
170 TEST(RefCountedUnitTest, ConvertibleEquality) {
171 scoped_refptr<Derived> p1(new Derived);
172 scoped_refptr<SelfAssign> p2;
174 EXPECT_NE(p1, p2);
175 EXPECT_NE(p2, p1);
177 p2 = p1;
179 EXPECT_EQ(p1, p2);
180 EXPECT_EQ(p2, p1);
183 TEST(RefCountedUnitTest, SelfMoveAssignment) {
184 ScopedRefPtrCountBase::reset_count();
187 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
188 scoped_refptr<ScopedRefPtrCountBase> p(raw);
189 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
190 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
192 p = p.Pass();
193 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
194 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
195 EXPECT_EQ(raw, p.get());
197 // p goes out of scope.
199 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
200 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
203 TEST(RefCountedUnitTest, MoveAssignment1) {
204 ScopedRefPtrCountBase::reset_count();
207 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
208 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
209 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
210 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
213 scoped_refptr<ScopedRefPtrCountBase> p2;
215 p2 = p1.Pass();
216 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
217 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
218 EXPECT_EQ(nullptr, p1.get());
219 EXPECT_EQ(raw, p2.get());
221 // p2 goes out of scope.
223 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
224 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
226 // p1 goes out of scope.
228 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
229 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
232 TEST(RefCountedUnitTest, MoveAssignment2) {
233 ScopedRefPtrCountBase::reset_count();
236 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
237 scoped_refptr<ScopedRefPtrCountBase> p1;
238 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
239 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
242 scoped_refptr<ScopedRefPtrCountBase> p2(raw);
243 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
244 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
246 p1 = p2.Pass();
247 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
248 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
249 EXPECT_EQ(raw, p1.get());
250 EXPECT_EQ(nullptr, p2.get());
252 // p2 goes out of scope.
254 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
255 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
257 // p1 goes out of scope.
259 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
260 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
263 TEST(RefCountedUnitTest, MoveAssignmentSameInstance1) {
264 ScopedRefPtrCountBase::reset_count();
267 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
268 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
269 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
270 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
273 scoped_refptr<ScopedRefPtrCountBase> p2(p1);
274 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
275 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
277 p1 = p2.Pass();
278 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
279 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
280 EXPECT_EQ(raw, p1.get());
281 EXPECT_EQ(nullptr, p2.get());
283 // p2 goes out of scope.
285 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
286 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
288 // p1 goes out of scope.
290 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
291 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
294 TEST(RefCountedUnitTest, MoveAssignmentSameInstance2) {
295 ScopedRefPtrCountBase::reset_count();
298 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
299 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
300 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
301 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
304 scoped_refptr<ScopedRefPtrCountBase> p2(p1);
305 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
306 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
308 p2 = p1.Pass();
309 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
310 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
311 EXPECT_EQ(nullptr, p1.get());
312 EXPECT_EQ(raw, p2.get());
314 // p2 goes out of scope.
316 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
317 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
319 // p1 goes out of scope.
321 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
322 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
325 TEST(RefCountedUnitTest, MoveAssignmentDifferentInstances) {
326 ScopedRefPtrCountBase::reset_count();
329 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
330 scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
331 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
332 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
335 ScopedRefPtrCountBase *raw2 = new ScopedRefPtrCountBase();
336 scoped_refptr<ScopedRefPtrCountBase> p2(raw2);
337 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
338 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
340 p1 = p2.Pass();
341 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
342 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
343 EXPECT_EQ(raw2, p1.get());
344 EXPECT_EQ(nullptr, p2.get());
346 // p2 goes out of scope.
348 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
349 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
351 // p1 goes out of scope.
353 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
354 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
357 TEST(RefCountedUnitTest, MoveAssignmentDerived) {
358 ScopedRefPtrCountBase::reset_count();
359 ScopedRefPtrCountDerived::reset_count();
362 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
363 scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
364 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
365 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
366 EXPECT_EQ(0, ScopedRefPtrCountDerived::constructor_count());
367 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
370 ScopedRefPtrCountDerived *raw2 = new ScopedRefPtrCountDerived();
371 scoped_refptr<ScopedRefPtrCountDerived> p2(raw2);
372 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
373 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
374 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
375 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
377 p1 = p2.Pass();
378 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
379 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
380 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
381 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
382 EXPECT_EQ(raw2, p1.get());
383 EXPECT_EQ(nullptr, p2.get());
385 // p2 goes out of scope.
387 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
388 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
389 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
390 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
392 // p1 goes out of scope.
394 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
395 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
396 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
397 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
400 TEST(RefCountedUnitTest, MoveConstructor) {
401 ScopedRefPtrCountBase::reset_count();
404 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
405 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
406 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
407 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
410 scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass());
411 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
412 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
413 EXPECT_EQ(nullptr, p1.get());
414 EXPECT_EQ(raw, p2.get());
416 // p2 goes out of scope.
418 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
419 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
421 // p1 goes out of scope.
423 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
424 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
427 TEST(RefCountedUnitTest, MoveConstructorDerived) {
428 ScopedRefPtrCountBase::reset_count();
429 ScopedRefPtrCountDerived::reset_count();
432 ScopedRefPtrCountDerived *raw1 = new ScopedRefPtrCountDerived();
433 scoped_refptr<ScopedRefPtrCountDerived> p1(raw1);
434 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
435 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
436 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
437 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
440 scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass());
441 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
442 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
443 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
444 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
445 EXPECT_EQ(nullptr, p1.get());
446 EXPECT_EQ(raw1, p2.get());
448 // p2 goes out of scope.
450 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
451 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
452 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
453 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
455 // p1 goes out of scope.
457 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
458 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
459 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
460 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());