• 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/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