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_observable.h"
6 
7 #include <utility>
8 #include <vector>
9 
10 #include "testing/fx_string_testhelpers.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 namespace {
14 
15 class PseudoObservable : public CFX_Observable<PseudoObservable> {
16  public:
PseudoObservable()17   PseudoObservable() {}
SomeMethod()18   int SomeMethod() { return 42; }
ActiveObservedPtrs() const19   size_t ActiveObservedPtrs() const { return ActiveObservedPtrsForTesting(); }
20 };
21 
22 }  // namespace
23 
TEST(fxcrt,ObservePtrNull)24 TEST(fxcrt, ObservePtrNull) {
25   PseudoObservable::ObservedPtr ptr;
26   EXPECT_EQ(nullptr, ptr.Get());
27 }
28 
TEST(fxcrt,ObservePtrLivesLonger)29 TEST(fxcrt, ObservePtrLivesLonger) {
30   PseudoObservable* pObs = new PseudoObservable;
31   PseudoObservable::ObservedPtr ptr(pObs);
32   EXPECT_NE(nullptr, ptr.Get());
33   EXPECT_EQ(1u, pObs->ActiveObservedPtrs());
34   delete pObs;
35   EXPECT_EQ(nullptr, ptr.Get());
36 }
37 
TEST(fxcrt,ObservePtrLivesShorter)38 TEST(fxcrt, ObservePtrLivesShorter) {
39   PseudoObservable obs;
40   {
41     PseudoObservable::ObservedPtr ptr(&obs);
42     EXPECT_NE(nullptr, ptr.Get());
43     EXPECT_EQ(1u, obs.ActiveObservedPtrs());
44   }
45   EXPECT_EQ(0u, obs.ActiveObservedPtrs());
46 }
47 
TEST(fxcrt,ObserveCopyConstruct)48 TEST(fxcrt, ObserveCopyConstruct) {
49   PseudoObservable obs;
50   {
51     PseudoObservable::ObservedPtr ptr(&obs);
52     EXPECT_NE(nullptr, ptr.Get());
53     EXPECT_EQ(1u, obs.ActiveObservedPtrs());
54     {
55       PseudoObservable::ObservedPtr ptr2(ptr);
56       EXPECT_NE(nullptr, ptr2.Get());
57       EXPECT_EQ(2u, obs.ActiveObservedPtrs());
58     }
59     EXPECT_EQ(1u, obs.ActiveObservedPtrs());
60   }
61   EXPECT_EQ(0u, obs.ActiveObservedPtrs());
62 }
63 
TEST(fxcrt,ObserveCopyAssign)64 TEST(fxcrt, ObserveCopyAssign) {
65   PseudoObservable obs;
66   {
67     PseudoObservable::ObservedPtr ptr(&obs);
68     EXPECT_NE(nullptr, ptr.Get());
69     EXPECT_EQ(1u, obs.ActiveObservedPtrs());
70     {
71       PseudoObservable::ObservedPtr ptr2;
72       ptr2 = ptr;
73       EXPECT_NE(nullptr, ptr2.Get());
74       EXPECT_EQ(2u, obs.ActiveObservedPtrs());
75     }
76     EXPECT_EQ(1u, obs.ActiveObservedPtrs());
77   }
78   EXPECT_EQ(0u, obs.ActiveObservedPtrs());
79 }
80 
TEST(fxcrt,ObserveVector)81 TEST(fxcrt, ObserveVector) {
82   PseudoObservable obs;
83   {
84     std::vector<PseudoObservable::ObservedPtr> vec1;
85     std::vector<PseudoObservable::ObservedPtr> vec2;
86     vec1.emplace_back(&obs);
87     vec1.emplace_back(&obs);
88     EXPECT_NE(nullptr, vec1[0].Get());
89     EXPECT_NE(nullptr, vec1[1].Get());
90     EXPECT_EQ(2u, obs.ActiveObservedPtrs());
91     vec2 = vec1;
92     EXPECT_NE(nullptr, vec2[0].Get());
93     EXPECT_NE(nullptr, vec2[1].Get());
94     EXPECT_EQ(4u, obs.ActiveObservedPtrs());
95     vec1.clear();
96     EXPECT_EQ(2u, obs.ActiveObservedPtrs());
97     vec2.resize(10000);
98     EXPECT_EQ(2u, obs.ActiveObservedPtrs());
99     vec2.resize(0);
100     EXPECT_EQ(0u, obs.ActiveObservedPtrs());
101   }
102   EXPECT_EQ(0u, obs.ActiveObservedPtrs());
103 }
104 
TEST(fxcrt,ObserveVectorAutoClear)105 TEST(fxcrt, ObserveVectorAutoClear) {
106   std::vector<PseudoObservable::ObservedPtr> vec1;
107   {
108     PseudoObservable obs;
109     vec1.emplace_back(&obs);
110     vec1.emplace_back(&obs);
111     EXPECT_NE(nullptr, vec1[0].Get());
112     EXPECT_NE(nullptr, vec1[1].Get());
113     EXPECT_EQ(2u, obs.ActiveObservedPtrs());
114   }
115   EXPECT_EQ(nullptr, vec1[0].Get());
116   EXPECT_EQ(nullptr, vec1[1].Get());
117 }
118 
TEST(fxcrt,ObservePtrResetNull)119 TEST(fxcrt, ObservePtrResetNull) {
120   PseudoObservable obs;
121   PseudoObservable::ObservedPtr ptr(&obs);
122   EXPECT_EQ(1u, obs.ActiveObservedPtrs());
123   ptr.Reset();
124   EXPECT_EQ(0u, obs.ActiveObservedPtrs());
125 }
126 
TEST(fxcrt,ObservePtrReset)127 TEST(fxcrt, ObservePtrReset) {
128   PseudoObservable obs1;
129   PseudoObservable obs2;
130   PseudoObservable::ObservedPtr ptr(&obs1);
131   EXPECT_EQ(1u, obs1.ActiveObservedPtrs());
132   EXPECT_EQ(0u, obs2.ActiveObservedPtrs());
133   ptr.Reset(&obs2);
134   EXPECT_EQ(0u, obs1.ActiveObservedPtrs());
135   EXPECT_EQ(1u, obs2.ActiveObservedPtrs());
136 }
137 
TEST(fxcrt,ObservePtrEquals)138 TEST(fxcrt, ObservePtrEquals) {
139   PseudoObservable obj1;
140   PseudoObservable obj2;
141   PseudoObservable::ObservedPtr null_ptr1;
142   PseudoObservable::ObservedPtr obj1_ptr1(&obj1);
143   PseudoObservable::ObservedPtr obj2_ptr1(&obj2);
144   {
145     PseudoObservable::ObservedPtr null_ptr2;
146     EXPECT_TRUE(null_ptr1 == null_ptr2);
147 
148     PseudoObservable::ObservedPtr obj1_ptr2(&obj1);
149     EXPECT_TRUE(obj1_ptr1 == obj1_ptr2);
150 
151     PseudoObservable::ObservedPtr obj2_ptr2(&obj2);
152     EXPECT_TRUE(obj2_ptr1 == obj2_ptr2);
153   }
154   EXPECT_FALSE(null_ptr1 == obj1_ptr1);
155   EXPECT_FALSE(null_ptr1 == obj2_ptr1);
156   EXPECT_FALSE(obj1_ptr1 == obj2_ptr1);
157 }
158 
TEST(fxcrt,ObservePtrNotEquals)159 TEST(fxcrt, ObservePtrNotEquals) {
160   PseudoObservable obj1;
161   PseudoObservable obj2;
162   PseudoObservable::ObservedPtr null_ptr1;
163   PseudoObservable::ObservedPtr obj1_ptr1(&obj1);
164   PseudoObservable::ObservedPtr obj2_ptr1(&obj2);
165   {
166     PseudoObservable::ObservedPtr null_ptr2;
167     PseudoObservable::ObservedPtr obj1_ptr2(&obj1);
168     PseudoObservable::ObservedPtr obj2_ptr2(&obj2);
169     EXPECT_FALSE(null_ptr1 != null_ptr2);
170     EXPECT_FALSE(obj1_ptr1 != obj1_ptr2);
171     EXPECT_FALSE(obj2_ptr1 != obj2_ptr2);
172   }
173   EXPECT_TRUE(null_ptr1 != obj1_ptr1);
174   EXPECT_TRUE(null_ptr1 != obj2_ptr1);
175   EXPECT_TRUE(obj1_ptr1 != obj2_ptr1);
176 }
177 
TEST(fxcrt,ObservePtrBool)178 TEST(fxcrt, ObservePtrBool) {
179   PseudoObservable obj1;
180   PseudoObservable::ObservedPtr null_ptr;
181   PseudoObservable::ObservedPtr obj1_ptr(&obj1);
182   bool null_bool = !!null_ptr;
183   bool obj1_bool = !!obj1_ptr;
184   EXPECT_FALSE(null_bool);
185   EXPECT_TRUE(obj1_bool);
186 }
187