• 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/cfx_retain_ptr.h"
6 
7 #include <utility>
8 
9 #include "testing/fx_string_testhelpers.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 namespace {
13 
14 class PseudoRetainable {
15  public:
PseudoRetainable()16   PseudoRetainable() : retain_count_(0), release_count_(0) {}
Retain()17   void Retain() { ++retain_count_; }
Release()18   void Release() { ++release_count_; }
retain_count() const19   int retain_count() const { return retain_count_; }
release_count() const20   int release_count() const { return release_count_; }
21 
22  private:
23   int retain_count_;
24   int release_count_;
25 };
26 
27 }  // namespace
28 
TEST(fxcrt,RetainPtrNull)29 TEST(fxcrt, RetainPtrNull) {
30   CFX_RetainPtr<PseudoRetainable> ptr;
31   EXPECT_EQ(nullptr, ptr.Get());
32 }
33 
TEST(fxcrt,RetainPtrNormal)34 TEST(fxcrt, RetainPtrNormal) {
35   PseudoRetainable obj;
36   {
37     CFX_RetainPtr<PseudoRetainable> ptr(&obj);
38     EXPECT_EQ(&obj, ptr.Get());
39     EXPECT_EQ(1, obj.retain_count());
40     EXPECT_EQ(0, obj.release_count());
41   }
42   EXPECT_EQ(1, obj.retain_count());
43   EXPECT_EQ(1, obj.release_count());
44 }
45 
TEST(fxcrt,RetainPtrCopyCtor)46 TEST(fxcrt, RetainPtrCopyCtor) {
47   PseudoRetainable obj;
48   {
49     CFX_RetainPtr<PseudoRetainable> ptr1(&obj);
50     {
51       CFX_RetainPtr<PseudoRetainable> ptr2(ptr1);
52       EXPECT_EQ(2, obj.retain_count());
53       EXPECT_EQ(0, obj.release_count());
54     }
55     EXPECT_EQ(2, obj.retain_count());
56     EXPECT_EQ(1, obj.release_count());
57   }
58   EXPECT_EQ(2, obj.retain_count());
59   EXPECT_EQ(2, obj.release_count());
60 }
61 
TEST(fxcrt,RetainPtrMoveCtor)62 TEST(fxcrt, RetainPtrMoveCtor) {
63   PseudoRetainable obj;
64   {
65     CFX_RetainPtr<PseudoRetainable> ptr1(&obj);
66     {
67       CFX_RetainPtr<PseudoRetainable> ptr2(std::move(ptr1));
68       EXPECT_EQ(1, obj.retain_count());
69       EXPECT_EQ(0, obj.release_count());
70     }
71     EXPECT_EQ(1, obj.retain_count());
72     EXPECT_EQ(1, obj.release_count());
73   }
74   EXPECT_EQ(1, obj.retain_count());
75   EXPECT_EQ(1, obj.release_count());
76 }
77 
TEST(fxcrt,RetainPtrResetNull)78 TEST(fxcrt, RetainPtrResetNull) {
79   PseudoRetainable obj;
80   {
81     CFX_RetainPtr<PseudoRetainable> ptr(&obj);
82     ptr.Reset();
83     EXPECT_EQ(1, obj.retain_count());
84     EXPECT_EQ(1, obj.release_count());
85   }
86   EXPECT_EQ(1, obj.retain_count());
87   EXPECT_EQ(1, obj.release_count());
88 }
89 
TEST(fxcrt,RetainPtrReset)90 TEST(fxcrt, RetainPtrReset) {
91   PseudoRetainable obj1;
92   PseudoRetainable obj2;
93   {
94     CFX_RetainPtr<PseudoRetainable> ptr(&obj1);
95     ptr.Reset(&obj2);
96     EXPECT_EQ(1, obj1.retain_count());
97     EXPECT_EQ(1, obj1.release_count());
98     EXPECT_EQ(1, obj2.retain_count());
99     EXPECT_EQ(0, obj2.release_count());
100   }
101   EXPECT_EQ(1, obj1.retain_count());
102   EXPECT_EQ(1, obj1.release_count());
103   EXPECT_EQ(1, obj2.retain_count());
104   EXPECT_EQ(1, obj2.release_count());
105 }
106 
TEST(fxcrt,RetainPtrSwap)107 TEST(fxcrt, RetainPtrSwap) {
108   PseudoRetainable obj1;
109   PseudoRetainable obj2;
110   {
111     CFX_RetainPtr<PseudoRetainable> ptr1(&obj1);
112     {
113       CFX_RetainPtr<PseudoRetainable> ptr2(&obj2);
114       ptr1.Swap(ptr2);
115       EXPECT_EQ(1, obj1.retain_count());
116       EXPECT_EQ(0, obj1.release_count());
117       EXPECT_EQ(1, obj2.retain_count());
118       EXPECT_EQ(0, obj2.release_count());
119     }
120     EXPECT_EQ(1, obj1.retain_count());
121     EXPECT_EQ(1, obj1.release_count());
122     EXPECT_EQ(1, obj2.retain_count());
123     EXPECT_EQ(0, obj2.release_count());
124   }
125   EXPECT_EQ(1, obj1.retain_count());
126   EXPECT_EQ(1, obj1.release_count());
127   EXPECT_EQ(1, obj2.retain_count());
128   EXPECT_EQ(1, obj2.release_count());
129 }
130 
TEST(fxcrt,RetainPtrLeak)131 TEST(fxcrt, RetainPtrLeak) {
132   PseudoRetainable obj;
133   PseudoRetainable* leak;
134   {
135     CFX_RetainPtr<PseudoRetainable> ptr(&obj);
136     leak = ptr.Leak();
137     EXPECT_EQ(1, obj.retain_count());
138     EXPECT_EQ(0, obj.release_count());
139   }
140   EXPECT_EQ(1, obj.retain_count());
141   EXPECT_EQ(0, obj.release_count());
142   {
143     CFX_RetainPtr<PseudoRetainable> ptr;
144     ptr.Unleak(leak);
145     EXPECT_EQ(1, obj.retain_count());
146     EXPECT_EQ(0, obj.release_count());
147   }
148   EXPECT_EQ(1, obj.retain_count());
149   EXPECT_EQ(1, obj.release_count());
150 }
151 
TEST(fxcrt,RetainPtrSwapNull)152 TEST(fxcrt, RetainPtrSwapNull) {
153   PseudoRetainable obj1;
154   {
155     CFX_RetainPtr<PseudoRetainable> ptr1(&obj1);
156     {
157       CFX_RetainPtr<PseudoRetainable> ptr2;
158       ptr1.Swap(ptr2);
159       EXPECT_FALSE(ptr1);
160       EXPECT_TRUE(ptr2);
161       EXPECT_EQ(1, obj1.retain_count());
162       EXPECT_EQ(0, obj1.release_count());
163     }
164     EXPECT_EQ(1, obj1.retain_count());
165     EXPECT_EQ(1, obj1.release_count());
166   }
167   EXPECT_EQ(1, obj1.retain_count());
168   EXPECT_EQ(1, obj1.release_count());
169 }
170 
TEST(fxcrt,RetainPtrAssign)171 TEST(fxcrt, RetainPtrAssign) {
172   PseudoRetainable obj;
173   {
174     CFX_RetainPtr<PseudoRetainable> ptr(&obj);
175     {
176       CFX_RetainPtr<PseudoRetainable> ptr2;
177       ptr2 = ptr;
178       EXPECT_EQ(2, obj.retain_count());
179       EXPECT_EQ(0, obj.release_count());
180     }
181     EXPECT_EQ(2, obj.retain_count());
182     EXPECT_EQ(1, obj.release_count());
183   }
184   EXPECT_EQ(2, obj.retain_count());
185   EXPECT_EQ(2, obj.release_count());
186 }
187 
TEST(fxcrt,RetainPtrEquals)188 TEST(fxcrt, RetainPtrEquals) {
189   PseudoRetainable obj1;
190   PseudoRetainable obj2;
191   CFX_RetainPtr<PseudoRetainable> null_ptr1;
192   CFX_RetainPtr<PseudoRetainable> obj1_ptr1(&obj1);
193   CFX_RetainPtr<PseudoRetainable> obj2_ptr1(&obj2);
194   {
195     CFX_RetainPtr<PseudoRetainable> null_ptr2;
196     EXPECT_TRUE(null_ptr1 == null_ptr2);
197 
198     CFX_RetainPtr<PseudoRetainable> obj1_ptr2(&obj1);
199     EXPECT_TRUE(obj1_ptr1 == obj1_ptr2);
200 
201     CFX_RetainPtr<PseudoRetainable> obj2_ptr2(&obj2);
202     EXPECT_TRUE(obj2_ptr1 == obj2_ptr2);
203   }
204   EXPECT_FALSE(null_ptr1 == obj1_ptr1);
205   EXPECT_FALSE(null_ptr1 == obj2_ptr1);
206   EXPECT_FALSE(obj1_ptr1 == obj2_ptr1);
207 }
208 
TEST(fxcrt,RetainPtrNotEquals)209 TEST(fxcrt, RetainPtrNotEquals) {
210   PseudoRetainable obj1;
211   PseudoRetainable obj2;
212   CFX_RetainPtr<PseudoRetainable> null_ptr1;
213   CFX_RetainPtr<PseudoRetainable> obj1_ptr1(&obj1);
214   CFX_RetainPtr<PseudoRetainable> obj2_ptr1(&obj2);
215   {
216     CFX_RetainPtr<PseudoRetainable> null_ptr2;
217     CFX_RetainPtr<PseudoRetainable> obj1_ptr2(&obj1);
218     CFX_RetainPtr<PseudoRetainable> obj2_ptr2(&obj2);
219     EXPECT_FALSE(null_ptr1 != null_ptr2);
220     EXPECT_FALSE(obj1_ptr1 != obj1_ptr2);
221     EXPECT_FALSE(obj2_ptr1 != obj2_ptr2);
222   }
223   EXPECT_TRUE(null_ptr1 != obj1_ptr1);
224   EXPECT_TRUE(null_ptr1 != obj2_ptr1);
225   EXPECT_TRUE(obj1_ptr1 != obj2_ptr1);
226 }
227 
TEST(fxcrt,RetainPtrLessThan)228 TEST(fxcrt, RetainPtrLessThan) {
229   PseudoRetainable objs[2];
230   CFX_RetainPtr<PseudoRetainable> obj1_ptr(&objs[0]);
231   CFX_RetainPtr<PseudoRetainable> obj2_ptr(&objs[1]);
232   EXPECT_TRUE(obj1_ptr < obj2_ptr);
233   EXPECT_FALSE(obj2_ptr < obj1_ptr);
234 }
235 
TEST(fxcrt,RetainPtrBool)236 TEST(fxcrt, RetainPtrBool) {
237   PseudoRetainable obj1;
238   CFX_RetainPtr<PseudoRetainable> null_ptr;
239   CFX_RetainPtr<PseudoRetainable> obj1_ptr(&obj1);
240   bool null_bool = !!null_ptr;
241   bool obj1_bool = !!obj1_ptr;
242   EXPECT_FALSE(null_bool);
243   EXPECT_TRUE(obj1_bool);
244 }
245 
TEST(fxcrt,RetainPtrMakeRetained)246 TEST(fxcrt, RetainPtrMakeRetained) {
247   auto ptr = pdfium::MakeRetain<CFX_Retainable>();
248   EXPECT_TRUE(ptr->HasOneRef());
249   {
250     CFX_RetainPtr<CFX_Retainable> other = ptr;
251     EXPECT_FALSE(ptr->HasOneRef());
252   }
253   EXPECT_TRUE(ptr->HasOneRef());
254 }
255