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