diff options
Diffstat (limited to 'tests/auto/qsharedpointer/tst_qsharedpointer.cpp')
-rw-r--r-- | tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 165 |
1 files changed, 158 insertions, 7 deletions
diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 3adef09..1c98eb3 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -60,6 +60,7 @@ private slots: void memoryManagement(); void downCast(); void upCast(); + void objectCast(); void differentPointers(); void virtualBaseDifferentPointers(); #ifndef QTEST_NO_RTTI @@ -225,16 +226,37 @@ void tst_QSharedPointer::basics() } class ForwardDeclared; +ForwardDeclared *forwardPointer(); +void externalForwardDeclaration(); +extern int forwardDeclaredDestructorRunCount; + void tst_QSharedPointer::forwardDeclaration1() { - class Wrapper { QSharedPointer<ForwardDeclared> pointer; }; + externalForwardDeclaration(); + + struct Wrapper { QSharedPointer<ForwardDeclared> pointer; }; + + forwardDeclaredDestructorRunCount = 0; + { + Wrapper w; + w.pointer = QSharedPointer<ForwardDeclared>(forwardPointer()); + QVERIFY(!w.pointer.isNull()); + } + QCOMPARE(forwardDeclaredDestructorRunCount, 1); } -class ForwardDeclared { }; +#include "forwarddeclared.h" + void tst_QSharedPointer::forwardDeclaration2() { - class Wrapper { QSharedPointer<ForwardDeclared> pointer; }; - Wrapper w; + forwardDeclaredDestructorRunCount = 0; + { + struct Wrapper { QSharedPointer<ForwardDeclared> pointer; }; + Wrapper w1, w2; + w1.pointer = QSharedPointer<ForwardDeclared>(forwardPointer()); + QVERIFY(!w1.pointer.isNull()); + } + QCOMPARE(forwardDeclaredDestructorRunCount, 1); } void tst_QSharedPointer::memoryManagement() @@ -428,6 +450,109 @@ void tst_QSharedPointer::upCast() QCOMPARE(int(baseptr.d->strongref), 1); } +class OtherObject: public QObject +{ + Q_OBJECT +}; + +void tst_QSharedPointer::objectCast() +{ + { + OtherObject *data = new OtherObject; + QSharedPointer<QObject> baseptr = QSharedPointer<QObject>(data); + QVERIFY(baseptr == data); + QVERIFY(data == baseptr); + + // perform object cast + QSharedPointer<OtherObject> ptr = qSharedPointerObjectCast<OtherObject>(baseptr); + QVERIFY(!ptr.isNull()); + QCOMPARE(ptr.data(), data); + QVERIFY(ptr == data); + + // again: + ptr = baseptr.objectCast<OtherObject>(); + QVERIFY(ptr == data); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + ptr = qobject_cast<OtherObject *>(baseptr); + QVERIFY(ptr == data); + + // again: + ptr = qobject_cast<QSharedPointer<OtherObject> >(baseptr); + QVERIFY(ptr == data); +#endif + } + + { + const OtherObject *data = new OtherObject; + QSharedPointer<const QObject> baseptr = QSharedPointer<const QObject>(data); + QVERIFY(baseptr == data); + QVERIFY(data == baseptr); + + // perform object cast + QSharedPointer<const OtherObject> ptr = qSharedPointerObjectCast<const OtherObject>(baseptr); + QVERIFY(!ptr.isNull()); + QCOMPARE(ptr.data(), data); + QVERIFY(ptr == data); + + // again: + ptr = baseptr.objectCast<const OtherObject>(); + QVERIFY(ptr == data); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + ptr = qobject_cast<const OtherObject *>(baseptr); + QVERIFY(ptr == data); + + // again: + ptr = qobject_cast<QSharedPointer<const OtherObject> >(baseptr); + QVERIFY(ptr == data); +#endif + } + + { + OtherObject *data = new OtherObject; + QPointer<OtherObject> qptr = data; + QSharedPointer<OtherObject> ptr = QSharedPointer<OtherObject>(data); + QWeakPointer<QObject> weakptr = ptr; + + { + // perform object cast + QSharedPointer<OtherObject> otherptr = qSharedPointerObjectCast<OtherObject>(weakptr); + QVERIFY(otherptr == ptr); + + // again: + otherptr = qobject_cast<OtherObject *>(weakptr); + QVERIFY(otherptr == ptr); + + // again: + otherptr = qobject_cast<QSharedPointer<OtherObject> >(weakptr); + QVERIFY(otherptr == ptr); + } + + // drop the reference: + ptr.clear(); + QVERIFY(ptr.isNull()); + QVERIFY(qptr.isNull()); + QVERIFY(weakptr.toStrongRef().isNull()); + + // verify that the object casts fail without crash + QSharedPointer<OtherObject> otherptr = qSharedPointerObjectCast<OtherObject>(weakptr); + QVERIFY(otherptr.isNull()); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + otherptr = qobject_cast<OtherObject *>(weakptr); + QVERIFY(otherptr.isNull()); + + // again: + otherptr = qobject_cast<QSharedPointer<OtherObject> >(weakptr); + QVERIFY(otherptr.isNull()); +#endif + } +} + void tst_QSharedPointer::differentPointers() { { @@ -919,8 +1044,10 @@ void tst_QSharedPointer::invalidConstructs_data() // use of forward-declared class QTest::newRow("forward-declaration") - << &QTest::QExternalTest::tryCompileFail - << "QSharedPointer<ForwardDeclared> ptr;"; + << &QTest::QExternalTest::tryRun + << "forwardDeclaredDestructorRunCount = 0;\n" + "{ QSharedPointer<ForwardDeclared> ptr = QSharedPointer<ForwardDeclared>(forwardPointer()); }\n" + "exit(forwardDeclaredDestructorRunCount);"; // upcast without cast operator: QTest::newRow("upcast1") @@ -943,6 +1070,20 @@ void tst_QSharedPointer::invalidConstructs_data() << "QSharedPointer<const Data> baseptr = QSharedPointer<const Data>(new Data);\n" "QSharedPointer<Data> ptr;" "ptr = baseptr;"; + QTest::newRow("const-dropping-static-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer<const Data> baseptr = QSharedPointer<const Data>(new Data);\n" + "qSharedPointerCast<DerivedData>(baseptr);"; +#ifndef QTEST_NO_RTTI + QTest::newRow("const-dropping-dynamic-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer<const Data> baseptr = QSharedPointer<const Data>(new Data);\n" + "qSharedPointerDynamicCast<DerivedData>(baseptr);"; +#endif + QTest::newRow("const-dropping-object-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer<const QObject> baseptr = QSharedPointer<const QObject>(new QObject);\n" + "qSharedPointerObjectCast<QCoreApplication>(baseptr);"; // arithmethics through automatic cast operators QTest::newRow("arithmethic1") @@ -986,6 +1127,10 @@ void tst_QSharedPointer::invalidConstructs_data() << &QTest::QExternalTest::tryCompileFail << "QSharedPointer<Data> ptr1;\n" "QSharedPointer<int> ptr2 = qSharedPointerConstCast<int>(ptr1);"; + QTest::newRow("invalid-cast4") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer<Data> ptr1;\n" + "QSharedPointer<int> ptr2 = qSharedPointerObjectCast<int>(ptr1);"; } void tst_QSharedPointer::invalidConstructs() @@ -1000,13 +1145,19 @@ void tst_QSharedPointer::invalidConstructs() QTest::QExternalTest test; test.setDebugMode(true); test.setQtModules(QTest::QExternalTest::QtCore); + test.setExtraProgramSources(QStringList() << SRCDIR "forwarddeclared.cpp"); test.setProgramHeader( "#define QT_SHAREDPOINTER_TRACK_POINTERS\n" "#include <QtCore/qsharedpointer.h>\n" + "#include <QtCore/qcoreapplication.h>\n" "\n" "struct Data { int i; };\n" "struct DerivedData: public Data { int j; };\n" - "struct ForwardDeclared;"); + "\n" + "extern int forwardDeclaredDestructorRunCount;\n" + "struct ForwardDeclared;\n" + "ForwardDeclared *forwardPointer();\n" + ); QFETCH(QString, code); static bool sane = true; |