diff options
Diffstat (limited to 'src/testlib/qtestcase.cpp')
-rw-r--r-- | src/testlib/qtestcase.cpp | 194 |
1 files changed, 177 insertions, 17 deletions
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 435ecf4..70c8c8d 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -72,6 +72,8 @@ #include <windows.h> // for Sleep #endif #ifdef Q_OS_UNIX +#include <errno.h> +#include <signal.h> #include <time.h> #endif @@ -401,7 +403,8 @@ QT_BEGIN_NAMESPACE \overload - Simulates clicking of \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. + Simulates clicking of \a key with an optional \a modifier on a \a widget. + If \a delay is larger than 0, the test will wait for \a delay milliseconds. Example: \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 13 @@ -414,7 +417,8 @@ QT_BEGIN_NAMESPACE /*! \fn void QTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) - Simulates clicking of \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. + Simulates clicking of \a key with an optional \a modifier on a \a widget. + If \a delay is larger than 0, the test will wait for \a delay milliseconds. Examples: \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 14 @@ -429,20 +433,25 @@ QT_BEGIN_NAMESPACE /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) - Sends a Qt key event to \a widget with the given \a key and an associated \a action. Optionally, a keyboard \a modifier can be specified, as well as a \a delay (in milliseconds) of the test before sending the event. + Sends a Qt key event to \a widget with the given \a key and an associated \a action. + Optionally, a keyboard \a modifier can be specified, as well as a \a delay + (in milliseconds) of the test before sending the event. */ /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) \overload - Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action. Optionally, a keyboard \a modifier can be specified, as well as a \a delay (in milliseconds) of the test before sending the event. + Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action. + Optionally, a keyboard \a modifier can be specified, as well as a \a delay + (in milliseconds) of the test before sending the event. */ /*! \fn void QTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) - Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. + Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay + is larger than 0, the test will wait for \a delay milliseconds. \bold {Note:} At some point you should release the key using \l keyRelease(). @@ -453,7 +462,8 @@ QT_BEGIN_NAMESPACE \overload - Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. + Simulates pressing a \a key with an optional \a modifier on a \a widget. + If \a delay is larger than 0, the test will wait for \a delay milliseconds. \bold {Note:} At some point you should release the key using \l keyRelease(). @@ -462,7 +472,8 @@ QT_BEGIN_NAMESPACE /*! \fn void QTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) - Simulates releasing a \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. + Simulates releasing a \a key with an optional \a modifier on a \a widget. + If \a delay is larger than 0, the test will wait for \a delay milliseconds. \sa QTest::keyPress(), QTest::keyClick() */ @@ -471,7 +482,8 @@ QT_BEGIN_NAMESPACE \overload - Simulates releasing a \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. + Simulates releasing a \a key with an optional \a modifier on a \a widget. + If \a delay is larger than 0, the test will wait for \a delay milliseconds. \sa QTest::keyClick() */ @@ -687,6 +699,84 @@ QT_BEGIN_NAMESPACE \sa QTest::qSleep() */ +/*! + \class QTest::QTouchEventSequence + \inmodule QtTest + \since 4.6 + + \brief The QTouchEventSequence class is used to simulate a sequence of touch events. + + To simulate a sequence of touch events on a specific device for a widget, call + QTest::touchEvent to create a QTouchEventSequence instance. Add touch events to + the sequence by calling press(), move(), release() and stationary(), and let the + instance run out of scope to commit the sequence to the event system. +*/ + +/*! + \fn QTest::QTouchEventSequence::~QTouchEventSequence() + + Commits this sequence of touch events and frees allocated resources. +*/ + +/*! + \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWidget *widget) + + Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns + a reference to this QTouchEventSequence. + + The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then + \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence. + + Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId. +*/ + +/*! + \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWidget *widget) + + Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns + a reference to this QTouchEventSequence. + + The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then + \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence. + + Simulates that the user moved the finger identified by \a touchId. +*/ + +/*! + \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWidget *widget) + + Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns + a reference to this QTouchEventSequence. + + The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then + \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence. + + Simulates that the user lifted the finger identified by \a touchId. +*/ + +/*! + \fn QTouchEventSequence &QTest::QTouchEventSequence::stationary(int touchId) + + Adds a stationary event for touchpoint \a touchId to this sequence and returns + a reference to this QTouchEventSequence. + + Simulates that the user did not move the finger identified by \a touchId. +*/ + +/*! + \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchEvent::DeviceType deviceType) + + Creates and returns a QTouchEventSequence for the device \a deviceType to + simulate events for \a widget. + + When adding touch events to the sequence, \a widget will also be used to translate + the position provided to screen coordinates, unless another widget is provided in the + respective calls to press(), move() etc. + + The touch events are committed to the event system when the destructor of the + QTouchEventSequence is called (ie when the object returned runs out of scope). +*/ + namespace QTest { static QObject *currentTestObject = 0; @@ -1330,6 +1420,80 @@ static void qInvokeTestMethods(QObject *testObject) QTestLog::stopLogging(); } +#ifdef Q_OS_UNIX +class FatalSignalHandler +{ +public: + FatalSignalHandler(); + ~FatalSignalHandler(); + +private: + static void signal(int); + sigset_t handledSignals; +}; + +void FatalSignalHandler::signal(int signum) +{ + qFatal("Received signal %d", signum); +} + +FatalSignalHandler::FatalSignalHandler() +{ + sigemptyset(&handledSignals); + + const int fatalSignals[] = { + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 }; + + struct sigaction act; + memset(&act, 0, sizeof(act)); + act.sa_handler = FatalSignalHandler::signal; + + // Remove the handler after it is invoked. + act.sa_flags = SA_RESETHAND; + + // Block all fatal signals in our signal handler so we don't try to close + // the testlog twice. + sigemptyset(&act.sa_mask); + for (int i = 0; fatalSignals[i]; ++i) + sigaddset(&act.sa_mask, fatalSignals[i]); + + struct sigaction oldact; + + for (int i = 0; fatalSignals[i]; ++i) { + sigaction(fatalSignals[i], &act, &oldact); + // Don't overwrite any non-default handlers + if (oldact.sa_flags & SA_SIGINFO || oldact.sa_handler != SIG_DFL) { + sigaction(fatalSignals[i], &oldact, 0); + } else { + sigaddset(&handledSignals, fatalSignals[i]); + } + } +} + + +FatalSignalHandler::~FatalSignalHandler() +{ + // Unregister any of our remaining signal handlers + struct sigaction act; + memset(&act, 0, sizeof(act)); + act.sa_handler = SIG_DFL; + + struct sigaction oldact; + + for (int i = 0; i < 32; ++i) { + if (!sigismember(&handledSignals, i)) + continue; + sigaction(i, &act, &oldact); + + // If someone overwrote it in the mean time, put it back + if (oldact.sa_handler != FatalSignalHandler::signal) + sigaction(i, &oldact, 0); + } +} + +#endif + + } // namespace /*! @@ -1424,14 +1588,14 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) QBenchmarkValgrindUtils::cleanup(); - } else { + } else +#endif + { +#ifdef Q_OS_UNIX + FatalSignalHandler handler; #endif - qInvokeTestMethods(testObject); - -#ifdef QTESTLIB_USE_VALGRIND } -#endif #ifndef QT_NO_EXCEPTIONS } catch (...) { @@ -1927,8 +2091,4 @@ bool QTest::compare_string_helper(const char *t1, const char *t2, const char *ac \internal */ -/*! \fn int QTest::qt_snprintf(char *str, int size, const char *format, ...) - \internal -*/ - QT_END_NAMESPACE |