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