diff options
Diffstat (limited to 'tests/auto/corelib/tools/qscopedpointer')
3 files changed, 468 insertions, 0 deletions
diff --git a/tests/auto/corelib/tools/qscopedpointer/.gitignore b/tests/auto/corelib/tools/qscopedpointer/.gitignore new file mode 100644 index 0000000000..9f2324cb11 --- /dev/null +++ b/tests/auto/corelib/tools/qscopedpointer/.gitignore @@ -0,0 +1 @@ +tst_qscopedpointer diff --git a/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro b/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro new file mode 100644 index 0000000000..4a3d5b8de8 --- /dev/null +++ b/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +SOURCES += tst_qscopedpointer.cpp +QT -= gui +CONFIG += parallel_test diff --git a/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp b/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp new file mode 100644 index 0000000000..06c0ecbafd --- /dev/null +++ b/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp @@ -0,0 +1,463 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/QScopedPointer> + +/*! + \class tst_QScopedPointer + \internal + \since 4.6 + \brief Tests class QScopedPointer. + + */ +class tst_QScopedPointer : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void defaultConstructor(); + void dataOnDefaultConstructed(); + void useSubClassInConstructor(); + void dataOnValue(); + void dataSignature(); + void reset(); + void dereferenceOperator(); + void dereferenceOperatorSignature(); + void pointerOperator(); + void pointerOperatorSignature(); + void negationOperator(); + void negationOperatorSignature(); + void operatorBool(); + void operatorBoolSignature(); + void isNull(); + void isNullSignature(); + void objectSize(); + void comparison(); + void array(); + // TODO instanciate on const object +}; + +void tst_QScopedPointer::defaultConstructor() +{ + /* Check that the members, one, is correctly initialized. */ + QScopedPointer<int> p; + QCOMPARE(p.data(), static_cast<int *>(0)); +} + +void tst_QScopedPointer::dataOnDefaultConstructed() +{ + QScopedPointer<int> p; + + QCOMPARE(p.data(), static_cast<int *>(0)); +} + +class MyClass +{ +}; + +class MySubClass : public MyClass +{ +}; + +void tst_QScopedPointer::useSubClassInConstructor() +{ + /* Use a syntax which users typically would do. */ + QScopedPointer<MyClass> p(new MyClass()); +} + +void tst_QScopedPointer::dataOnValue() +{ + int *const rawPointer = new int(5); + QScopedPointer<int> p(rawPointer); + + QCOMPARE(p.data(), rawPointer); +} + +void tst_QScopedPointer::dataSignature() +{ + const QScopedPointer<int> p; + /* data() should be const. */ + p.data(); +} + +void tst_QScopedPointer::reset() +{ + /* Call reset() on a default constructed value. */ + { + QScopedPointer<int> p; + p.reset(); + QCOMPARE(p.data(), static_cast<int *>(0)); + } + + /* Call reset() on an active value. */ + { + QScopedPointer<int> p(new int(3)); + p.reset(); + QCOMPARE(p.data(), static_cast<int *>(0)); + } + + /* Call reset() with a value, on an active value. */ + { + QScopedPointer<int> p(new int(3)); + + int *const value = new int(9); + p.reset(value); + QCOMPARE(*p.data(), 9); + } + + /* Call reset() with a value, on default constructed value. */ + { + QScopedPointer<int> p; + + int *const value = new int(9); + p.reset(value); + QCOMPARE(*p.data(), 9); + } +} + +class AbstractClass +{ +public: + virtual ~AbstractClass() + { + } + + virtual int member() const = 0; +}; + +class SubClass : public AbstractClass +{ +public: + virtual int member() const + { + return 5; + } +}; + +void tst_QScopedPointer::dereferenceOperator() +{ + /* Dereference a basic value. */ + { + QScopedPointer<int> p(new int(5)); + + const int value2 = *p; + QCOMPARE(value2, 5); + } + + /* Dereference a pointer to an abstract class. This verifies + * that the operator returns a reference, when compiling + * with MSVC 2005. */ + { + QScopedPointer<AbstractClass> p(new SubClass()); + + QCOMPARE((*p).member(), 5); + } +} + +void tst_QScopedPointer::dereferenceOperatorSignature() +{ + /* The operator should be const. */ + { + const QScopedPointer<int> p(new int(5)); + *p; + } + + /* A reference should be returned, not a value. */ + { + const QScopedPointer<int> p(new int(5)); + Q_UNUSED(static_cast<int &>(*p)); + } + + /* Instantiated on a const object, the returned object is a const reference. */ + { + const QScopedPointer<const int> p(new int(5)); + Q_UNUSED(static_cast<const int &>(*p)); + } +} + +class AnyForm +{ +public: + int value; +}; + +void tst_QScopedPointer::pointerOperator() +{ + QScopedPointer<AnyForm> p(new AnyForm()); + p->value = 5; + + QCOMPARE(p->value, 5); +} + +void tst_QScopedPointer::pointerOperatorSignature() +{ + /* The operator should be const. */ + const QScopedPointer<AnyForm> p(new AnyForm); + p->value = 5; + + QVERIFY(p->value); +} + +void tst_QScopedPointer::negationOperator() +{ + /* Invoke on default constructed value. */ + { + QScopedPointer<int> p; + QVERIFY(!p); + } + + /* Invoke on a value. */ + { + QScopedPointer<int> p(new int(2)); + QCOMPARE(!p, false); + } +} + +void tst_QScopedPointer::negationOperatorSignature() +{ + /* The signature should be const. */ + const QScopedPointer<int> p; + !p; + + /* The return value should be bool. */ + static_cast<bool>(!p); +} + +void tst_QScopedPointer::operatorBool() +{ + /* Invoke on default constructed value. */ + { + QScopedPointer<int> p; + QCOMPARE(bool(p), false); + } + + /* Invoke on active value. */ + { + QScopedPointer<int> p(new int(3)); + QVERIFY(p); + } +} + +void tst_QScopedPointer::operatorBoolSignature() +{ + /* The signature should be const and return bool. */ + const QScopedPointer<int> p; + + (void)static_cast<bool>(p); +} + +void tst_QScopedPointer::isNull() +{ + /* Invoke on default constructed value. */ + { + QScopedPointer<int> p; + QVERIFY(p.isNull()); + } + + /* Invoke on a set value. */ + { + QScopedPointer<int> p(new int(69)); + QVERIFY(!p.isNull()); + } +} + +void tst_QScopedPointer::isNullSignature() +{ + const QScopedPointer<int> p(new int(69)); + + /* The signature should be const and return bool. */ + static_cast<bool>(p.isNull()); +} + +void tst_QScopedPointer::objectSize() +{ + /* The size of QScopedPointer should be the same as one pointer. */ + QCOMPARE(sizeof(QScopedPointer<int>), sizeof(void *)); +} + +struct RefCounted +{ + RefCounted() + : ref(0) + { + instanceCount.ref(); + } + + RefCounted(RefCounted const &) + : ref(0) + { + instanceCount.ref(); + } + + ~RefCounted() + { + QVERIFY( ref == 0 ); + instanceCount.deref(); + } + + RefCounted &operator=(RefCounted const &) + { + return *this; + } + + QAtomicInt ref; + + static QAtomicInt instanceCount; +}; + +QAtomicInt RefCounted::instanceCount = 0; + +template <class A1, class A2, class B> +void scopedPointerComparisonTest(const A1 &a1, const A2 &a2, const B &b) +{ + // test equality on equal pointers + QVERIFY(a1 == a2); + QVERIFY(a2 == a1); + + // test inequality on equal pointers + QVERIFY(!(a1 != a2)); + QVERIFY(!(a2 != a1)); + + // test equality on unequal pointers + QVERIFY(!(a1 == b)); + QVERIFY(!(a2 == b)); + QVERIFY(!(b == a1)); + QVERIFY(!(b == a2)); + + // test inequality on unequal pointers + QVERIFY(b != a1); + QVERIFY(b != a2); + QVERIFY(a1 != b); + QVERIFY(a2 != b); +} + +void tst_QScopedPointer::comparison() +{ + QCOMPARE( int(RefCounted::instanceCount), 0 ); + + { + RefCounted *a = new RefCounted; + RefCounted *b = new RefCounted; + + QCOMPARE( int(RefCounted::instanceCount), 2 ); + + QScopedPointer<RefCounted> pa1(a); + QScopedPointer<RefCounted> pa2(a); + QScopedPointer<RefCounted> pb(b); + + scopedPointerComparisonTest(pa1, pa1, pb); + scopedPointerComparisonTest(pa2, pa2, pb); + scopedPointerComparisonTest(pa1, pa2, pb); + + pa2.take(); + + QCOMPARE( int(RefCounted::instanceCount), 2 ); + } + + QCOMPARE( int(RefCounted::instanceCount), 0 ); + + { + RefCounted *a = new RefCounted[42]; + RefCounted *b = new RefCounted[43]; + + QCOMPARE( int(RefCounted::instanceCount), 85 ); + + QScopedArrayPointer<RefCounted> pa1(a); + QScopedArrayPointer<RefCounted> pa2(a); + QScopedArrayPointer<RefCounted> pb(b); + + scopedPointerComparisonTest(pa1, pa2, pb); + + pa2.take(); + + QCOMPARE( int(RefCounted::instanceCount), 85 ); + } + + QCOMPARE( int(RefCounted::instanceCount), 0 ); + + { + // QScopedSharedPointer is an internal helper class -- it is unsupported! + + RefCounted *a = new RefCounted; + RefCounted *b = new RefCounted; + + QCOMPARE( int(RefCounted::instanceCount), 2 ); + + QSharedDataPointer<RefCounted> pa1(a); + QSharedDataPointer<RefCounted> pa2(a); + QSharedDataPointer<RefCounted> pb(b); + + QCOMPARE( int(a->ref), 2 ); + QCOMPARE( int(b->ref), 1 ); + QCOMPARE( int(RefCounted::instanceCount), 2 ); + + scopedPointerComparisonTest(pa1, pa2, pb); + + QCOMPARE( int(RefCounted::instanceCount), 2 ); + } + + QCOMPARE( int(RefCounted::instanceCount), 0 ); +} + +void tst_QScopedPointer::array() +{ + int instCount = RefCounted::instanceCount; + { + QScopedArrayPointer<RefCounted> array; + array.reset(new RefCounted[42]); + QCOMPARE(instCount + 42, int(RefCounted::instanceCount)); + } + QCOMPARE(instCount, int(RefCounted::instanceCount)); + { + QScopedArrayPointer<RefCounted> array(new RefCounted[42]); + QCOMPARE(instCount + 42, int(RefCounted::instanceCount)); + array.reset(new RefCounted[28]); + QCOMPARE(instCount + 28, int(RefCounted::instanceCount)); + array.reset(0); + QCOMPARE(instCount, int(RefCounted::instanceCount)); + } + QCOMPARE(instCount, int(RefCounted::instanceCount)); +} + + +QTEST_MAIN(tst_QScopedPointer) +#include "tst_qscopedpointer.moc" |