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