• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 PDFium 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 "core/fxcrt/weak_ptr.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 namespace fxcrt {
13 namespace {
14 
15 class PseudoDeletable;
16 using WeakTestPtr = WeakPtr<PseudoDeletable, ReleaseDeleter<PseudoDeletable>>;
17 using UniqueTestPtr =
18     std::unique_ptr<PseudoDeletable, ReleaseDeleter<PseudoDeletable>>;
19 
20 class PseudoDeletable {
21  public:
PseudoDeletable()22   PseudoDeletable() : delete_count_(0) {}
Release()23   void Release() {
24     ++delete_count_;
25     next_.Reset();
26   }
SetNext(const WeakTestPtr & next)27   void SetNext(const WeakTestPtr& next) { next_ = next; }
delete_count() const28   int delete_count() const { return delete_count_; }
29 
30  private:
31   int delete_count_;
32   WeakTestPtr next_;
33 };
34 
35 }  // namespace
36 
TEST(WeakPtr,Null)37 TEST(WeakPtr, Null) {
38   WeakTestPtr ptr1;
39   EXPECT_FALSE(ptr1);
40 
41   WeakTestPtr ptr2;
42   EXPECT_TRUE(ptr1 == ptr2);
43   EXPECT_FALSE(ptr1 != ptr2);
44 
45   WeakTestPtr ptr3(ptr1);
46   EXPECT_TRUE(ptr1 == ptr3);
47   EXPECT_FALSE(ptr1 != ptr3);
48 
49   WeakTestPtr ptr4 = ptr1;
50   EXPECT_TRUE(ptr1 == ptr4);
51   EXPECT_FALSE(ptr1 != ptr4);
52 }
53 
TEST(WeakPtr,NonNull)54 TEST(WeakPtr, NonNull) {
55   PseudoDeletable thing;
56   EXPECT_EQ(0, thing.delete_count());
57   {
58     UniqueTestPtr unique(&thing);
59     WeakTestPtr ptr1(std::move(unique));
60     EXPECT_TRUE(ptr1);
61     EXPECT_EQ(&thing, ptr1.Get());
62 
63     WeakTestPtr ptr2;
64     EXPECT_FALSE(ptr1 == ptr2);
65     EXPECT_TRUE(ptr1 != ptr2);
66     {
67       WeakTestPtr ptr3(ptr1);
68       EXPECT_TRUE(ptr1 == ptr3);
69       EXPECT_FALSE(ptr1 != ptr3);
70       EXPECT_EQ(&thing, ptr3.Get());
71       {
72         WeakTestPtr ptr4 = ptr1;
73         EXPECT_TRUE(ptr1 == ptr4);
74         EXPECT_FALSE(ptr1 != ptr4);
75         EXPECT_EQ(&thing, ptr4.Get());
76       }
77     }
78     EXPECT_EQ(0, thing.delete_count());
79   }
80   EXPECT_EQ(1, thing.delete_count());
81 }
82 
TEST(WeakPtr,ResetNull)83 TEST(WeakPtr, ResetNull) {
84   PseudoDeletable thing;
85   {
86     UniqueTestPtr unique(&thing);
87     WeakTestPtr ptr1(std::move(unique));
88     WeakTestPtr ptr2 = ptr1;
89     ptr1.Reset();
90     EXPECT_FALSE(ptr1);
91     EXPECT_EQ(nullptr, ptr1.Get());
92     EXPECT_TRUE(ptr2);
93     EXPECT_EQ(&thing, ptr2.Get());
94     EXPECT_FALSE(ptr1 == ptr2);
95     EXPECT_TRUE(ptr1 != ptr2);
96     EXPECT_EQ(0, thing.delete_count());
97   }
98   EXPECT_EQ(1, thing.delete_count());
99 }
100 
TEST(WeakPtr,ResetNonNull)101 TEST(WeakPtr, ResetNonNull) {
102   PseudoDeletable thing1;
103   PseudoDeletable thing2;
104   {
105     UniqueTestPtr unique1(&thing1);
106     WeakTestPtr ptr1(std::move(unique1));
107     WeakTestPtr ptr2 = ptr1;
108     UniqueTestPtr unique2(&thing2);
109     ptr2.Reset(std::move(unique2));
110     EXPECT_TRUE(ptr1);
111     EXPECT_EQ(&thing1, ptr1.Get());
112     EXPECT_TRUE(ptr2);
113     EXPECT_EQ(&thing2, ptr2.Get());
114     EXPECT_FALSE(ptr1 == ptr2);
115     EXPECT_TRUE(ptr1 != ptr2);
116     EXPECT_EQ(0, thing1.delete_count());
117     EXPECT_EQ(0, thing2.delete_count());
118   }
119   EXPECT_EQ(1, thing1.delete_count());
120   EXPECT_EQ(1, thing2.delete_count());
121 }
122 
TEST(WeakPtr,DeleteObject)123 TEST(WeakPtr, DeleteObject) {
124   PseudoDeletable thing;
125   {
126     UniqueTestPtr unique(&thing);
127     WeakTestPtr ptr1(std::move(unique));
128     WeakTestPtr ptr2 = ptr1;
129     ptr1.DeleteObject();
130     EXPECT_FALSE(ptr1);
131     EXPECT_EQ(nullptr, ptr1.Get());
132     EXPECT_FALSE(ptr2);
133     EXPECT_EQ(nullptr, ptr2.Get());
134     EXPECT_FALSE(ptr1 == ptr2);
135     EXPECT_TRUE(ptr1 != ptr2);
136     EXPECT_EQ(1, thing.delete_count());
137   }
138   EXPECT_EQ(1, thing.delete_count());
139 }
140 
TEST(WeakPtr,Cyclic)141 TEST(WeakPtr, Cyclic) {
142   PseudoDeletable thing1;
143   PseudoDeletable thing2;
144   {
145     UniqueTestPtr unique1(&thing1);
146     UniqueTestPtr unique2(&thing2);
147     WeakTestPtr ptr1(std::move(unique1));
148     WeakTestPtr ptr2(std::move(unique2));
149     ptr1->SetNext(ptr2);
150     ptr2->SetNext(ptr1);
151   }
152   // Leaks without explicit clear.
153   EXPECT_EQ(0, thing1.delete_count());
154   EXPECT_EQ(0, thing2.delete_count());
155 }
156 
TEST(WeakPtr,CyclicDeleteObject)157 TEST(WeakPtr, CyclicDeleteObject) {
158   PseudoDeletable thing1;
159   PseudoDeletable thing2;
160   {
161     UniqueTestPtr unique1(&thing1);
162     UniqueTestPtr unique2(&thing2);
163     WeakTestPtr ptr1(std::move(unique1));
164     WeakTestPtr ptr2(std::move(unique2));
165     ptr1->SetNext(ptr2);
166     ptr2->SetNext(ptr1);
167     ptr1.DeleteObject();
168     EXPECT_EQ(1, thing1.delete_count());
169     EXPECT_EQ(0, thing2.delete_count());
170   }
171   EXPECT_EQ(1, thing1.delete_count());
172   EXPECT_EQ(1, thing2.delete_count());
173 }
174 
175 }  // namespace fxcrt
176