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