summaryrefslogtreecommitdiffstats
path: root/src/testlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/testlib')
-rw-r--r--src/testlib/qplaintestlogger.cpp2
-rw-r--r--src/testlib/qtestcase.cpp200
-rw-r--r--src/testlib/qtestfilelogger.cpp25
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)