1 /* This file is part of the KDE libraries
2    Copyright (C) 2006 David Faure <faure@kde.org>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License version 2 as published by the Free Software Foundation.
7 
8    This library is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11    Library General Public License for more details.
12 
13    You should have received a copy of the GNU Library General Public License
14    along with this library; see the file COPYING.LIB.  If not, write to
15    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16    Boston, MA 02110-1301, USA.
17 */
18 
19 #ifndef QTEST_KDE_H
20 #define QTEST_KDE_H
21 
22 #include <kdelibs4support_export.h>
23 #include <QTest>
24 #include <stdlib.h>
25 #include <assert.h>
26 #include <k4aboutdata.h>
27 #include <klocalizedstring.h>
28 #include <kcmdlineargs.h>
29 #include <kcomponentdata.h>
30 #include "kglobal.h"
31 #include <kurl.h>
32 #include <QApplication>
33 #include <QEventLoop>
34 #include <QSignalSpy>
35 
36 namespace QTest
37 {
38 /**
39  * Starts an event loop that runs until the given signal is received.
40  * Optionally the event loop can return earlier on a timeout.
41  *
42  * \param timeout the timeout in milliseconds
43  *
44  * \return \p true if the requested signal was received
45  *         \p false on timeout
46  * \deprecated since 5.0, use QSignalSpy::wait(timeout)
47  */
48 KDELIBS4SUPPORT_DEPRECATED_EXPORT bool kWaitForSignal(QObject *obj, const char *signal, int timeout = 0);
49 } // namespace QTest
50 
51 // By default, unit tests get no gui.
52 // Pass GUI if you use any GUI classes
53 enum KDEMainFlag { NoGUI = 0, GUI = 1 }; // bitfield, next item is 2!
54 Q_DECLARE_FLAGS(KDEMainFlags, KDEMainFlag)
55 Q_DECLARE_OPERATORS_FOR_FLAGS(KDEMainFlags)
56 /**
57  * \short QTEST_KDEMAIN variant with additional argument for the main component name
58  *
59  * This variant is useful for testing application classes which rely on the main
60  * component having a specific name (for instance to find xmlgui .rc files).
61  *
62  * This variant should not be needed in kdelibs's own unit tests.
63  *
64  * \param TestObject The class you use for testing.
65  * \param flags one of KDEMainFlag. This is passed to the QApplication constructor.
66  * \param componentName the name that will be given to the main component data.
67  *
68  * \see KDEMainFlag
69  * \see QTestLib
70  */
71 #define QTEST_KDEMAIN_WITH_COMPONENTNAME(TestObject, flags, componentName) \
72     int main(int argc, char *argv[]) \
73     { \
74         qputenv("LC_ALL", "C"); \
75         assert( !QDir::homePath().isEmpty() ); \
76         qputenv("XDG_DATA_HOME", QFile::encodeName( QDir::homePath() + QString::fromLatin1("/.kde-unit-test/xdg/local") )); \
77         qputenv("XDG_CONFIG_HOME", QFile::encodeName( QDir::homePath() + QString::fromLatin1("/.kde-unit-test/xdg/config") )); \
78         qputenv("XDG_CACHE_HOME", QFile::encodeName( QDir::homePath() + QString::fromLatin1("/.kde-unit-test/xdg/cache") )); \
79         qputenv("KDE_SKIP_KDERC", "1"); \
80         unsetenv("KDE_COLOR_DEBUG"); \
81         QFile::remove(QDir::homePath() + QString::fromLatin1("/.kde-unit-test/xdg/config/qttestrc"));  \
82         K4AboutData aboutData( QByteArray(componentName), QByteArray(), ki18n("KDE Test Program"), QByteArray("version") );  \
83         KDEMainFlags mainFlags = flags;                         \
84         KComponentData cData(&aboutData); \
85         QApplication app( argc, argv, (mainFlags & GUI) != 0 ); \
86         app.setApplicationName( QLatin1String("qttest") ); \
87         qRegisterMetaType<KUrl>(); /*as done by kapplication*/ \
88         qRegisterMetaType<QList<KUrl> >(); \
89         TestObject tc; \
90         KGlobal::ref(); /* don't quit qeventloop after closing a mainwindow */ \
91         return QTest::qExec( &tc, argc, argv ); \
92     }
93 
94 /**
95  * \short KDE Replacement for QTEST_MAIN from QTestLib
96  *
97  * This macro should be used for classes that need a KComponentData.
98  * So instead of writing QTEST_MAIN( TestClass ) you write
99  * QTEST_KDEMAIN( TestClass, GUI ).
100  *
101  * \param TestObject The class you use for testing.
102  * \param flags one of KDEMainFlag. This is passed to the QApplication constructor.
103  *
104  * \see KDEMainFlag
105  * \see QTestLib
106  */
107 #define QTEST_KDEMAIN(TestObject, flags) QTEST_KDEMAIN_WITH_COMPONENTNAME(TestObject, flags, "qttest")
108 
109 /**
110  * \short KDE Replacement for QTEST_MAIN from QTestLib, for non-gui code.
111  *
112  * This macro should be used for classes that need a KComponentData.
113  * So instead of writing QTEST_MAIN( TestClass ) you write
114  * QTEST_KDEMAIN_CORE( TestClass ).
115  *
116  * \param TestObject The class you use for testing.
117  *
118  * \see KDEMainFlag
119  * \see QTestLib
120  * \since 4.3
121  */
122 #define QTEST_KDEMAIN_CORE_WITH_COMPONENTNAME(TestObject, componentName) \
123     int main(int argc, char *argv[]) \
124     { \
125         qputenv("LC_ALL", "C"); \
126         assert( !QDir::homePath().isEmpty() ); \
127         qputenv("XDG_DATA_HOME", QFile::encodeName( QDir::homePath() + QString::fromLatin1("/.kde-unit-test/xdg/local"))); \
128         qputenv("XDG_CONFIG_HOME", QFile::encodeName( QDir::homePath() + QString::fromLatin1("/.kde-unit-test/xdg/config") )); \
129         qputenv("XDG_CACHE_HOME", QFile::encodeName( QDir::homePath() + QString::fromLatin1("/.kde-unit-test/xdg/cache") )); \
130         qputenv("KDE_SKIP_KDERC", "1"); \
131         unsetenv("KDE_COLOR_DEBUG"); \
132         QFile::remove(QDir::homePath() + QString::fromLatin1("/.kde-unit-test/xdg/config/qttestrc"));  \
133         K4AboutData aboutData( QByteArray(componentName), QByteArray(), ki18n("KDE Test Program"), QByteArray("version") );  \
134         KComponentData cData(&aboutData); \
135         QCoreApplication app( argc, argv ); \
136         app.setApplicationName( QLatin1String("qttest") ); \
137         qRegisterMetaType<KUrl>(); /*as done by kapplication*/ \
138         qRegisterMetaType<QList<KUrl> >(); \
139         TestObject tc; \
140         KGlobal::ref(); /* don't quit qeventloop after closing a mainwindow */ \
141         return QTest::qExec( &tc, argc, argv ); \
142     }
143 
144 /**
145  * \short KDE Replacement for QTEST_MAIN from QTestLib, for non-gui code.
146  *
147  * This macro should be used for classes that need a KComponentData.
148  * So instead of writing QTEST_MAIN( TestClass ) you write
149  * QTEST_KDEMAIN_CORE( TestClass ).
150  *
151  * \param TestObject The class you use for testing.
152  *
153  * \see KDEMainFlag
154  * \see QTestLib
155  */
156 #define QTEST_KDEMAIN_CORE(TestObject) QTEST_KDEMAIN_CORE_WITH_COMPONENTNAME(TestObject, "qttest")
157 
158 #endif /* QTEST_KDE_H */
159