~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the test suite of the Qt Toolkit.
 
7
**
 
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.
 
16
**
 
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.
 
24
**
 
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.
 
28
**
 
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.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#include <QtTest/QtTest>
 
43
 
 
44
#include <QPointer>
 
45
#ifndef QT_NO_WIDGETS
 
46
#include <QWidget>
 
47
#endif
 
48
 
 
49
class tst_QPointer : public QObject
 
50
{
 
51
    Q_OBJECT
 
52
public:
 
53
    inline tst_QPointer *me() const
 
54
    { return const_cast<tst_QPointer *>(this); }
 
55
 
 
56
private slots:
 
57
    void constructors();
 
58
    void destructor();
 
59
    void assignment_operators();
 
60
    void equality_operators();
 
61
    void isNull();
 
62
    void dereference_operators();
 
63
    void disconnect();
 
64
    void castDuringDestruction();
 
65
    void threadSafety();
 
66
 
 
67
    void qvariantCast();
 
68
};
 
69
 
 
70
void tst_QPointer::constructors()
 
71
{
 
72
    QPointer<QObject> p1;
 
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));
 
78
}
 
79
 
 
80
void tst_QPointer::destructor()
 
81
{
 
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));
 
89
    QCOMPARE(p1, p2);
 
90
    // Destroy the guarded object
 
91
    delete object;
 
92
    // Check that both pointers were zeroed
 
93
    QCOMPARE(p1, QPointer<QObject>(0));
 
94
    QCOMPARE(p2, QPointer<QObject>(0));
 
95
    QCOMPARE(p1, p2);
 
96
}
 
97
 
 
98
void tst_QPointer::assignment_operators()
 
99
{
 
100
    QPointer<QObject> p1;
 
101
    QPointer<QObject> p2;
 
102
 
 
103
    // Test assignment with a QObject-derived object pointer
 
104
    p1 = this;
 
105
    p2 = p1;
 
106
    QCOMPARE(p1, QPointer<QObject>(this));
 
107
    QCOMPARE(p2, QPointer<QObject>(this));
 
108
    QCOMPARE(p1, QPointer<QObject>(p2));
 
109
 
 
110
    // Test assignment with a null pointer
 
111
    p1 = 0;
 
112
    p2 = p1;
 
113
    QCOMPARE(p1, QPointer<QObject>(0));
 
114
    QCOMPARE(p2, QPointer<QObject>(0));
 
115
    QCOMPARE(p1, QPointer<QObject>(p2));
 
116
 
 
117
    // Test assignment with a real QObject pointer
 
118
    QObject *object = new QObject;
 
119
 
 
120
    p1 = object;
 
121
    p2 = p1;
 
122
    QCOMPARE(p1, QPointer<QObject>(object));
 
123
    QCOMPARE(p2, QPointer<QObject>(object));
 
124
    QCOMPARE(p1, QPointer<QObject>(p2));
 
125
 
 
126
    // Test assignment with the same pointer that's already guarded
 
127
    p1 = object;
 
128
    p2 = p1;
 
129
    QCOMPARE(p1, QPointer<QObject>(object));
 
130
    QCOMPARE(p2, QPointer<QObject>(object));
 
131
    QCOMPARE(p1, QPointer<QObject>(p2));
 
132
 
 
133
    // Cleanup
 
134
    delete object;
 
135
}
 
136
 
 
137
void tst_QPointer::equality_operators()
 
138
{
 
139
    QPointer<QObject> p1;
 
140
    QPointer<QObject> p2;
 
141
 
 
142
    QVERIFY(p1 == p2);
 
143
 
 
144
    QObject *object = 0;
 
145
#ifndef QT_NO_WIDGETS
 
146
    QWidget *widget = 0;
 
147
#endif
 
148
 
 
149
    p1 = object;
 
150
    QVERIFY(p1 == p2);
 
151
    QVERIFY(p1 == object);
 
152
    p2 = object;
 
153
    QVERIFY(p2 == p1);
 
154
    QVERIFY(p2 == object);
 
155
 
 
156
    p1 = this;
 
157
    QVERIFY(p1 != p2);
 
158
    p2 = p1;
 
159
    QVERIFY(p1 == p2);
 
160
 
 
161
    // compare to zero
 
162
    p1 = 0;
 
163
    QVERIFY(p1 == 0);
 
164
    QVERIFY(0 == p1);
 
165
    QVERIFY(p2 != 0);
 
166
    QVERIFY(0 != p2);
 
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);
 
