1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#include <QtTest/QtTest>
49
class tst_QPointer : public QObject
53
inline tst_QPointer *me() const
54
{ return const_cast<tst_QPointer *>(this); }
59
void assignment_operators();
60
void equality_operators();
62
void dereference_operators();
64
void castDuringDestruction();
70
void tst_QPointer::constructors()
73
QPointer<QObject> p2(this);
74
QPointer<QObject> p3(p2);
75
QCOMPARE(p1, QPointer<QObject>(0));
76
QCOMPARE(p2, QPointer<QObject>(this));
77
QCOMPARE(p3, QPointer<QObject>(this));
80
void tst_QPointer::destructor()
82
// Make two QPointer's to the same object
83
QObject *object = new QObject;
84
QPointer<QObject> p1 = object;
85
QPointer<QObject> p2 = object;
86
// Check that they point to the correct object
87
QCOMPARE(p1, QPointer<QObject>(object));
88
QCOMPARE(p2, QPointer<QObject>(object));
90
// Destroy the guarded object
92
// Check that both pointers were zeroed
93
QCOMPARE(p1, QPointer<QObject>(0));
94
QCOMPARE(p2, QPointer<QObject>(0));
98
void tst_QPointer::assignment_operators()
100
QPointer<QObject> p1;
101
QPointer<QObject> p2;
103
// Test assignment with a QObject-derived object pointer
106
QCOMPARE(p1, QPointer<QObject>(this));
107
QCOMPARE(p2, QPointer<QObject>(this));
108
QCOMPARE(p1, QPointer<QObject>(p2));
110
// Test assignment with a null pointer
113
QCOMPARE(p1, QPointer<QObject>(0));
114
QCOMPARE(p2, QPointer<QObject>(0));
115
QCOMPARE(p1, QPointer<QObject>(p2));
117
// Test assignment with a real QObject pointer
118
QObject *object = new QObject;
122
QCOMPARE(p1, QPointer<QObject>(object));
123
QCOMPARE(p2, QPointer<QObject>(object));
124
QCOMPARE(p1, QPointer<QObject>(p2));
126
// Test assignment with the same pointer that's already guarded
129
QCOMPARE(p1, QPointer<QObject>(object));
130
QCOMPARE(p2, QPointer<QObject>(object));
131
QCOMPARE(p1, QPointer<QObject>(p2));
137
void tst_QPointer::equality_operators()
139
QPointer<QObject> p1;
140
QPointer<QObject> p2;
145
#ifndef QT_NO_WIDGETS
151
QVERIFY(p1 == object);
154
QVERIFY(p2 == object);
167
QVERIFY(p1 == object);
168
QVERIFY(object == p1);
169
QVERIFY(p2 != object);
170
QVERIFY(object != p2);
171
#ifndef QT_NO_WIDGETS
172
QVERIFY(p1 == widget);
173
QVERIFY(widget == p1);
174
QVERIFY(p2 != widget);
175
QVERIFY(widget != p2);
179
void tst_QPointer::isNull()
181
QPointer<QObject> p1;
182
QVERIFY(p1.isNull());
184
QVERIFY(!p1.isNull());
186
QVERIFY(p1.isNull());
189
void tst_QPointer::dereference_operators()
191
QPointer<tst_QPointer> p1 = this;
192
QPointer<tst_QPointer> p2;
194
// operator->() -- only makes sense if not null
195
QObject *object = p1->me();
196
QCOMPARE(object, this);
198
// operator*() -- only makes sense if not null
200
QCOMPARE(&ref, this);
203
QCOMPARE(static_cast<QObject *>(p1), this);
204
QCOMPARE(static_cast<QObject *>(p2), static_cast<QObject *>(0));
207
QCOMPARE(p1.data(), this);
208
QCOMPARE(p2.data(), static_cast<QObject *>(0));
211
void tst_QPointer::disconnect()
213
// Verify that pointer remains guarded when all signals are disconencted.
214
QPointer<QObject> p1 = new QObject;
215
QVERIFY(!p1.isNull());
217
QVERIFY(!p1.isNull());
218
delete static_cast<QObject *>(p1);
219
QVERIFY(p1.isNull());
222
class ChildObject : public QObject
224
QPointer<QObject> guardedPointer;
227
ChildObject(QObject *parent)
228
: QObject(parent), guardedPointer(parent)
233
ChildObject::~ChildObject()
235
QCOMPARE(static_cast<QObject *>(guardedPointer), static_cast<QObject *>(0));
236
QCOMPARE(qobject_cast<QObject *>(guardedPointer), static_cast<QObject *>(0));
239
#ifndef QT_NO_WIDGETS
240
class ChildWidget : public QWidget
242
QPointer<QWidget> guardedPointer;
245
ChildWidget(QWidget *parent)
246
: QWidget(parent), guardedPointer(parent)
251
ChildWidget::~ChildWidget()
253
QCOMPARE(static_cast<QWidget *>(guardedPointer), parentWidget());
254
QCOMPARE(qobject_cast<QWidget *>(guardedPointer), parentWidget());
260
class DerivedParent : public QObject
264
DerivedChild *derivedChild;
271
class DerivedChild : public QObject
275
DerivedParent *parentPointer;
276
QPointer<DerivedParent> guardedParentPointer;
279
DerivedChild(DerivedParent *parent)
280
: QObject(parent), parentPointer(parent), guardedParentPointer(parent)
285
DerivedParent::DerivedParent()
288
derivedChild = new DerivedChild(this);
291
DerivedParent::~DerivedParent()
296
DerivedChild::~DerivedChild()
298
QCOMPARE(static_cast<DerivedParent *>(guardedParentPointer), parentPointer);
299
QCOMPARE(qobject_cast<DerivedParent *>(guardedParentPointer), parentPointer);
302
void tst_QPointer::castDuringDestruction()
305
QObject *parentObject = new QObject();
306
(void) new ChildObject(parentObject);
310
#ifndef QT_NO_WIDGETS
312
QWidget *parentWidget = new QWidget();
313
(void) new ChildWidget(parentWidget);
319
delete new DerivedParent();
323
class TestRunnable : public QObject, public QRunnable {
325
QPointer<QObject> obj1 = new QObject;
326
QPointer<QObject> obj2 = new QObject;
327
obj1->moveToThread(thread()); // this is the owner thread
328
obj1->deleteLater(); // the delete will happen in the owner thread
329
obj2->moveToThread(thread()); // this is the owner thread
330
obj2->deleteLater(); // the delete will happen in the owner thread
334
void tst_QPointer::threadSafety()
341
for (int i = 0; i < 300; i++) {
342
QPointer<TestRunnable> task = new TestRunnable;
343
task->setAutoDelete(true);
344
task->moveToThread(&owner);
353
void tst_QPointer::qvariantCast()
355
QPointer<QFile> tracking = new QFile;
356
tracking->setObjectName("A test name");
357
QVariant v = QVariant::fromValue(tracking);
360
QPointer<QObject> other = qPointerFromVariant<QObject>(v);
361
QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
364
QPointer<QIODevice> other = qPointerFromVariant<QIODevice>(v);
365
QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
368
QPointer<QFile> other = qPointerFromVariant<QFile>(v);
369
QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
372
QPointer<QThread> other = qPointerFromVariant<QThread>(v);
376
QPointer<QFile> toBeDeleted = new QFile;
377
QVariant deletedVariant = QVariant::fromValue(toBeDeleted);
379
QPointer<QObject> deleted = qPointerFromVariant<QObject>(deletedVariant);
383
// Intentionally does not compile.
384
// QPointer<int> sop = qPointerFromVariant<int>(v);
389
QTEST_MAIN(tst_QPointer)
390
#include "tst_qpointer.moc"