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/observed_ptr.h"
6
7 #include <utility>
8 #include <vector>
9
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/base/ptr_util.h"
12
13 namespace fxcrt {
14 namespace {
15
16 class PseudoObservable final : public Observable {
17 public:
SomeMethod()18 int SomeMethod() { return 42; }
ActiveObservedPtrs() const19 size_t ActiveObservedPtrs() const { return ActiveObserversForTesting(); }
20 };
21
22 class SelfObservable final : public Observable {
23 public:
24 ObservedPtr<SelfObservable> m_pOther;
25 };
26
27 } // namespace
28
TEST(ObservePtr,Null)29 TEST(ObservePtr, Null) {
30 ObservedPtr<PseudoObservable> ptr;
31 EXPECT_EQ(nullptr, ptr.Get());
32 }
33
TEST(ObservePtr,LivesLonger)34 TEST(ObservePtr, LivesLonger) {
35 ObservedPtr<PseudoObservable> ptr;
36 {
37 auto pObs = pdfium::MakeUnique<PseudoObservable>();
38 ptr.Reset(pObs.get());
39 EXPECT_NE(nullptr, ptr.Get());
40 EXPECT_EQ(1u, pObs->ActiveObservedPtrs());
41 }
42 EXPECT_EQ(nullptr, ptr.Get());
43 }
44
TEST(ObservePtr,LivesShorter)45 TEST(ObservePtr, LivesShorter) {
46 PseudoObservable obs;
47 {
48 ObservedPtr<PseudoObservable> ptr(&obs);
49 EXPECT_NE(nullptr, ptr.Get());
50 EXPECT_EQ(1u, obs.ActiveObservedPtrs());
51 }
52 EXPECT_EQ(0u, obs.ActiveObservedPtrs());
53 }
54
TEST(ObservePtr,CopyConstruct)55 TEST(ObservePtr, CopyConstruct) {
56 PseudoObservable obs;
57 {
58 ObservedPtr<PseudoObservable> ptr(&obs);
59 EXPECT_NE(nullptr, ptr.Get());
60 EXPECT_EQ(1u, obs.ActiveObservedPtrs());
61 {
62 ObservedPtr<PseudoObservable> ptr2(ptr);
63 EXPECT_NE(nullptr, ptr2.Get());
64 EXPECT_EQ(2u, obs.ActiveObservedPtrs());
65 }
66 EXPECT_EQ(1u, obs.ActiveObservedPtrs());
67 }
68 EXPECT_EQ(0u, obs.ActiveObservedPtrs());
69 }
70
TEST(ObservePtr,CopyAssign)71 TEST(ObservePtr, CopyAssign) {
72 PseudoObservable obs;
73 {
74 ObservedPtr<PseudoObservable> ptr(&obs);
75 EXPECT_NE(nullptr, ptr.Get());
76 EXPECT_EQ(1u, obs.ActiveObservedPtrs());
77 {
78 ObservedPtr<PseudoObservable> ptr2;
79 ptr2 = ptr;
80 EXPECT_NE(nullptr, ptr2.Get());
81 EXPECT_EQ(2u, obs.ActiveObservedPtrs());
82 }
83 EXPECT_EQ(1u, obs.ActiveObservedPtrs());
84 }
85 EXPECT_EQ(0u, obs.ActiveObservedPtrs());
86 }
87
TEST(ObservePtr,Vector)88 TEST(ObservePtr, Vector) {
89 PseudoObservable obs;
90 {
91 std::vector<ObservedPtr<PseudoObservable>> vec1;
92 std::vector<ObservedPtr<PseudoObservable>> vec2;
93 vec1.emplace_back(&obs);
94 vec1.emplace_back(&obs);
95 EXPECT_NE(nullptr, vec1[0].Get());
96 EXPECT_NE(nullptr, vec1[1].Get());
97 EXPECT_EQ(2u, obs.ActiveObservedPtrs());
98 vec2 = vec1;
99 EXPECT_NE(nullptr, vec2[0].Get());
100 EXPECT_NE(nullptr, vec2[1].Get());
101 EXPECT_EQ(4u, obs.ActiveObservedPtrs());
102 vec1.clear();
103 EXPECT_EQ(2u, obs.ActiveObservedPtrs());
104 vec2.resize(10000);
105 EXPECT_EQ(2u, obs.ActiveObservedPtrs());
106 vec2.resize(0);
107 EXPECT_EQ(0u, obs.ActiveObservedPtrs());
108 }
109 EXPECT_EQ(0u, obs.ActiveObservedPtrs());
110 }
111
TEST(ObservePtr,VectorAutoClear)112 TEST(ObservePtr, VectorAutoClear) {
113 std::vector<ObservedPtr<PseudoObservable>> vec1;
114 {
115 PseudoObservable obs;
116 vec1.emplace_back(&obs);
117 vec1.emplace_back(&obs);
118 EXPECT_NE(nullptr, vec1[0].Get());
119 EXPECT_NE(nullptr, vec1[1].Get());
120 EXPECT_EQ(2u, obs.ActiveObservedPtrs());
121 }
122 EXPECT_EQ(nullptr, vec1[0].Get());
123 EXPECT_EQ(nullptr, vec1[1].Get());
124 }
125
TEST(ObservePtr,ResetNull)126 TEST(ObservePtr, ResetNull) {
127 PseudoObservable obs;
128 ObservedPtr<PseudoObservable> ptr(&obs);
129 EXPECT_EQ(1u, obs.ActiveObservedPtrs());
130 ptr.Reset();
131 EXPECT_EQ(0u, obs.ActiveObservedPtrs());
132 }
133
TEST(ObservePtr,Reset)134 TEST(ObservePtr, Reset) {
135 PseudoObservable obs1;
136 PseudoObservable obs2;
137 ObservedPtr<PseudoObservable> ptr(&obs1);
138 EXPECT_EQ(1u, obs1.ActiveObservedPtrs());
139 EXPECT_EQ(0u, obs2.ActiveObservedPtrs());
140 ptr.Reset(&obs2);
141 EXPECT_EQ(0u, obs1.ActiveObservedPtrs());
142 EXPECT_EQ(1u, obs2.ActiveObservedPtrs());
143 }
144
TEST(ObservePtr,Equals)145 TEST(ObservePtr, Equals) {
146 PseudoObservable obj1;
147 PseudoObservable obj2;
148 ObservedPtr<PseudoObservable> null_ptr1;
149 ObservedPtr<PseudoObservable> obj1_ptr1(&obj1);
150 ObservedPtr<PseudoObservable> obj2_ptr1(&obj2);
151 EXPECT_TRUE(&obj1 == obj1_ptr1);
152 EXPECT_TRUE(obj1_ptr1 == &obj1);
153 EXPECT_TRUE(&obj2 == obj2_ptr1);
154 EXPECT_TRUE(obj2_ptr1 == &obj2);
155 {
156 ObservedPtr<PseudoObservable> null_ptr2;
157 EXPECT_TRUE(null_ptr1 == null_ptr2);
158
159 ObservedPtr<PseudoObservable> obj1_ptr2(&obj1);
160 EXPECT_TRUE(obj1_ptr1 == obj1_ptr2);
161
162 ObservedPtr<PseudoObservable> obj2_ptr2(&obj2);
163 EXPECT_TRUE(obj2_ptr1 == obj2_ptr2);
164 }
165 EXPECT_FALSE(null_ptr1 == obj1_ptr1);
166 EXPECT_FALSE(null_ptr1 == obj2_ptr1);
167 EXPECT_FALSE(obj1_ptr1 == obj2_ptr1);
168 }
169
TEST(ObservePtr,NotEquals)170 TEST(ObservePtr, NotEquals) {
171 PseudoObservable obj1;
172 PseudoObservable obj2;
173 ObservedPtr<PseudoObservable> null_ptr1;
174 ObservedPtr<PseudoObservable> obj1_ptr1(&obj1);
175 ObservedPtr<PseudoObservable> obj2_ptr1(&obj2);
176 EXPECT_FALSE(&obj1 != obj1_ptr1);
177 EXPECT_FALSE(obj1_ptr1 != &obj1);
178 EXPECT_FALSE(&obj2 != obj2_ptr1);
179 EXPECT_FALSE(obj2_ptr1 != &obj2);
180 {
181 ObservedPtr<PseudoObservable> null_ptr2;
182 ObservedPtr<PseudoObservable> obj1_ptr2(&obj1);
183 ObservedPtr<PseudoObservable> obj2_ptr2(&obj2);
184 EXPECT_FALSE(null_ptr1 != null_ptr2);
185 EXPECT_FALSE(obj1_ptr1 != obj1_ptr2);
186 EXPECT_FALSE(obj2_ptr1 != obj2_ptr2);
187 }
188 EXPECT_TRUE(null_ptr1 != obj1_ptr1);
189 EXPECT_TRUE(null_ptr1 != obj2_ptr1);
190 EXPECT_TRUE(obj1_ptr1 != obj2_ptr1);
191 }
192
TEST(ObservePtr,Bool)193 TEST(ObservePtr, Bool) {
194 PseudoObservable obj1;
195 ObservedPtr<PseudoObservable> null_ptr;
196 ObservedPtr<PseudoObservable> obj1_ptr(&obj1);
197 bool null_bool = !!null_ptr;
198 bool obj1_bool = !!obj1_ptr;
199 EXPECT_FALSE(null_bool);
200 EXPECT_TRUE(obj1_bool);
201 }
202
TEST(ObservePtr,SelfObservable)203 TEST(ObservePtr, SelfObservable) {
204 SelfObservable thing;
205 thing.m_pOther.Reset(&thing);
206 EXPECT_EQ(&thing, thing.m_pOther.Get());
207 // Must be no ASAN violations upon cleanup here.
208 }
209
TEST(ObservePtr,PairwiseObservable)210 TEST(ObservePtr, PairwiseObservable) {
211 SelfObservable thing1;
212 {
213 SelfObservable thing2;
214 thing1.m_pOther.Reset(&thing2);
215 thing2.m_pOther.Reset(&thing1);
216 EXPECT_EQ(&thing2, thing1.m_pOther.Get());
217 EXPECT_EQ(&thing1, thing2.m_pOther.Get());
218 }
219 EXPECT_EQ(nullptr, thing1.m_pOther.Get());
220 // Must be no ASAN violations upon cleanup here.
221 }
222
223 } // namespace fxcrt
224