/* SPDX-FileCopyrightText: 2013, 2014, 2015 Ivan Cukic SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef COMMON_TEST_H #define COMMON_TEST_H #include #include #include #include #include class Test : public QObject { Q_OBJECT public: Test(QObject *parent = nullptr); protected: enum WhenToFail { DontFail = 0, FailIfTrue = 1, FailIfFalse = 2, }; template void continue_future(const QFuture<_ReturnType> &future, _Continuation &&continuation) { if (!future.isFinished()) { auto watcher = new QFutureWatcher(); QObject::connect( watcher, &QFutureWatcherBase::finished, watcher, [=] { continuation(watcher->result()); watcher->deleteLater(); }, Qt::QueuedConnection); watcher->setFuture(future); } else { continuation(future.result()); } } template void continue_future(const QFuture &future, _Continuation &&continuation) { if (!future.isFinished()) { auto watcher = new QFutureWatcher(); QObject::connect( watcher, &QFutureWatcherBase::finished, watcher, [=] { continuation(); watcher->deleteLater(); }, Qt::QueuedConnection); watcher->setFuture(future); } else { continuation(); } } template static inline void wait_until(T condition, const char *msg, int msecs = 300) { auto start = QTime::currentTime(); while (!condition()) { QCoreApplication::processEvents(); auto now = QTime::currentTime(); QVERIFY2(start.msecsTo(now) < msecs, msg); if (start.msecsTo(now) >= msecs) break; } } // clang-format off #define TEST_WAIT_UNTIL(C) \ wait_until([&] () -> bool { return C; }, "Timeout waiting for: " #C); #define TEST_WAIT_UNTIL_WITH_TIMEOUT(C, T) \ wait_until([&] () ->bool { return C; }, "Timeout waiting for: " #C, T); // clang-format on template static bool check(T what, WhenToFail wtf = DontFail, const char *msg = nullptr) { bool result = what(); if ((wtf == FailIfTrue && result) || (wtf == FailIfFalse && !result)) { qFatal( "\n" "\n" "!!! > \n" "!!! > %s\n" "!!! > \n", msg); } return result; } static bool inEmptySession(); static bool isActivityManagerRunning(); Q_SIGNALS: void testFinished(); }; #define CHECK_CONDITION(A, B) check(A, B, #A " raised " #B) // Pretty print #include #if defined(Q_NO_DEBUG) || !defined(Q_OS_LINUX) #define TEST_CHUNK(Name) #else inline void _test_chunk(const QString &message) { std::cerr << '\n' << message.toStdString() << "\n" << std::string(message.length(), '-') << '\n'; } #define TEST_CHUNK(Name) _test_chunk(Name); #endif #endif /* TEST_H */