176
#endif
 
177
}
 
178
 
 
179
void tst_QPointer::isNull()
 
180
{
 
181
    QPointer<QObject> p1;
 
182
    QVERIFY(p1.isNull());
 
183
    p1 = this;
 
184
    QVERIFY(!p1.isNull());
 
185
    p1 = 0;
 
186
    QVERIFY(p1.isNull());
 
187
}
 
188
 
 
189
void tst_QPointer::dereference_operators()
 
190
{
 
191
    QPointer<tst_QPointer> p1 = this;
 
192
    QPointer<tst_QPointer> p2;
 
193
 
 
194
    // operator->() -- only makes sense if not null
 
195
    QObject *object = p1->me();
 
196
    QCOMPARE(object, this);
 
197
 
 
198
    // operator*() -- only makes sense if not null
 
199
    QObject &ref = *p1;
 
200
    QCOMPARE(&ref, this);
 
201
 
 
202
    // operator T*()
 
203
    QCOMPARE(static_cast<QObject *>(p1), this);
 
204
    QCOMPARE(static_cast<QObject *>(p2), static_cast<QObject *>(0));
 
205
 
 
206
    // data()
 
207
    QCOMPARE(p1.data(), this);
 
208
    QCOMPARE(p2.data(), static_cast<QObject *>(0));
 
209
}
 
210
 
 
211
void tst_QPointer::disconnect()
 
212
{
 
213
    // Verify that pointer remains guarded when all signals are disconencted.
 
214
    QPointer<QObject> p1 = new QObject;
 
215
    QVERIFY(!p1.isNull());
 
216
    p1->disconnect();
 
217
    QVERIFY(!p1.isNull());
 
218
    delete static_cast<QObject *>(p1);
 
219
    QVERIFY(p1.isNull());
 
220
}
 
221
 
 
222
class ChildObject : public QObject
 
223
{
 
224
    QPointer<QObject> guardedPointer;
 
225
 
 
226
public:
 
227
    ChildObject(QObject *parent)
 
228
        : QObject(parent), guardedPointer(parent)
 
229
    { }
 
230
    ~ChildObject();
 
231
};
 
232
 
 
233
ChildObject::~ChildObject()
 
234
{
 
235
    QCOMPARE(static_cast<QObject *>(guardedPointer), static_cast<QObject *>(0));
 
236
    QCOMPARE(qobject_cast<QObject *>(guardedPointer), static_cast<QObject *>(0));
 
237
}
 
238
 
 
239
#ifndef QT_NO_WIDGETS
 
240
class ChildWidget : public QWidget
 
241
{
 
242
    QPointer<QWidget> guardedPointer;
 
243
 
 
244
public:
 
245
    ChildWidget(QWidget *parent)
 
246
        : QWidget(parent), guardedPointer(parent)
 
247
    { }
 
248
    ~ChildWidget();
 
249
};
 
250
 
 
251
ChildWidget::~ChildWidget()
 
252
{
 
253
    QCOMPARE(static_cast<QWidget *>(guardedPointer), parentWidget());
 
254
    QCOMPARE(qobject_cast<QWidget *>(guardedPointer), parentWidget());
 
255
}
 
256
#endif
 
257
 
 
258
class DerivedChild;
 
259
 
 
260
class DerivedParent : public QObject
 
261
{
 
262
    Q_OBJECT
 
263
 
 
264
    DerivedChild *derivedChild;
 
265
 
 
266
public:
 
267
    DerivedParent();
 
268
    ~DerivedParent();
 
269
};
 
270
 
 
271
class DerivedChild : public QObject
 
