diff options
Diffstat (limited to 'src/testlib')
-rw-r--r-- | src/testlib/qplaintestlogger.cpp | 2 | ||||
-rw-r--r-- | src/testlib/qtestcase.cpp | 200 | ||||
-rw-r--r-- | src/testlib/qtestfilelogger.cpp | 25 |
3 files changed, 198 insertions, 29 deletions
diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp index ce4bb5d..3560331 100644 --- a/src/testlib/qplaintestlogger.cpp +++ b/src/testlib/qplaintestlogger.cpp @@ -155,7 +155,7 @@ namespace QTest { int length = strlen(str); for (int pos = 0; pos < length; pos +=255) { QString uniText = QString::fromLatin1(str + pos, 255); - OutputDebugStringW((const LPCWSTR) uniText.utf16()); + OutputDebugString((wchar_t*)uniText.utf16()); } if (QTestLog::outputFileName()) #elif defined(Q_OS_WIN) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 00e532a..a8a4b1a 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 @@ -406,7 +408,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 @@ -419,7 +422,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 @@ -434,20 +438,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(). @@ -458,7 +467,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(). @@ -467,7 +477,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() */ @@ -476,7 +487,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() */ @@ -692,6 +704,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; @@ -852,7 +942,7 @@ static void qParseArgs(int argc, char *argv[]) " -iterations n : Sets the number of accumulation iterations.\n" " -median n : Sets the number of median iterations.\n" " -vb : Print out verbose benchmarking information.\n" -#if !defined(QT_NO_PROCESS) || !defined(QT_NO_SETTINGS) +#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS) " -chart : Create chart based on the benchmark result.\n" #endif "\n" @@ -968,7 +1058,7 @@ static void qParseArgs(int argc, char *argv[]) } else if (strcmp(argv[i], "-vb") == 0) { QBenchmarkGlobalData::current->verboseOutput = true; -#if !defined(QT_NO_PROCESS) || !defined(QT_NO_SETTINGS) +#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS) } else if (strcmp(argv[i], "-chart") == 0) { QBenchmarkGlobalData::current->createChart = true; QTestLog::setLogMode(QTestLog::XML); @@ -1335,6 +1425,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 = 1; 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 /*! @@ -1434,14 +1598,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 (...) { @@ -1473,7 +1637,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) #endif -#if !defined(QT_NO_PROCESS) || !defined(QT_NO_SETTINGS) +#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS) if (QBenchmarkGlobalData::current->createChart) { QString chartLocation = QLibraryInfo::location(QLibraryInfo::BinariesPath); #ifdef Q_OS_WIN @@ -1937,8 +2101,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 diff --git a/src/testlib/qtestfilelogger.cpp b/src/testlib/qtestfilelogger.cpp index 0c146b4..a717058 100644 --- a/src/testlib/qtestfilelogger.cpp +++ b/src/testlib/qtestfilelogger.cpp @@ -72,15 +72,24 @@ void QTestFileLogger::init() QTest::qt_snprintf(filename, sizeof(filename), "%s.log", QTestResult::currentTestObjectName()); - #if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_OS_WINCE) - if (::fopen_s(&QTest::stream, filename, "wt")) { - #else - QTest::stream = ::fopen(filename, "wt"); - if (!QTest::stream) { - #endif - printf("Unable to open file for simple logging: %s", filename); - ::exit(1); + // Keep filenames simple + for (int i = 0; i < sizeof(filename) && filename[i]; ++i) { + char& c = filename[i]; + if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '-' + || c == '.')) { + c = '_'; } + } + +#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_OS_WINCE) + if (::fopen_s(&QTest::stream, filename, "wt")) { +#else + QTest::stream = ::fopen(filename, "wt"); + if (!QTest::stream) { +#endif + printf("Unable to open file for simple logging: %s", filename); + ::exit(1); + } } void QTestFileLogger::flush(const char *msg) |