File indexing completed on 2024-06-09 04:22:15
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Boudewijn Rempt boud @valdyas.org 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_shared_ptr_test.h" 0008 #include <simpletest.h> 0009 0010 0011 #include "kis_shared_ptr.h" 0012 #include "kis_shared.h" 0013 0014 class TestClassWatcher 0015 { 0016 public: 0017 0018 TestClassWatcher() { 0019 deleted = false; 0020 } 0021 0022 0023 bool deleted; 0024 }; 0025 0026 class TestClass : public KisShared 0027 { 0028 public: 0029 0030 TestClass(TestClassWatcher * tcw) { 0031 m_tcw = tcw; 0032 } 0033 0034 ~TestClass() { 0035 m_tcw->deleted = true; 0036 } 0037 0038 TestClassWatcher * m_tcw; 0039 }; 0040 0041 typedef KisSharedPtr<TestClass> TestClassSP; 0042 typedef KisWeakSharedPtr<TestClass> TestClassWSP; 0043 typedef QVector<TestClass> vTestClassSP; 0044 typedef vTestClassSP::iterator vTestClassSP_it; 0045 typedef vTestClassSP::const_iterator vTestClassSP_cit; 0046 0047 void KisSharedPtrTest::testRefTwoSharedPointersOneInstance() 0048 { 0049 TestClassWatcher * tcw = new TestClassWatcher(); 0050 TestClass * instance = new TestClass(tcw); 0051 0052 { 0053 TestClassSP instanceSP(instance); 0054 { 0055 // Create a second shared ptr to the pointer in the first one, 0056 // pointing to the same class. 0057 TestClassSP instanceSP2 = instanceSP.data(); 0058 } 0059 // Even though the second owner of the pointer has gone out of 0060 // scope, the pointer shouldn't have been deleted. 0061 QVERIFY(instanceSP.data() != 0); 0062 QVERIFY(instance != 0); 0063 } 0064 QVERIFY(tcw->deleted == true); 0065 delete tcw; 0066 } 0067 0068 void KisSharedPtrTest::testCopy() 0069 { 0070 0071 TestClassWatcher * tcw = new TestClassWatcher(); 0072 TestClass * instance = new TestClass(tcw); 0073 0074 { 0075 TestClassSP instanceSP(instance); 0076 { 0077 // Copy the shared pointer; refcount should be 2 by now 0078 TestClassSP instanceSP2 = instance; 0079 } 0080 // Even though the second owner of the pointer has gone out of 0081 // scope, the pointer shouldn't have been deleted. 0082 QVERIFY(instanceSP.data() != 0); 0083 QVERIFY(instance != 0); 0084 } 0085 0086 // The first shared pointer went out of scope; the object should 0087 // have been deleted and the pointer set to 0 0088 QVERIFY(tcw->deleted = true); 0089 } 0090 0091 void KisSharedPtrTest::testCopy2() 0092 { 0093 0094 TestClassWatcher * tcw = new TestClassWatcher(); 0095 TestClass * instance = new TestClass(tcw); 0096 0097 { 0098 TestClassSP instanceSP(instance); 0099 { 0100 // Copy the shared pointer; refcount should be 2 by now. 0101 // This happens a lot in Krita code! 0102 TestClassSP instanceSP2(instanceSP.data()); 0103 } 0104 // Even though the second owner of the pointer has gone out of 0105 // scope, the pointer shouldn't have been deleted. 0106 QVERIFY(instanceSP.data() != 0); 0107 QVERIFY(instance != 0); 0108 } 0109 0110 // The first shared pointer went out of scope; the object should 0111 // have been deleted and the pointer set to 0 0112 QVERIFY(tcw->deleted = true); 0113 } 0114 0115 void KisSharedPtrTest::testCopy0() 0116 { 0117 TestClassSP null = 0; 0118 QVERIFY(null == 0); 0119 TestClassSP null2 = null; 0120 QVERIFY(null2 == 0); 0121 TestClassSP null3; 0122 null3 = null; 0123 QVERIFY(null3 == null); 0124 } 0125 0126 void KisSharedPtrTest::testClear() 0127 { 0128 TestClassWatcher * tcw = new TestClassWatcher(); 0129 TestClassSP instance = new TestClass(tcw); 0130 TestClassSP instance2 = instance; 0131 instance.clear(); 0132 QVERIFY(tcw->deleted = true); 0133 QVERIFY(instance.data() == 0); 0134 } 0135 0136 void KisSharedPtrTest::testWeakSP() 0137 { 0138 0139 TestClassWatcher * tcw = new TestClassWatcher(); 0140 TestClass * instance = new TestClass(tcw); 0141 0142 { 0143 TestClassWSP instanceWSP(instance); 0144 { 0145 // Copy the shared pointer; refcount should be 2 by now. 0146 // This happens a lot in Krita code! 0147 TestClassSP instanceSP(instance); 0148 } 0149 // The wsp doesn't prevent the sp from deleting the instance 0150 QVERIFY(!instanceWSP.isValid()); 0151 QVERIFY(tcw->deleted = true); 0152 } 0153 0154 0155 } 0156 0157 void KisSharedPtrTest::testBoolOnInvalidWeakPointer() 0158 { 0159 TestClassWatcher * tcw = new TestClassWatcher(); 0160 TestClass * instance = new TestClass(tcw); 0161 0162 TestClassWSP instanceWSP(instance); 0163 { 0164 // Copy the shared pointer; refcount should be 2 by now. 0165 // This happens a lot in Krita code! 0166 TestClassSP instanceSP(instance); 0167 } 0168 0169 QString result1 = instanceWSP.isValid() ? "should not happen" : "good"; 0170 QString result2 = instanceWSP ? "should not happen" : "good"; 0171 QString result3 = !instanceWSP ? "good" : "should not happen"; 0172 0173 QCOMPARE(result1, QString("good")); 0174 QCOMPARE(result2, QString("good")); 0175 QCOMPARE(result3, QString("good")); 0176 } 0177 0178 void KisSharedPtrTest::testInvalidWeakSPAssignToSP() 0179 { 0180 TestClassWatcher * tcw = new TestClassWatcher(); 0181 TestClass *instance = new TestClass(tcw); 0182 0183 TestClassWSP instanceWSP(instance); 0184 { 0185 TestClassSP sp(instance); 0186 } 0187 0188 // instanceWSP should be invalid but we should be able to assign it 0189 // to a new shared pointer 0190 TestClassSP instanceSP = instanceWSP; 0191 0192 // Since the weak pointer was invalid, the shared pointer should be null 0193 QVERIFY(!instanceSP); 0194 } 0195 0196 void KisSharedPtrTest::testInvalidWeakSPToSPCopy() 0197 { 0198 TestClassWatcher * tcw = new TestClassWatcher(); 0199 TestClass *instance = new TestClass(tcw); 0200 0201 TestClassWSP instanceWSP(instance); 0202 { 0203 TestClassSP sp(instance); 0204 } 0205 0206 // Same as above but we test the copy constructor 0207 TestClassSP instanceSP(instanceWSP); 0208 0209 QVERIFY(!instanceSP); 0210 } 0211 0212 void KisSharedPtrTest::testWeakSPAssignToWeakSP() 0213 { 0214 TestClassWatcher * tcw = new TestClassWatcher(); 0215 TestClass *instance = new TestClass(tcw); 0216 0217 TestClassWSP instanceWSP(instance); 0218 0219 TestClassWSP newValidInstanceWSP = instanceWSP; 0220 0221 // The assignment should give us a valid weak pointer 0222 QVERIFY(newValidInstanceWSP.isValid()); 0223 0224 { 0225 TestClassSP sp(instance); 0226 } 0227 0228 // instanceWSP should be invalid but we should be able to assign it 0229 // to a new weak shared pointer 0230 TestClassWSP newInvalidInstanceWSP = instanceWSP; 0231 0232 // Since instanceWSP was invalid, the newInstanceWSP should be invalid 0233 QVERIFY(!newInvalidInstanceWSP.isValid()); 0234 } 0235 0236 void KisSharedPtrTest::testWeakSPToWeakSPCopy() 0237 { 0238 TestClassWatcher * tcw = new TestClassWatcher(); 0239 TestClass *instance = new TestClass(tcw); 0240 0241 TestClassWSP instanceWSP(instance); 0242 0243 // Same as above but we test the copy constructor 0244 TestClassWSP newValidInstanceWSP(instanceWSP); 0245 0246 QVERIFY(newValidInstanceWSP.isValid()); 0247 0248 { 0249 TestClassSP sp(instance); 0250 } 0251 0252 // Same as above but we test the copy constructor 0253 TestClassWSP newInvalidInstanceWSP(instanceWSP); 0254 0255 QVERIFY(!newInvalidInstanceWSP.isValid()); 0256 } 0257 0258 #include "kis_restricted_shared_ptr.h" 0259 0260 void KisSharedPtrTest::testRestrictedPointer() 0261 { 0262 QScopedPointer<TestClassWatcher> tcw(new TestClassWatcher()); 0263 0264 TestClass * instance = new TestClass(tcw.data()); 0265 0266 TestClassSP instanceSP(instance); 0267 0268 typedef KisRestrictedSharedPtr<TestClass> TestClassRestrictedSP; 0269 0270 TestClassRestrictedSP restricted(instanceSP); 0271 0272 TestClassSP instanceSP2(restricted); 0273 QVERIFY(!restricted->m_tcw->deleted); 0274 0275 // this line should cause a build failure! 0276 //TestClassRestrictedSP restricted2(instance); 0277 } 0278 0279 #include "kis_pinned_shared_ptr.h" 0280 0281 void KisSharedPtrTest::testRestrictedPointerNoBackward() 0282 { 0283 QScopedPointer<TestClassWatcher> tcw(new TestClassWatcher()); 0284 0285 TestClass * instance = new TestClass(tcw.data()); 0286 TestClassSP instanceSP(instance); 0287 0288 typedef KisPinnedSharedPtr<TestClass> TestClassPinnedSP; 0289 0290 TestClassPinnedSP pinned(instanceSP); 0291 0292 TestClassSP instanceSP2 = pinned; 0293 // TestClass *instance2 = pinned; 0294 // delete pinned; 0295 } 0296 0297 0298 SIMPLE_TEST_MAIN(KisSharedPtrTest) 0299 0300