272
{
 
273
    Q_OBJECT
 
274
 
 
275
    DerivedParent *parentPointer;
 
276
    QPointer<DerivedParent> guardedParentPointer;
 
277
 
 
278
public:
 
279
    DerivedChild(DerivedParent *parent)
 
280
        : QObject(parent), parentPointer(parent), guardedParentPointer(parent)
 
281
    { }
 
282
    ~DerivedChild();
 
283
};
 
284
 
 
285
DerivedParent::DerivedParent()
 
286
    : QObject()
 
287
{
 
288
    derivedChild = new DerivedChild(this);
 
289
}
 
290
 
 
291
DerivedParent::~DerivedParent()
 
292
{
 
293
    delete derivedChild;
 
294
}
 
295
 
 
296
DerivedChild::~DerivedChild()
 
297
{
 
298
    QCOMPARE(static_cast<DerivedParent *>(guardedParentPointer), parentPointer);
 
299
    QCOMPARE(qobject_cast<DerivedParent *>(guardedParentPointer), parentPointer);
 
300
}
 
301
 
 
302
void tst_QPointer::castDuringDestruction()
 
303
{
 
304
    {
 
305
        QObject *parentObject = new QObject();
 
306
        (void) new ChildObject(parentObject);
 
307
        delete parentObject;
 
308
    }
 
309
 
 
310
#ifndef QT_NO_WIDGETS
 
311
    {
 
312
        QWidget *parentWidget = new QWidget();
 
313
        (void) new ChildWidget(parentWidget);
 
314
        delete parentWidget;
 
315
    }
 
316
#endif
 
317
 
 
318
    {
 
319
        delete new DerivedParent();
 
320
    }
 
321
}
 
322
 
 
323
class TestRunnable : public QObject, public QRunnable {
 
324
    void run() {
 
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
 
331
    }
 
332
};
 
333
 
 
334
void tst_QPointer::threadSafety()
 
335
{
 
336
 
 
337
    QThread owner;
 
338
    owner.start();
 
339
 
 
340
    QThreadPool pool;
 
341
    for (int i = 0; i < 300; i++) {
 
342
        QPointer<TestRunnable> task = new TestRunnable;
 
343
        task->setAutoDelete(true);
 
344
        task->moveToThread(&owner);
 
345
        pool.start(task);
 
346
    }
 
347
    pool.waitForDone();
 
348
 
 
349
    owner.quit();
 
350
    owner.wait();
 
351
}
 
352
 
 
353
void tst_QPointer::qvariantCast()
 
354
{
 
355
    QPointer<QFile> tracking = new QFile;
 
356
    tracking->setObjectName("A test name");
 
357
    QVariant v = QVariant::fromValue(tracking);
 
358
 
 
359
    {
 
360
        QPointer<QObject> other = qPointerFromVariant<QObject>(v);
 
361
        QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
 
362
    }
 
363
    {
 
364
        QPointer<QIODevice> other = qPointerFromVariant<QIODevice>(v);
 
365
        QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
 
366
    }
 
367
    {
 
368
        QPointer<QFile> other = qPointerFromVariant<QFile>(v);
 
369
        QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
 
370
    }
 
371
    {
 
372
        QPointer<QThread> other = qPointerFromVariant<QThread>(v);
 
373
        QVERIFY(!other);
 
374
    }
 
375
    {
 
376
        QPointer<QFile> toBeDeleted = new QFile;
 
377
        QVariant deletedVariant = QVariant::fromValue(toBeDeleted);
 
378
        delete toBeDeleted;
 
379
        QPointer<QObject> deleted = qPointerFromVariant<QObject>(deletedVariant);
 
380
        QVERIFY(!deleted);
 
381
    }
 
382
 
 
383
    // Intentionally does not compile.
 
384
//     QPointer<int> sop = qPointerFromVariant<int>(v);
 
385
}
 
386
 
 
387
 
 
388
 
 
389
QTEST_MAIN(tst_QPointer)
 
390
#include "tst_qpointer.moc"