d/control: Recommend gdb
[gammaray-debian.git] / tests / test_connections.cpp
blob87772d45b3c1254270316a2618466219294a2bbc
1 /*
2 test_connections.cpp
4 This file is part of GammaRay, the Qt application inspection and
5 manipulation tool.
7 Copyright (C) 2010-2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
8 Author: Milian Wolff <milian.wolff@kdab.com>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "test_connections.h"
26 #include <QtCore/QDebug>
27 #include <QApplication>
28 #include <QtCore/QTimer>
29 #include <QtTest/QtTestGui>
30 #include <QtCore/QProcessEnvironment>
32 const int TIMEOUTINTERVAL = 10;
33 const int OBJECTS = 50;
34 const int TIMEOUTS = 100;
36 //BEGIN TestObject
37 TestObject::TestObject(QObject *parent)
38 : QObject(parent)
39 // test object creation in ctor
40 , child(new QObject(this))
42 setObjectName("TestObject");
43 child->setObjectName("TestObjectChild");
44 // test connect/disconnect in ctor
45 connect(child, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
46 disconnect(child, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
47 // now connect again for dtor
48 connect(child, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
51 TestObject::~TestObject()
53 // test disconnect
54 disconnect(child, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
55 // test connect, and leave it around to test disconnect-on-delete
56 connect(child, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
59 //END TestObject
61 //BEGIN TestConnections
62 TestConnections::TestConnections(TestConnections::Type type, int timeOuts, int timeoutInterval)
63 : m_type(type), m_timeOuts(timeOuts), m_numTimeout(0), m_timer(new QTimer(this))
65 m_timer = new QTimer(this);
66 connect(m_timer, SIGNAL(timeout()), SLOT(timeout()));
67 m_timer->start(timeoutInterval == -1 ? TIMEOUTINTERVAL : timeoutInterval);
70 TestConnections::~TestConnections()
74 void TestConnections::timeout()
76 if (m_numTimeout == m_timeOuts) {
77 qDeleteAll(m_objects);
78 m_objects.clear();
79 emit done();
80 delete m_timer;
81 m_timer = 0;
82 return;
84 m_numTimeout++;
86 if (m_type == NoEventLoop) {
87 // directly create and delete objects without eventloop in between
88 QObject *obj = new TestObject(this);
89 connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
90 delete obj;
91 } else if (m_type == Stack) {
92 QObject obj;
93 connect(&obj, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
94 disconnect(&obj, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
95 } else if (m_type == SetParent) {
96 TestObject *obj = new TestObject;
97 obj->setParent(this);
98 obj->child->setParent(0);
99 obj->child->setParent(obj);
100 obj->deleteLater();
101 } else {
102 // delete last objects
103 for (int i = 0; i < m_objects.count(); ++i) {
104 QObject *obj = m_objects.at(i);
105 switch(m_type) {
106 case Delete:
107 delete obj;
108 break;
109 case DeleteLater:
110 obj->deleteLater();
111 break;
112 default:
113 break;
116 m_objects.clear();
118 // create some new objects
119 for (int i = 0; i < OBJECTS; ++i) {
120 QObject *obj = new TestObject(this);
121 m_objects << obj;
122 connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(dummySlot()));
126 //END TestConnections
128 //BEGIN TestThread
129 TestThread::TestThread(TestConnections::Type type, int timeOuts, int timeoutInterval,
130 QObject *parent)
131 : QThread(parent), m_type(type), m_timeOuts(timeOuts), m_timeoutInterval(timeoutInterval)
135 TestThread::~TestThread()
139 void TestThread::run()
141 TestConnections tester(m_type, m_timeOuts, m_timeoutInterval == -1 ?
142 TIMEOUTS : m_timeoutInterval);
144 QEventLoop *loop = new QEventLoop;
145 connect(&tester, SIGNAL(done()), loop, SLOT(quit()));
146 loop->exec();
147 delete loop;
149 //END TestThread
151 //BEGIN TestWaiter
152 void TestWaiter::addTester(TestConnections *tester)
154 connect(tester, SIGNAL(done()), SLOT(testerDone()));
155 m_tester << tester;
158 void TestWaiter::testerDone()
160 TestConnections* tester = qobject_cast<TestConnections*>(sender());
161 QVERIFY(tester);
162 QVERIFY(m_tester.removeOne(tester));
163 checkFinished();
166 void TestWaiter::addThread(TestThread *thread)
168 connect(thread, SIGNAL(finished()), SLOT(threadFinished()));
169 m_threads << thread;
172 void TestWaiter::threadFinished()
174 TestThread* thread = qobject_cast<TestThread*>(sender());
175 QVERIFY(thread);
176 QVERIFY(m_threads.removeOne(thread));
177 checkFinished();
180 void TestWaiter::checkFinished()
182 if (!m_loop) {
183 return;
185 if (m_threads.isEmpty() && m_tester.isEmpty()) {
186 m_loop->quit();
190 void TestWaiter::startThreadsAndWaitForFinished()
192 if (m_threads.isEmpty() && m_tester.isEmpty()) {
193 return;
196 foreach (TestThread *thread, m_threads) {
197 thread->start();
200 m_loop = new QEventLoop;
201 m_loop->exec();
202 delete m_loop;
203 m_loop = 0;
205 //END TestWaiter
207 //BEGIN TestMain
209 TestMain::TestMain(int argc, char **argv)
210 : m_argc(argc), m_argv(argv)
212 QMetaObject::invokeMethod(this, "startTests", Qt::QueuedConnection);
215 void TestMain::startTests()
217 qApp->exit(QTest::qExec(this, m_argc, m_argv));
220 void TestMain::run_data()
222 QTest::addColumn<int>("type");
223 QTest::newRow("delete") << static_cast<int>(TestConnections::Delete);
224 QTest::newRow("deleteLater") << static_cast<int>(TestConnections::DeleteLater);
225 QTest::newRow("noEventLoop") << static_cast<int>(TestConnections::NoEventLoop);
226 QTest::newRow("stack") << static_cast<int>(TestConnections::Stack);
227 QTest::newRow("setParent") << static_cast<int>(TestConnections::SetParent);
230 void TestMain::run()
232 QFETCH(int, type);
234 bool manual = QProcessEnvironment::systemEnvironment().value("GAMMARAY_TEST_MANUAL").toInt();
235 TestConnections tester(static_cast<TestConnections::Type>(type),
236 manual ? -1 : TIMEOUTS);
238 TestWaiter waiter;
239 waiter.addTester(&tester);
240 waiter.startThreadsAndWaitForFinished();
243 void TestMain::threading()
245 TestWaiter waiter;
246 const int timeouts = 10;
247 // some testers to be run in the main thread
248 // with varying timouts
249 TestConnections tester1(TestConnections::NoEventLoop, timeouts, 10);
250 waiter.addTester(&tester1);
251 TestConnections tester2(TestConnections::Delete, timeouts, 11);
252 waiter.addTester(&tester2);
253 TestConnections tester3(TestConnections::DeleteLater, timeouts, 12);
254 waiter.addTester(&tester3);
255 TestConnections tester4(TestConnections::Stack, timeouts, 13);
256 waiter.addTester(&tester4);
257 TestConnections tester5(TestConnections::SetParent, timeouts, 14);
258 waiter.addTester(&tester5);
259 // now some threads
260 TestThread thread1(TestConnections::NoEventLoop, timeouts, 10);
261 waiter.addThread(&thread1);
262 TestThread thread2(TestConnections::Delete, timeouts, 11);
263 waiter.addThread(&thread2);
264 TestThread thread3(TestConnections::DeleteLater, timeouts, 12);
265 waiter.addThread(&thread3);
266 TestThread thread4(TestConnections::Stack, timeouts, 13);
267 waiter.addThread(&thread4);
268 TestThread thread5(TestConnections::SetParent, timeouts, 13);
269 waiter.addThread(&thread5);
271 waiter.startThreadsAndWaitForFinished();
273 //END TestMain
275 int main(int argc, char *argv[]) {
276 QApplication app(argc, argv);
277 TestMain tc(argc, argv);
278 return app.exec();
280 #include "test_connections.moc"