File indexing completed on 2024-11-24 05:00:11
0001 /* 0002 SPDX-FileCopyrightText: 2013, 2014, 2015 Ivan Cukic <ivan.cukic(at)kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef COMMON_TEST_H 0008 #define COMMON_TEST_H 0009 0010 #include <QCoreApplication> 0011 #include <QDate> 0012 #include <QFuture> 0013 #include <QFutureWatcher> 0014 #include <QObject> 0015 #include <QTest> 0016 0017 class Test : public QObject 0018 { 0019 Q_OBJECT 0020 public: 0021 Test(QObject *parent = nullptr); 0022 0023 protected: 0024 enum WhenToFail { 0025 DontFail = 0, 0026 FailIfTrue = 1, 0027 FailIfFalse = 2, 0028 }; 0029 0030 template<typename _ReturnType, typename _Continuation> 0031 void continue_future(const QFuture<_ReturnType> &future, _Continuation &&continuation) 0032 { 0033 if (!future.isFinished()) { 0034 auto watcher = new QFutureWatcher<decltype(future.result())>(); 0035 QObject::connect( 0036 watcher, 0037 &QFutureWatcherBase::finished, 0038 watcher, 0039 [=] { 0040 continuation(watcher->result()); 0041 watcher->deleteLater(); 0042 }, 0043 Qt::QueuedConnection); 0044 0045 watcher->setFuture(future); 0046 0047 } else { 0048 continuation(future.result()); 0049 } 0050 } 0051 0052 template<typename _Continuation> 0053 void continue_future(const QFuture<void> &future, _Continuation &&continuation) 0054 { 0055 if (!future.isFinished()) { 0056 auto watcher = new QFutureWatcher<void>(); 0057 QObject::connect( 0058 watcher, 0059 &QFutureWatcherBase::finished, 0060 watcher, 0061 [=] { 0062 continuation(); 0063 watcher->deleteLater(); 0064 }, 0065 Qt::QueuedConnection); 0066 0067 watcher->setFuture(future); 0068 0069 } else { 0070 continuation(); 0071 } 0072 } 0073 0074 template<typename T> 0075 static inline void wait_until(T condition, const char *msg, int msecs = 300) 0076 { 0077 auto start = QTime::currentTime(); 0078 0079 while (!condition()) { 0080 QCoreApplication::processEvents(); 0081 0082 auto now = QTime::currentTime(); 0083 QVERIFY2(start.msecsTo(now) < msecs, msg); 0084 if (start.msecsTo(now) >= msecs) 0085 break; 0086 } 0087 } 0088 0089 #define TEST_WAIT_UNTIL(C) \ 0090 wait_until( \ 0091 [&]() -> bool { \ 0092 return C; \ 0093 }, \ 0094 "Timeout waiting for: " #C); 0095 #define TEST_WAIT_UNTIL_WITH_TIMEOUT(C, T) \ 0096 wait_until( \ 0097 [&]() -> bool { \ 0098 return C; \ 0099 }, \ 0100 "Timeout waiting for: " #C, \ 0101 T); 0102 0103 template<typename T> 0104 static bool check(T what, WhenToFail wtf = DontFail, const char *msg = nullptr) 0105 { 0106 bool result = what(); 0107 0108 if ((wtf == FailIfTrue && result) || (wtf == FailIfFalse && !result)) { 0109 qFatal( 0110 "\n" 0111 "\n" 0112 "!!! > \n" 0113 "!!! > %s\n" 0114 "!!! > \n", 0115 msg); 0116 } 0117 0118 return result; 0119 } 0120 0121 static bool inEmptySession(); 0122 static bool isActivityManagerRunning(); 0123 0124 Q_SIGNALS: 0125 void testFinished(); 0126 }; 0127 0128 #define CHECK_CONDITION(A, B) check(A, B, #A " raised " #B) 0129 0130 // Pretty print 0131 #include <iostream> 0132 0133 #if defined(Q_NO_DEBUG) || !defined(Q_OS_LINUX) 0134 #define TEST_CHUNK(Name) 0135 #else 0136 inline void _test_chunk(const QString &message) 0137 { 0138 std::cerr << '\n' << message.toStdString() << "\n" << std::string(message.length(), '-') << '\n'; 0139 } 0140 #define TEST_CHUNK(Name) _test_chunk(Name); 0141 #endif 0142 0143 #endif /* TEST_H */