summaryrefslogtreecommitdiffstats
path: root/src/testlib/qtesteventloop.h
blob: ca442bd2b6d7dceda5107ad1192462ba7eb23e9a (plain)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
// Copyright (C) 2021 The Qt Company Ltd.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#ifndef QTESTEVENTLOOP_H#define QTESTEVENTLOOP_H#include <QtTest/qttestglobal.h>#include <QtTest/qtestcase.h>#include <QtCore/qbasictimer.h>#include <QtCore/qcoreapplication.h>#include <QtCore/qeventloop.h>#include <QtCore/qobject.h>#include <QtCore/qpointer.h>#include <QtCore/qthread.h> QT_BEGIN_NAMESPACE class Q_TESTLIB_EXPORT QTestEventLoop :public QObject { Q_OBJECT public:QTestEventLoop(QObject *parent =nullptr):QObject(parent),_timeout(false){}voidenterLoopMSecs(int ms) {enterLoop(std::chrono::milliseconds{ms}); }voidenterLoop(int secs) {enterLoop(std::chrono::seconds{secs}); }inlinevoidenterLoop(std::chrono::milliseconds msecs);inlinevoidchangeInterval(int secs){changeInterval(std::chrono::seconds{secs}); }voidchangeInterval(std::chrono::nanoseconds nsecs){ timer.start(nsecs,this); }inlinebooltimeout()const{return _timeout; }inlinestatic QTestEventLoop &instance(){ Q_CONSTINIT static QPointer<QTestEventLoop> testLoop;if(testLoop.isNull()) testLoop =newQTestEventLoop(QCoreApplication::instance());return*static_cast<QTestEventLoop *>(testLoop);}public Q_SLOTS:inlinevoidexitLoop();protected:inlinevoidtimerEvent(QTimerEvent *e) override;private: QEventLoop *loop =nullptr; QBasicTimer timer; uint _timeout :1; Q_DECL_UNUSED_MEMBER uint reserved :31;};inlinevoidQTestEventLoop::enterLoop(std::chrono::milliseconds msecs){Q_ASSERT(!loop); _timeout =false;if(QTest::runningTest() &&QTest::currentTestResolved())return;using namespacestd::chrono_literals; QEventLoop l;// if tests want to measure sub-second precision, use a precise timer timer.start(msecs, msecs <1s ?Qt::PreciseTimer :Qt::CoarseTimer,this); loop = &l; l.exec(); loop =nullptr;}inlinevoidQTestEventLoop::exitLoop(){if(thread() !=QThread::currentThread()){QMetaObject::invokeMethod(this,"exitLoop",Qt::QueuedConnection);return;} timer.stop();if(loop) loop->exit();}inlinevoidQTestEventLoop::timerEvent(QTimerEvent *e){if(e->id() != timer.id())return; _timeout =true;exitLoop();} QT_END_NAMESPACE #endif
close