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: 17 PseudoObservable() {} 18 int SomeMethod() { return 42; } 19 size_t ActiveObservedPtrs() const { return ActiveObservedPtrsForTesting(); } 20 }; 21 22 } // namespace 23 24 TEST(fxcrt, ObservePtrNull) { 25 PseudoObservable::ObservedPtr ptr; 26 EXPECT_EQ(nullptr, ptr.Get()); 27 } 28 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 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 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 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 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 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 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 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 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 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 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