summaryrefslogtreecommitdiffstats
path: root/src/testlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/testlib')
-rw-r--r--src/testlib/3rdparty/cycle_p.h19
-rw-r--r--src/testlib/qabstracttestlogger.cpp50
-rw-r--r--src/testlib/qabstracttestlogger_p.h68
-rw-r--r--src/testlib/qbenchmark.cpp30
-rw-r--r--src/testlib/qbenchmark.h9
-rw-r--r--src/testlib/qbenchmark_p.h5
-rw-r--r--src/testlib/qbenchmarkvalgrind.cpp17
-rw-r--r--src/testlib/qplaintestlogger.cpp70
-rw-r--r--src/testlib/qsignaldumper.cpp10
-rw-r--r--src/testlib/qsignalspy.qdoc98
-rw-r--r--src/testlib/qtest.h38
-rw-r--r--src/testlib/qtest_global.h5
-rw-r--r--src/testlib/qtest_gui.h9
-rw-r--r--src/testlib/qtestbasicstreamer.cpp219
-rw-r--r--src/testlib/qtestbasicstreamer.h91
-rw-r--r--src/testlib/qtestcase.cpp448
-rw-r--r--src/testlib/qtestcase.h37
-rw-r--r--src/testlib/qtestcoreelement.h172
-rw-r--r--src/testlib/qtestcorelist.h136
-rw-r--r--src/testlib/qtestelement.cpp88
-rw-r--r--src/testlib/qtestelement.h75
-rw-r--r--src/testlib/qtestelementattribute.cpp177
-rw-r--r--src/testlib/qtestelementattribute.h111
-rw-r--r--src/testlib/qtestevent.h7
-rw-r--r--src/testlib/qtestevent.qdoc191
-rw-r--r--src/testlib/qtestfilelogger.cpp104
-rw-r--r--src/testlib/qtestfilelogger.h67
-rw-r--r--src/testlib/qtestkeyboard.h2
-rw-r--r--src/testlib/qtestlightxmlstreamer.cpp178
-rw-r--r--src/testlib/qtestlightxmlstreamer.h72
-rw-r--r--src/testlib/qtestlog.cpp44
-rw-r--r--src/testlib/qtestlog_p.h5
-rw-r--r--src/testlib/qtestlogger.cpp403
-rw-r--r--src/testlib/qtestlogger_p.h127
-rw-r--r--src/testlib/qtestmouse.h10
-rw-r--r--src/testlib/qtestresult.cpp2
-rw-r--r--src/testlib/qtestspontaneevent.h6
-rw-r--r--src/testlib/qtestsystem.h21
-rw-r--r--src/testlib/qtesttouch.h153
-rw-r--r--src/testlib/qtestxmlstreamer.cpp209
-rw-r--r--src/testlib/qtestxmlstreamer.h72
-rw-r--r--src/testlib/qtestxunitstreamer.cpp209
-rw-r--r--src/testlib/qtestxunitstreamer.h77
-rw-r--r--src/testlib/qxmltestlogger.cpp283
-rw-r--r--src/testlib/qxmltestlogger_p.h5
-rw-r--r--src/testlib/testlib.pro95
46 files changed, 4076 insertions, 248 deletions
diff --git a/src/testlib/3rdparty/cycle_p.h b/src/testlib/3rdparty/cycle_p.h
index b4b6876..a292423 100644
--- a/src/testlib/3rdparty/cycle_p.h
+++ b/src/testlib/3rdparty/cycle_p.h
@@ -190,6 +190,7 @@ INLINE_ELAPSED(__inline__)
#endif
/* Visual C++ -- thanks to Morten Nissov for his help with this */
+#if defined(_MSC_VER)
#if _MSC_VER >= 1200 && (_M_IX86 >= 500 || (defined(_WIN32_WCE) && defined(_X86_))) && !defined(HAVE_TICK_COUNTER)
#include <windows.h>
typedef LARGE_INTEGER CycleCounterTicks;
@@ -215,6 +216,7 @@ static __inline double elapsed(CycleCounterTicks t1, CycleCounterTicks t0)
#define HAVE_TICK_COUNTER
#define TIME_MIN 5000.0 /* unreliable pentium IV cycle counter */
#endif
+#endif
#if _MSC_VER >= 1400 && defined(_WIN32_WCE) && !defined(HAVE_TICK_COUNTER)
#include <windows.h>
@@ -491,4 +493,21 @@ INLINE_ELAPSED(inline)
#define HAVE_TICK_COUNTER
#endif
+/*----------------------------------------------------------------*/
+/* Symbian */
+#if defined(__SYMBIAN32__) && !defined(HAVE_TICK_COUNTER)
+#include <e32std.h>
+
+typedef TUint32 CycleCounterTicks;
+
+static inline CycleCounterTicks getticks(void)
+{
+ return User::FastCounter();
+}
+
+INLINE_ELAPSED(inline)
+
+#define HAVE_TICK_COUNTER
+#endif
+
#endif // QBENCHLIB_CYCLE_H
diff --git a/src/testlib/qabstracttestlogger.cpp b/src/testlib/qabstracttestlogger.cpp
index 84bda3c..f388fcc 100644
--- a/src/testlib/qabstracttestlogger.cpp
+++ b/src/testlib/qabstracttestlogger.cpp
@@ -43,8 +43,11 @@
#include "QtTest/private/qtestlog_p.h"
#include "QtTest/qtestassert.h"
+#include "QtCore/qbytearray.h"
+
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#ifndef Q_OS_WIN
#include <unistd.h>
@@ -77,6 +80,7 @@ bool QAbstractTestLogger::isTtyOutput()
#endif
}
+
void QAbstractTestLogger::startLogging()
{
QTEST_ASSERT(!QTest::stream);
@@ -105,4 +109,50 @@ void QAbstractTestLogger::stopLogging()
QTest::stream = 0;
}
+namespace QTest
+{
+
+extern void filter_unprintable(char *str);
+
+/*!
+ \fn int QTest::qt_asprintf(QTestCharBuffer *buf, const char *format, ...);
+ \internal
+ */
+int qt_asprintf(QTestCharBuffer *str, const char *format, ...)
+{
+ static const int MAXSIZE = 1024*1024*2;
+
+ Q_ASSERT(str);
+
+ int size = str->size();
+
+ va_list ap;
+ int res = 0;
+
+ for (;;) {
+ va_start(ap, format);
+ res = qvsnprintf(str->data(), size, format, ap);
+ va_end(ap);
+ str->data()[size - 1] = '\0';
+ if (res >= 0 && res < size) {
+ // We succeeded
+ break;
+ }
+ // buffer wasn't big enough, try again.
+ // Note, we're assuming that a result of -1 is always due to running out of space.
+ size *= 2;
+ if (size > MAXSIZE) {
+ break;
+ }
+ if (!str->reset(size))
+ break; // out of memory - take what we have
+ }
+
+ filter_unprintable(str->data());
+
+ return res;
+}
+
+}
+
QT_END_NAMESPACE
diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h
index 93b4b18..2340c58 100644
--- a/src/testlib/qabstracttestlogger_p.h
+++ b/src/testlib/qabstracttestlogger_p.h
@@ -99,6 +99,74 @@ public:
static bool isTtyOutput();
};
+struct QTestCharBuffer
+{
+ enum { InitialSize = 512 };
+
+ inline QTestCharBuffer()
+ : _size(InitialSize), buf(staticBuf)
+ {
+ staticBuf[0] = '\0';
+ }
+
+ inline ~QTestCharBuffer()
+ {
+ if (buf != staticBuf)
+ qFree(buf);
+ }
+
+ inline char *data()
+ {
+ return buf;
+ }
+
+ inline char **buffer()
+ {
+ return &buf;
+ }
+
+ inline const char* constData() const
+ {
+ return buf;
+ }
+
+ inline int size() const
+ {
+ return _size;
+ }
+
+ inline bool reset(int newSize)
+ {
+ char *newBuf = 0;
+ if (buf == staticBuf) {
+ // if we point to our internal buffer, we need to malloc first
+ newBuf = reinterpret_cast<char *>(qMalloc(newSize));
+ } else {
+ // if we already malloc'ed, just realloc
+ newBuf = reinterpret_cast<char *>(qRealloc(buf, newSize));
+ }
+
+ // if the allocation went wrong (newBuf == 0), we leave the object as is
+ if (!newBuf)
+ return false;
+
+ _size = newSize;
+ buf = newBuf;
+ return true;
+ }
+
+private:
+ int _size;
+ char* buf;
+ char staticBuf[InitialSize];
+};
+
+namespace QTest
+{
+ int qt_asprintf(QTestCharBuffer *buf, const char *format, ...);
+}
+
+
QT_END_NAMESPACE
#endif
diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp
index a4e4de3..3bd9054 100644
--- a/src/testlib/qbenchmark.cpp
+++ b/src/testlib/qbenchmark.cpp
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
@@ -117,7 +116,7 @@ int QBenchmarkGlobalData::adjustMedianIterationCount()
QBenchmarkTestMethodData *QBenchmarkTestMethodData::current;
QBenchmarkTestMethodData::QBenchmarkTestMethodData()
-:resultAccepted(false), iterationCount(-1)
+:resultAccepted(false), runOnce(false), iterationCount(-1)
{
}
@@ -158,6 +157,11 @@ void QBenchmarkTestMethodData::setResult(qint64 value)
if (QBenchmarkGlobalData::current->iterationCount != -1)
accepted = true;
+ if (QBenchmarkTestMethodData::current->runOnce) {
+ iterationCount = 1;
+ accepted = true;
+ }
+
// Test the result directly without calling the measurer if the minimum time
// has been specifed on the command line with -minimumvalue.
else if (QBenchmarkGlobalData::current->walltimeMinimum != -1)
@@ -175,16 +179,31 @@ void QBenchmarkTestMethodData::setResult(qint64 value)
QBenchmarkResult(QBenchmarkGlobalData::current->context, value, iterationCount);
}
-/*! \internal
+/*!
+ \class QTest::QBenchmarkIterationController
+ \internal
+
The QBenchmarkIterationController class is used by the QBENCHMARK macro to
drive the benchmarking loop. It is repsonsible for starting and stopping
the timing measurements as well as calling the result reporting functions.
*/
-QTest::QBenchmarkIterationController::QBenchmarkIterationController()
+
+/*! \internal
+*/
+QTest::QBenchmarkIterationController::QBenchmarkIterationController(RunMode runMode)
{
+ i = 0;
+ if (runMode == RunOnce)
+ QBenchmarkTestMethodData::current->runOnce = true;
QTest::beginBenchmarkMeasurement();
+}
+
+QTest::QBenchmarkIterationController::QBenchmarkIterationController()
+{
i = 0;
+ QTest::beginBenchmarkMeasurement();
}
+
/*! \internal
*/
QTest::QBenchmarkIterationController::~QBenchmarkIterationController()
@@ -196,6 +215,8 @@ QTest::QBenchmarkIterationController::~QBenchmarkIterationController()
*/
bool QTest::QBenchmarkIterationController::isDone()
{
+ if (QBenchmarkTestMethodData::current->runOnce)
+ return i > 0;
return i >= QTest::iterationCount();
}
@@ -219,6 +240,7 @@ void QTest::setIterationCountHint(int count)
{
QBenchmarkTestMethodData::current->adjustIterationCount(count);
}
+
/*! \internal
*/
void QTest::setIterationCount(int count)
diff --git a/src/testlib/qbenchmark.h b/src/testlib/qbenchmark.h
index 41bcd92..3fb1336 100644
--- a/src/testlib/qbenchmark.h
+++ b/src/testlib/qbenchmark.h
@@ -64,7 +64,9 @@ namespace QTest
class Q_TESTLIB_EXPORT QBenchmarkIterationController
{
public:
+ enum RunMode { RepeatUntilValidMeasurement, RunOnce };
QBenchmarkIterationController();
+ QBenchmarkIterationController(RunMode runMode);
~QBenchmarkIterationController();
bool isDone();
void next();
@@ -74,7 +76,12 @@ public:
}
#define QBENCHMARK \
- for (QTest::QBenchmarkIterationController __iteration_controller; __iteration_controller.isDone() == false; __iteration_controller.next())
+ for (QTest::QBenchmarkIterationController __iteration_controller; \
+ __iteration_controller.isDone() == false; __iteration_controller.next())
+
+#define QBENCHMARK_ONCE \
+ for (QTest::QBenchmarkIterationController __iteration_controller(QTest::QBenchmarkIterationController::RunOnce); \
+ __iteration_controller.isDone() == false; __iteration_controller.next())
QT_END_NAMESPACE
diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h
index a96a8af..2f0900b 100644
--- a/src/testlib/qbenchmark_p.h
+++ b/src/testlib/qbenchmark_p.h
@@ -55,7 +55,7 @@
#include <QtCore/qglobal.h>
-#if defined(Q_OS_LINUX) && !defined(QT_NO_PROCESS)
+#if (defined(Q_OS_LINUX) || defined Q_OS_MAC) && !defined(QT_NO_PROCESS)
#define QTESTLIB_USE_VALGRIND
#else
#undef QTESTLIB_USE_VALGRIND
@@ -81,7 +81,7 @@ struct QBenchmarkContext
QString toString() const
{
- QString s = QString(QLatin1String("%1,%2,%3")).arg(slotName).arg(tag).arg(checkpointIndex);
+ QString s = QString::fromLatin1("%1,%2,%3").arg(slotName).arg(tag).arg(checkpointIndex);
return s;
}
@@ -171,6 +171,7 @@ public:
QBenchmarkResult result;
bool resultAccepted;
+ bool runOnce;
int iterationCount;
};
diff --git a/src/testlib/qbenchmarkvalgrind.cpp b/src/testlib/qbenchmarkvalgrind.cpp
index 5c4a141..88cb37f 100644
--- a/src/testlib/qbenchmarkvalgrind.cpp
+++ b/src/testlib/qbenchmarkvalgrind.cpp
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
@@ -52,6 +51,8 @@
#include <QtCore/qset.h>
#include "3rdparty/callgrind_p.h"
+QT_BEGIN_NAMESPACE
+
// Returns true iff a sufficiently recent valgrind is available.
bool QBenchmarkValgrindUtils::haveValgrind()
{
@@ -113,7 +114,7 @@ qint64 QBenchmarkValgrindUtils::extractResult(const QString &fileName)
while (!file.atEnd()) {
const QString line(QLatin1String(file.readLine()));
if (rxValue.indexIn(line) != -1) {
- Q_ASSERT(rxValue.numCaptures() == 1);
+ Q_ASSERT(rxValue.captureCount() == 1);
bool ok;
val = rxValue.cap(1).toLongLong(&ok);
Q_ASSERT(ok);
@@ -132,12 +133,12 @@ QString QBenchmarkValgrindUtils::getNewestFileName()
QString base = QBenchmarkGlobalData::current->callgrindOutFileBase;
Q_ASSERT(!base.isEmpty());
- nameFilters << QString(QLatin1String("%1.*")).arg(base);
+ nameFilters << QString::fromLatin1("%1.*").arg(base);
QFileInfoList fiList = QDir().entryInfoList(nameFilters, QDir::Files | QDir::Readable);
Q_ASSERT(!fiList.empty());
int hiSuffix = -1;
QFileInfo lastFileInfo;
- const QString pattern = QString(QLatin1String("%1.(\\d+)")).arg(base);
+ const QString pattern = QString::fromLatin1("%1.(\\d+)").arg(base);
const QRegExp rx(pattern);
foreach (QFileInfo fileInfo, fiList) {
const int index = rx.indexIn(fileInfo.fileName());
@@ -167,8 +168,8 @@ void QBenchmarkValgrindUtils::cleanup()
QString base = QBenchmarkGlobalData::current->callgrindOutFileBase;
Q_ASSERT(!base.isEmpty());
nameFilters
- << QString(QLatin1String("%1")).arg(base) // overall summary
- << QString(QLatin1String("%1.*")).arg(base); // individual dumps
+ << base // overall summary
+ << QString::fromLatin1("%1.*").arg(base); // individual dumps
QFileInfoList fiList = QDir().entryInfoList(nameFilters, QDir::Files | QDir::Readable);
foreach (QFileInfo fileInfo, fiList) {
const bool removeOk = QFile::remove(fileInfo.fileName());
@@ -179,7 +180,7 @@ void QBenchmarkValgrindUtils::cleanup()
QString QBenchmarkValgrindUtils::outFileBase(qint64 pid)
{
- return QString(QLatin1String("callgrind.out.%1")).arg(
+ return QString::fromLatin1("callgrind.out.%1").arg(
pid != -1 ? pid : QCoreApplication::applicationPid());
}
@@ -272,4 +273,6 @@ QString QBenchmarkCallgrindMeasurer::metricText()
return QLatin1String("callgrind");
}
+QT_END_NAMESPACE
+
#endif // QTESTLIB_USE_VALGRIND
diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp
index b6b60ae..61c3728 100644
--- a/src/testlib/qplaintestlogger.cpp
+++ b/src/testlib/qplaintestlogger.cpp
@@ -54,6 +54,10 @@
#include "windows.h"
#endif
+#if defined(Q_OS_SYMBIAN)
+#include <e32debug.h>
+#endif
+
#ifdef Q_OS_WINCE
#include <QtCore/QString>
#endif
@@ -125,7 +129,11 @@ namespace QTest {
static const char *messageType2String(QAbstractTestLogger::MessageTypes type)
{
+#ifdef Q_OS_WIN
static bool colored = (!qgetenv("QTEST_COLORED").isEmpty());
+#else
+ static bool colored = ::getenv("QTEST_COLORED");
+#endif
switch (type) {
case QAbstractTestLogger::Skip:
return COLORED_MSG(0, 37, "SKIP "); //white
@@ -148,17 +156,39 @@ namespace QTest {
static void outputMessage(const char *str)
{
#if defined(Q_OS_WINCE)
- int length = strlen(str);
- for (int pos = 0; pos < length; pos +=255) {
- QString uniText = QString::fromLatin1(str + pos, 255);
- OutputDebugStringW((const LPCWSTR) uniText.utf16());
- }
+ QString strUtf16 = QString::fromLatin1(str);
+ const int maxOutputLength = 255;
+ do {
+ QString tmp = strUtf16.left(maxOutputLength);
+ OutputDebugString((wchar_t*)tmp.utf16());
+ strUtf16.remove(0, maxOutputLength);
+ } while (!strUtf16.isEmpty());
if (QTestLog::outputFileName())
#elif defined(Q_OS_WIN)
EnterCriticalSection(&outputCriticalSection);
// OutputDebugString is not threadsafe
OutputDebugStringA(str);
LeaveCriticalSection(&outputCriticalSection);
+#elif defined(Q_OS_SYMBIAN)
+ // RDebug::Print has a cap of 256 characters so break it up
+ TPtrC8 ptr(reinterpret_cast<const TUint8*>(str));
+ _LIT(format, "[QTestLib] %S");
+ const int maxBlockSize = 256 - ((const TDesC &)format).Length();
+ HBufC* hbuffer = HBufC::New(maxBlockSize);
+ if(hbuffer) {
+ for (int i = 0; i < ptr.Length(); i += maxBlockSize) {
+ int size = Min(maxBlockSize, ptr.Length() - i);
+ hbuffer->Des().Copy(ptr.Mid(i, size));
+ RDebug::Print(format, hbuffer);
+ }
+ }
+ else {
+ // fast, no allocations, but truncates silently
+ RDebug::RawPrint(format);
+ TPtrC8 ptr(reinterpret_cast<const TUint8*>(str));
+ RDebug::RawPrint(ptr);
+ RDebug::RawPrint(_L8("\n"));
+ }
#endif
QAbstractTestLogger::outputString(str);
}
@@ -168,7 +198,7 @@ namespace QTest {
QTEST_ASSERT(type);
QTEST_ASSERT(msg);
- char buf[1024];
+ QTestCharBuffer buf;
const char *fn = QTestResult::currentTestFunction() ? QTestResult::currentTestFunction()
: "UnknownTestFunc";
@@ -178,7 +208,7 @@ namespace QTest {
: "";
const char *filler = (tag[0] && gtag[0]) ? ":" : "";
if (file) {
- QTest::qt_snprintf(buf, sizeof(buf), "%s: %s::%s(%s%s%s)%s%s\n"
+ QTest::qt_asprintf(&buf, "%s: %s::%s(%s%s%s)%s%s\n"
#ifdef Q_OS_WIN
"%s(%d) : failure location\n"
#else
@@ -187,12 +217,14 @@ namespace QTest {
, type, QTestResult::currentTestObjectName(), fn, gtag, filler, tag,
msg[0] ? " " : "", msg, file, line);
} else {
- QTest::qt_snprintf(buf, sizeof(buf), "%s: %s::%s(%s%s%s)%s%s\n",
+ QTest::qt_asprintf(&buf, "%s: %s::%s(%s%s%s)%s%s\n",
type, QTestResult::currentTestObjectName(), fn, gtag, filler, tag,
msg[0] ? " " : "", msg);
}
- memcpy(buf, type, strlen(type));
- outputMessage(buf);
+ // In colored mode, printf above stripped our nonprintable control characters.
+ // Put them back.
+ memcpy(buf.data(), type, strlen(type));
+ outputMessage(buf.data());
}
template <typename T>
@@ -203,7 +235,7 @@ namespace QTest {
int digits = 0;
qreal divisor = 1;
-
+
while (num / divisor >= 1) {
divisor *= 10;
++digits;
@@ -216,17 +248,17 @@ namespace QTest {
template <typename T> QString formatResult(T number, int significantDigits)
{
if (number < T(0))
- return QString(QLatin1String("NAN"));
+ return QLatin1String("NAN");
if (number == T(0))
- return QString(QLatin1String("0"));
+ return QLatin1String("0");
QString beforeDecimalPoint = QString::number(qint64(number), 'f', 0);
QString afterDecimalPoint = QString::number(number, 'f', 20);
afterDecimalPoint.remove(0, beforeDecimalPoint.count() + 1);
-
+
int beforeUse = qMin(beforeDecimalPoint.count(), significantDigits);
int beforeRemove = beforeDecimalPoint.count() - beforeUse;
-
+
// Replace insignificant digits before the decimal point with zeros.
beforeDecimalPoint.chop(beforeRemove);
for (int i = 0; i < beforeRemove; ++i) {
@@ -264,10 +296,10 @@ namespace QTest {
print = beforeDecimalPoint;
if (afterUse > 0)
print.append(decimalPoint);
-
+
print += afterDecimalPoint;
-
+
return print;
}
@@ -288,7 +320,7 @@ namespace QTest {
char buf1[1024];
QTest::qt_snprintf(
buf1, sizeof(buf1), "%s: %s::%s",
- bmtag,
+ bmtag,
QTestResult::currentTestObjectName(),
result.context.slotName.toAscii().data());
@@ -299,7 +331,7 @@ namespace QTest {
if (tag.isEmpty() == false) {
QTest::qt_snprintf(bufTag, sizeof(bufTag), ":\"%s\"", tag.data());
}
-
+
char fillFormat[8];
int fillLength = 5;
diff --git a/src/testlib/qsignaldumper.cpp b/src/testlib/qsignaldumper.cpp
index 620b41c..bc4152b 100644
--- a/src/testlib/qsignaldumper.cpp
+++ b/src/testlib/qsignaldumper.cpp
@@ -87,7 +87,7 @@ static void qSignalDumperCallback(QObject *caller, int method_index, void **argv
str.fill(' ', QTest::iLevel++ * QTest::IndentSpacesCount);
str += "Signal: ";
str += mo->className();
- str += "(";
+ str += '(';
QString objname = caller->objectName();
str += objname.toLocal8Bit();
@@ -114,15 +114,15 @@ static void qSignalDumperCallback(QObject *caller, int method_index, void **argv
str.append(QByteArray::number(addr, 16));
} else if (typeId != QMetaType::Void) {
str.append(arg)
- .append("(")
+ .append('(')
.append(QVariant(typeId, argv[i + 1]).toString().toLocal8Bit())
- .append(")");
+ .append(')');
}
str.append(", ");
}
if (str.endsWith(", "))
str.chop(2);
- str.append(")");
+ str.append(')');
qPrintMessage(str);
}
@@ -143,7 +143,7 @@ static void qSignalDumperCallbackSlot(QObject *caller, int method_index, void **
str.fill(' ', QTest::iLevel * QTest::IndentSpacesCount);
str += "Slot: ";
str += mo->className();
- str += "(";
+ str += '(';
QString objname = caller->objectName();
str += objname.toLocal8Bit();
diff --git a/src/testlib/qsignalspy.qdoc b/src/testlib/qsignalspy.qdoc
new file mode 100644
index 0000000..8143ffd
--- /dev/null
+++ b/src/testlib/qsignalspy.qdoc
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QSignalSpy
+ \inmodule QtTest
+
+ \brief The QSignalSpy class enables introspection of signal emission.
+
+ QSignalSpy can connect to any signal of any object and records its emission.
+ QSignalSpy itself is a list of QVariant lists. Each emission of the signal
+ will append one item to the list, containing the arguments of the signal.
+
+ The following example records all signal emissions for the \c clicked() signal
+ of a QCheckBox:
+
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 0
+
+ \c{spy.takeFirst()} returns the arguments for the first emitted signal, as a
+ list of QVariant objects. The \c clicked() signal has a single bool argument,
+ which is stored as the first entry in the list of arguments.
+
+ The example below catches a signal from a custom object:
+
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 1
+
+ \bold {Note:} Non-standard data types need to be registered, using
+ the qRegisterMetaType() function, before you can create a
+ QSignalSpy. For example:
+
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 2
+
+ To retrieve the \c QModelIndex, you can use qvariant_cast:
+
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 3
+ */
+
+/*! \fn QSignalSpy::QSignalSpy(QObject *object, const char *signal)
+
+ Constructs a new QSignalSpy that listens for emissions of the \a signal
+ from the QObject \a object. Neither \a signal nor \a object can be null.
+
+ Example:
+ \snippet doc/src/snippets/code/doc_src_qsignalspy.qdoc 4
+*/
+
+/*! \fn QSignalSpy::isValid() const
+
+ Returns true if the signal spy listens to a valid signal, otherwise false.
+*/
+
+/*! \fn QSignalSpy::signal() const
+
+ Returns the normalized signal the spy is currently listening to.
+*/
+
+/*! \fn int QSignalSpy::qt_metacall(QMetaObject::Call call, int id, void **a)
+ \internal
+*/
+
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index 52f0f57..f2d865b 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -53,6 +53,7 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qobject.h>
+#include <QtCore/qvariant.h>
#include <QtCore/qurl.h>
#include <QtCore/qpoint.h>
@@ -87,14 +88,14 @@ template<> inline char *toString(const QByteArray &ba)
template<> inline char *toString(const QTime &time)
{
return time.isValid()
- ? qstrdup(time.toString(QLatin1String("hh:mm:ss.zzz")).toLatin1())
+ ? qstrdup(time.toString(QLatin1String("hh:mm:ss.zzz")).toLatin1().constData())
: qstrdup("Invalid QTime");
}
template<> inline char *toString(const QDate &date)
{
return date.isValid()
- ? qstrdup(date.toString(QLatin1String("yyyy/MM/dd")).toLatin1())
+ ? qstrdup(date.toString(QLatin1String("yyyy/MM/dd")).toLatin1().constData())
: qstrdup("Invalid QDate");
}
@@ -102,7 +103,7 @@ template<> inline char *toString(const QDateTime &dateTime)
{
return dateTime.isValid()
? qstrdup((dateTime.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz")) +
- (dateTime.timeSpec() == Qt::LocalTime ? QLatin1String("[local time]") : QLatin1String("[UTC]"))).toLatin1())
+ (dateTime.timeSpec() == Qt::LocalTime ? QLatin1String("[local time]") : QLatin1String("[UTC]"))).toLatin1().constData())
: qstrdup("Invalid QDateTime");
}
@@ -146,6 +147,30 @@ template<> inline char *toString(const QUrl &uri)
return qstrdup(uri.toEncoded().constData());
}
+template<> inline char *toString(const QVariant &v)
+{
+ QByteArray vstring("QVariant(");
+ if (v.isValid()) {
+ QByteArray type(v.typeName());
+ if (type.isEmpty()) {
+ type = QByteArray::number(v.userType());
+ }
+ vstring.append(type);
+ if (!v.isNull()) {
+ vstring.append(',');
+ if (v.canConvert(QVariant::String)) {
+ vstring.append(qVariantValue<QString>(v).toLatin1());
+ }
+ else {
+ vstring.append("<value not representable as string>");
+ }
+ }
+ }
+ vstring.append(')');
+
+ return qstrdup(vstring.constData());
+}
+
#ifndef QTEST_NO_SPECIALIZATIONS
template<>
#endif
@@ -226,10 +251,17 @@ int main(int argc, char *argv[]) \
#include <QtTest/qtest_gui.h>
+#ifdef QT_KEYPAD_NAVIGATION
+# define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone);
+#else
+# define QTEST_DISABLE_KEYPAD_NAVIGATION
+#endif
+
#define QTEST_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
QApplication app(argc, argv); \
+ QTEST_DISABLE_KEYPAD_NAVIGATION \
TestObject tc; \
return QTest::qExec(&tc, argc, argv); \
}
diff --git a/src/testlib/qtest_global.h b/src/testlib/qtest_global.h
index b020467..e78d6e1 100644
--- a/src/testlib/qtest_global.h
+++ b/src/testlib/qtest_global.h
@@ -52,7 +52,7 @@ QT_MODULE(Test)
#ifdef QTEST_EMBED
# define Q_TESTLIB_EXPORT
-#elif !defined(QT_SHARED)
+#elif !defined(QT_SHARED) && !(defined(Q_OS_SYMBIAN) && defined(Q_CC_RVCT))
# define Q_TESTLIB_EXPORT
#else
# ifdef QTESTLIB_MAKEDLL
@@ -62,10 +62,11 @@ QT_MODULE(Test)
# endif
#endif
-#if (defined (Q_CC_MSVC) && _MSC_VER < 1310) || defined (Q_CC_SUN) || defined (Q_CC_XLC) || (defined (Q_CC_GNU) && (__GNUC__ - 0 < 3))
+#if (defined (Q_CC_MSVC) && _MSC_VER < 1310) || defined (Q_CC_SUN) || defined (Q_CC_XLC) || (defined (Q_CC_GNU) && (__GNUC__ - 0 < 3)) || defined (Q_CC_NOKIAX86)
# define QTEST_NO_SPECIALIZATIONS
#endif
+
#if (defined Q_CC_HPACC) && (defined __ia64)
# ifdef Q_TESTLIB_EXPORT
# undef Q_TESTLIB_EXPORT
diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h
index 7d99485..13063a8 100644
--- a/src/testlib/qtest_gui.h
+++ b/src/testlib/qtest_gui.h
@@ -42,10 +42,19 @@
#ifndef QTEST_GUI_H
#define QTEST_GUI_H
+// enable GUI features
+#ifndef QT_GUI_LIB
+#define QT_GUI_LIB
+#endif
+#if 0
+#pragma qt_class(QtTestGui)
+#endif
+
#include <QtTest/qtestassert.h>
#include <QtTest/qtest.h>
#include <QtTest/qtestevent.h>
#include <QtTest/qtestmouse.h>
+#include <QtTest/qtesttouch.h>
#include <QtTest/qtestkeyboard.h>
#include <QtGui/qicon.h>
diff --git a/src/testlib/qtestbasicstreamer.cpp b/src/testlib/qtestbasicstreamer.cpp
new file mode 100644
index 0000000..dd47ddf
--- /dev/null
+++ b/src/testlib/qtestbasicstreamer.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestbasicstreamer.h"
+#include "qtestlogger_p.h"
+#include "qtestelement.h"
+#include "qtestelementattribute.h"
+#include "QtTest/private/qtestlog_p.h"
+#include "qtestassert.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef Q_OS_WIN
+#include <unistd.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace QTest
+{
+ static FILE *stream = 0;
+}
+
+QTestBasicStreamer::QTestBasicStreamer()
+ :testLogger(0)
+{
+}
+
+QTestBasicStreamer::~QTestBasicStreamer()
+{}
+
+void QTestBasicStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted )
+ return;
+ formatted->data()[0] = '\0';
+}
+
+void QTestBasicStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted )
+ return;
+ formatted->data()[0] = '\0';
+}
+
+void QTestBasicStreamer::formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted )
+ return;
+ formatted->data()[0] = '\0';
+}
+
+void QTestBasicStreamer::formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted )
+ return;
+ formatted->data()[0] = '\0';
+}
+
+void QTestBasicStreamer::formatAttributes(const QTestElement *, const QTestElementAttribute *attribute, QTestCharBuffer *formatted) const
+{
+ if(!attribute || !formatted )
+ return;
+ formatted->data()[0] = '\0';
+}
+
+void QTestBasicStreamer::output(QTestElement *element) const
+{
+ if(!element)
+ return;
+
+ outputElements(element);
+}
+
+void QTestBasicStreamer::outputElements(QTestElement *element, bool) const
+{
+ QTestCharBuffer buf;
+ bool hasChildren;
+ /*
+ Elements are in reverse order of occurrence, so start from the end and work
+ our way backwards.
+ */
+ while (element && element->nextElement()) {
+ element = element->nextElement();
+ }
+ while (element) {
+ hasChildren = element->childElements();
+
+ formatStart(element, &buf);
+ outputString(buf.data());
+
+ formatBeforeAttributes(element, &buf);
+ outputString(buf.data());
+
+ outputElementAttributes(element, element->attributes());
+
+ formatAfterAttributes(element, &buf);
+ outputString(buf.data());
+
+ if(hasChildren)
+ outputElements(element->childElements(), true);
+
+ formatEnd(element, &buf);
+ outputString(buf.data());
+
+ element = element->previousElement();
+ }
+}
+
+void QTestBasicStreamer::outputElementAttributes(const QTestElement* element, QTestElementAttribute *attribute) const
+{
+ QTestCharBuffer buf;
+ while(attribute){
+ formatAttributes(element, attribute, &buf);
+ outputString(buf.data());
+ attribute = attribute->nextElement();
+ }
+}
+
+void QTestBasicStreamer::outputString(const char *msg) const
+{
+ QTEST_ASSERT(QTest::stream);
+
+ ::fputs(msg, QTest::stream);
+ ::fflush(QTest::stream);
+}
+
+void QTestBasicStreamer::startStreaming()
+{
+ QTEST_ASSERT(!QTest::stream);
+
+ const char *out = QTestLog::outputFileName();
+ if (!out) {
+ QTest::stream = stdout;
+ return;
+ }
+ #if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_OS_WINCE)
+ if (::fopen_s(&QTest::stream, out, "wt")) {
+ #else
+ QTest::stream = ::fopen(out, "wt");
+ if (!QTest::stream) {
+ #endif
+ printf("Unable to open file for logging: %s", out);
+ ::exit(1);
+ }
+}
+
+bool QTestBasicStreamer::isTtyOutput()
+{
+ QTEST_ASSERT(QTest::stream);
+
+#if defined(Q_OS_WIN) || defined(Q_OS_INTEGRITY)
+ return true;
+#else
+ static bool ttyoutput = isatty(fileno(QTest::stream));
+ return ttyoutput;
+#endif
+}
+
+void QTestBasicStreamer::stopStreaming()
+{
+ QTEST_ASSERT(QTest::stream);
+ if (QTest::stream != stdout)
+ fclose(QTest::stream);
+
+ QTest::stream = 0;
+}
+
+void QTestBasicStreamer::setLogger(const QTestLogger *tstLogger)
+{
+ testLogger = tstLogger;
+}
+
+const QTestLogger *QTestBasicStreamer::logger() const
+{
+ return testLogger;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtestbasicstreamer.h b/src/testlib/qtestbasicstreamer.h
new file mode 100644
index 0000000..f8311b0
--- /dev/null
+++ b/src/testlib/qtestbasicstreamer.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTBASICSTREAMER_H
+#define QTESTBASICSTREAMER_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+class QTestElement;
+class QTestElementAttribute;
+class QTestLogger;
+struct QTestCharBuffer;
+
+class QTestBasicStreamer
+{
+ public:
+ QTestBasicStreamer();
+ virtual ~QTestBasicStreamer();
+
+ virtual void output(QTestElement *element) const;
+
+ void outputString(const char *msg) const;
+ bool isTtyOutput();
+ void startStreaming();
+ void stopStreaming();
+
+ void setLogger(const QTestLogger *tstLogger);
+ const QTestLogger *logger() const;
+
+ protected:
+ virtual void formatStart(const QTestElement *element, QTestCharBuffer *formatted) const;
+ virtual void formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const;
+ virtual void formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const;
+ virtual void formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const;
+ virtual void formatAttributes(const QTestElement *element, const QTestElementAttribute *attribute, QTestCharBuffer *formatted) const;
+ virtual void outputElements(QTestElement *element, bool isChildElement = false) const;
+ virtual void outputElementAttributes(const QTestElement *element, QTestElementAttribute *attribute) const;
+
+ private:
+ const QTestLogger *testLogger;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 0c63ffa..9dea6dc 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -54,6 +54,7 @@
#include <QtCore/qdir.h>
#include <QtCore/qprocess.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qlibraryinfo.h>
#include "QtTest/private/qtestlog_p.h"
#include "QtTest/private/qtesttable_p.h"
@@ -71,6 +72,8 @@
#include <windows.h> // for Sleep
#endif
#ifdef Q_OS_UNIX
+#include <errno.h>
+#include <signal.h>
#include <time.h>
#endif
@@ -300,10 +303,15 @@ QT_BEGIN_NAMESPACE
the \a TestClass, and executes all tests in the order they were defined.
Use this macro to build stand-alone executables.
+ \bold {Note:} On platforms that have keypad navigation enabled by default (eg: Symbian),
+ this macro will forcfully disable it to simplify the usage of key events when writing
+ autotests. If you wish to write a test case that uses keypad navigation, you should
+ enable it either in the \c {initTestCase()} or \c {init()} functions of your test case.
+
Example:
\snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 11
- \sa QTEST_APPLESS_MAIN(), QTest::qExec()
+ \sa QTEST_APPLESS_MAIN(), QTest::qExec(), QApplication::setNavigationMode()
*/
/*! \macro QTEST_APPLESS_MAIN(TestClass)
@@ -348,6 +356,29 @@ QT_BEGIN_NAMESPACE
{Chapter 5: Writing a Benchmark}{Writing a Benchmark}
*/
+/*!
+ \macro QBENCHMARK_ONCE
+ \since 4.6
+
+ \relates QTest
+
+ \brief The QBENCHMARK_ONCE macro is for measuring performance of a
+ code block by running it once.
+
+ This macro is used to measure the performance of code within a test.
+ The code to be benchmarked is contained within a code block following
+ this macro.
+
+ Unlike QBENCHMARK, the contents of the contained code block is only run
+ once. The elapsed time will be reported as "0" if it's to short to
+ be measured by the selected backend. (Use)
+
+ \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark},
+ {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
+*/
+
+
+
/*! \enum QTest::SkipMode
This enum describes the modes for skipping tests during execution
@@ -400,7 +431,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
@@ -413,7 +445,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
@@ -428,20 +461,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().
@@ -452,7 +490,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().
@@ -461,7 +500,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()
*/
@@ -470,7 +510,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()
*/
@@ -672,6 +713,13 @@ QT_BEGIN_NAMESPACE
Returns a textual representation of the given \a rectangle.
*/
+/*!
+ \fn char *QTest::toString(const QVariant &variant)
+ \overload
+
+ Returns a textual representation of the given \a variant.
+*/
+
/*! \fn void QTest::qWait(int ms)
Waits for \a ms milliseconds. While waiting, events will be processed and
@@ -686,16 +734,105 @@ QT_BEGIN_NAMESPACE
\sa QTest::qSleep()
*/
+/*! \fn bool QTest::qWaitForWindowShown(QWidget *window)
+ \since 4.6
+
+ Waits until the \a window is shown in the screen. This is mainly useful for
+ asynchronous systems like X11, where a window will be mapped to screen some
+ time after being asked to show itself on the screen. Returns true.
+
+ Example:
+ \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 24
+*/
+
+/*!
+ \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;
- struct TestFunction {
+ static struct TestFunction {
TestFunction():function(0), data(0) {}
~TestFunction() { delete [] data; }
int function;
char *data;
- } testFuncs[512];
+ } *testFuncs;
/**
* Contains the count of test functions that was supplied
@@ -710,6 +847,16 @@ namespace QTest
static int eventDelay = -1;
static int keyVerbose = -1;
+void filter_unprintable(char *str)
+{
+ char *idx = str;
+ while (*idx) {
+ if (((*idx < 0x20 && *idx != '\n' && *idx != '\t') || *idx > 0x7e))
+ *idx = '?';
+ ++idx;
+ }
+}
+
/*! \internal
*/
int qt_snprintf(char *str, int size, const char *format, ...)
@@ -722,12 +869,8 @@ int qt_snprintf(char *str, int size, const char *format, ...)
va_end(ap);
str[size - 1] = '\0';
- char *idx = str;
- while (*idx) {
- if (((*idx < 0x20 && *idx != '\n' && *idx != '\t') || *idx > 0x7e))
- *idx = '?';
- ++idx;
- }
+ filter_unprintable(str);
+
return res;
}
@@ -818,8 +961,10 @@ static void qParseArgs(int argc, char *argv[])
const char *testOptions =
" options:\n"
" -functions : Returns a list of current testfunctions\n"
+ " -xunitxml : Outputs results as XML XUnit document\n"
" -xml : Outputs results as XML document\n"
" -lightxml : Outputs results as stream of XML tags\n"
+ " -flush : Flushes the resutls\n"
" -o filename: Writes all output into a file\n"
" -silent : Only outputs warnings and failures\n"
" -v1 : Print enter messages for each testfunction\n"
@@ -844,9 +989,8 @@ 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"
-#ifndef QT_NO_PROCESS
-// Will be enabled when tools are integrated.
-// " -chart : Runs the chart generator after the test. No output is printed to the console\n"
+#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS)
+ " -chart : Create chart based on the benchmark result.\n"
#endif
"\n"
" -help : This help\n";
@@ -861,10 +1005,14 @@ static void qParseArgs(int argc, char *argv[])
} else if (strcmp(argv[i], "-functions") == 0) {
qPrintTestSlots();
exit(0);
+ } else if(strcmp(argv[i], "-xunitxml") == 0){
+ QTestLog::setLogMode(QTestLog::XunitXML);
} else if (strcmp(argv[i], "-xml") == 0) {
QTestLog::setLogMode(QTestLog::XML);
} else if (strcmp(argv[i], "-lightxml") == 0) {
QTestLog::setLogMode(QTestLog::LightXML);
+ }else if(strcmp(argv[i], "-flush") == 0){
+ QTestLog::setFlushMode(QTestLog::FLushOn);
} else if (strcmp(argv[i], "-silent") == 0) {
QTestLog::setVerboseLevel(-1);
} else if (strcmp(argv[i], "-v1") == 0) {
@@ -957,7 +1105,7 @@ static void qParseArgs(int argc, char *argv[])
} else if (strcmp(argv[i], "-vb") == 0) {
QBenchmarkGlobalData::current->verboseOutput = true;
-#ifndef QT_NO_PROCESS
+#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS)
} else if (strcmp(argv[i], "-chart") == 0) {
QBenchmarkGlobalData::current->createChart = true;
QTestLog::setLogMode(QTestLog::XML);
@@ -991,6 +1139,11 @@ static void qParseArgs(int argc, char *argv[])
exit(1);
}
++QTest::lastTestFuncIdx;
+ if (!QTest::testFuncs) {
+ struct Cleanup { ~Cleanup() { delete[] QTest::testFuncs; } };
+ static Cleanup cleanup;
+ QTest::testFuncs = new TestFunction[512];
+ }
QTest::testFuncs[QTest::lastTestFuncIdx].function = idx;
QTest::testFuncs[QTest::lastTestFuncIdx].data = data;
QTEST_ASSERT(QTest::lastTestFuncIdx < 512);
@@ -1006,7 +1159,7 @@ QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
if (count == 1)
return container.at(0);
-
+
QList<QBenchmarkResult> containerCopy = container;
qSort(containerCopy);
@@ -1056,7 +1209,7 @@ static void qInvokeTestMethodDataEntry(char *slot)
QTestResult::currentDataTag()
? QTestResult::currentDataTag() : "");
- invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot,
+ invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot,
Qt::DirectConnection);
if (!invokeOk)
QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);
@@ -1077,7 +1230,7 @@ static void qInvokeTestMethodDataEntry(char *slot)
if (i > -1) // iteration -1 is the warmup iteration.
results.append(QBenchmarkTestMethodData::current->result);
- if (QBenchmarkTestMethodData::current->isBenchmark() &&
+ if (QBenchmarkTestMethodData::current->isBenchmark() &&
QBenchmarkGlobalData::current->verboseOutput) {
if (i == -1) {
qDebug() << "warmup stage result :" << QBenchmarkTestMethodData::current->result.value;
@@ -1208,13 +1361,13 @@ void *fetchData(QTestData *data, const char *tagName, int typeId)
/*!
\fn char* QTest::toHexRepresentation(const char *ba, int length)
-
+
Returns a pointer to a string that is the string \a ba represented
as a space-separated sequence of hex characters. If the input is
considered too long, it is truncated. A trucation is indicated in
the returned string as an ellipsis at the end.
- \a length is the length of the string \a ba.
+ \a length is the length of the string \a ba.
*/
char *toHexRepresentation(const char *ba, int length)
{
@@ -1273,56 +1426,134 @@ char *toHexRepresentation(const char *ba, int length)
return result;
}
-static void qInvokeTestMethods(QObject *testObject)
-{
- const QMetaObject *metaObject = testObject->metaObject();
- QTEST_ASSERT(metaObject);
-
- QTestLog::startLogging();
-
- QTestResult::setCurrentTestFunction("initTestCase");
- QTestResult::setCurrentTestLocation(QTestResult::DataFunc);
- QTestTable::globalTestTable();
- QMetaObject::invokeMethod(testObject, "initTestCase_data", Qt::DirectConnection);
-
- if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {
- QTestResult::setCurrentTestLocation(QTestResult::InitFunc);
- QMetaObject::invokeMethod(testObject, "initTestCase");
-
- // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy.
- const bool previousFailed = QTestResult::testFailed();
- QTestResult::finishedCurrentTestFunction();
-
- if(!QTestResult::skipCurrentTest() && !previousFailed) {
-
- if (lastTestFuncIdx >= 0) {
- for (int i = 0; i <= lastTestFuncIdx; ++i) {
- if (!qInvokeTestMethod(metaObject->method(testFuncs[i].function).signature(),
- testFuncs[i].data))
- break;
- }
- } else {
- int methodCount = metaObject->methodCount();
- for (int i = 0; i < methodCount; ++i) {
- QMetaMethod slotMethod = metaObject->method(i);
- if (!isValidSlot(slotMethod))
- continue;
- if (!qInvokeTestMethod(slotMethod.signature()))
- break;
- }
- }
- }
-
- QTestResult::setSkipCurrentTest(false);
- QTestResult::setCurrentTestFunction("cleanupTestCase");
- QMetaObject::invokeMethod(testObject, "cleanupTestCase");
- }
- QTestResult::finishedCurrentTestFunction();
- QTestResult::setCurrentTestFunction(0);
- QTestTable::clearGlobalTestTable();
-
- QTestLog::stopLogging();
-}
+static void qInvokeTestMethods(QObject *testObject)
+{
+ const QMetaObject *metaObject = testObject->metaObject();
+ QTEST_ASSERT(metaObject);
+
+ QTestLog::startLogging();
+
+ QTestResult::setCurrentTestFunction("initTestCase");
+ QTestResult::setCurrentTestLocation(QTestResult::DataFunc);
+ QTestTable::globalTestTable();
+ QMetaObject::invokeMethod(testObject, "initTestCase_data", Qt::DirectConnection);
+
+ if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {
+ QTestResult::setCurrentTestLocation(QTestResult::InitFunc);
+ QMetaObject::invokeMethod(testObject, "initTestCase");
+
+ // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy.
+ const bool previousFailed = QTestResult::testFailed();
+ QTestResult::finishedCurrentTestFunction();
+
+ if(!QTestResult::skipCurrentTest() && !previousFailed) {
+
+ if (lastTestFuncIdx >= 0) {
+ for (int i = 0; i <= lastTestFuncIdx; ++i) {
+ if (!qInvokeTestMethod(metaObject->method(testFuncs[i].function).signature(),
+ testFuncs[i].data))
+ break;
+ }
+ } else {
+ int methodCount = metaObject->methodCount();
+ for (int i = 0; i < methodCount; ++i) {
+ QMetaMethod slotMethod = metaObject->method(i);
+ if (!isValidSlot(slotMethod))
+ continue;
+ if (!qInvokeTestMethod(slotMethod.signature()))
+ break;
+ }
+ }
+ }
+
+ QTestResult::setSkipCurrentTest(false);
+ QTestResult::setCurrentTestFunction("cleanupTestCase");
+ QMetaObject::invokeMethod(testObject, "cleanupTestCase");
+ }
+ QTestResult::finishedCurrentTestFunction();
+ QTestResult::setCurrentTestFunction(0);
+ QTestTable::clearGlobalTestTable();
+
+ QTestLog::stopLogging();
+}
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+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);
+#ifndef Q_WS_QWS
+ // Don't overwrite any non-default handlers
+ // however, we need to replace the default QWS handlers
+ if (oldact.sa_flags & SA_SIGINFO || oldact.sa_handler != SIG_DFL) {
+ sigaction(fatalSignals[i], &oldact, 0);
+ } else
+#endif
+ {
+ 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
@@ -1399,6 +1630,14 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
}
#endif
+#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
+ // Delay execution of tests in Symbian emulator.
+ // Needed to allow worst of other higher priority apps and services launched by emulator
+ // to get out of the way before we run our test. Otherwise some of the timing sensitive tests
+ // will not work properly.
+ qSleep(3000);
+#endif
+
QTestResult::reset();
QTEST_ASSERT(testObject);
@@ -1418,16 +1657,16 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
QBenchmarkValgrindUtils::cleanup();
- } else {
+ } else
+#endif
+ {
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+ FatalSignalHandler handler;
#endif
-
qInvokeTestMethods(testObject);
-
-#ifdef QTESTLIB_USE_VALGRIND
}
-#endif
- #ifndef QT_NO_EXCEPTIONS
+#ifndef QT_NO_EXCEPTIONS
} catch (...) {
QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__);
if (QTestResult::currentTestFunction()) {
@@ -1441,13 +1680,11 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
IOPMAssertionRelease(powerID);
}
#endif
- #ifdef Q_OS_WIN
- // rethrow exception to make debugging easier
+ // Rethrow exception to make debugging easier.
throw;
- #endif
- return -1;
+ return 1;
}
- #endif
+# endif
currentTestObject = 0;
#ifdef QT_MAC_USE_COCOA
@@ -1457,26 +1694,21 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
#endif
-#ifndef QT_NO_PROCESS
+#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS)
if (QBenchmarkGlobalData::current->createChart) {
-
-#define XSTR(s) STR(s)
-#define STR(s) #s
+ QString chartLocation = QLibraryInfo::location(QLibraryInfo::BinariesPath);
#ifdef Q_OS_WIN
- const char * path = XSTR(QBENCHLIB_BASE) "/tools/generatereport/generatereport.exe";
+ chartLocation += QLatin1String("/../tools/qtestlib/chart/release/chart.exe");
#else
- const char * path = XSTR(QBENCHLIB_BASE) "/tools/generatereport/generatereport";
+ chartLocation += QLatin1String("/../tools/qtestlib/chart/chart");
#endif
-#undef XSTR
-#undef STR
-
- if (QFile::exists(QLatin1String(path))) {
+ if (QFile::exists(chartLocation)) {
QProcess p;
p.setProcessChannelMode(QProcess::ForwardedChannels);
- p.start(QLatin1String(path), QStringList() << QLatin1String("results.xml"));
+ p.start(chartLocation, QStringList() << QLatin1String("results.xml"));
p.waitForFinished(-1);
} else {
- qWarning("Could not find %s, please make sure it is compiled.", path);
+ qDebug() << QLatin1String("Could not find the chart tool in ") + chartLocation + QLatin1String(", please make sure it is compiled.");
}
}
#endif
@@ -1755,7 +1987,7 @@ bool QTest::compare_helper(bool success, const char *msg, char *val1, char *val2
\internal
*/
template <>
-bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected,
+Q_TESTLIB_EXPORT bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected,
const char *file, int line)
{
return qFuzzyCompare(t1, t2)
@@ -1768,7 +2000,7 @@ bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual
\internal
*/
template <>
-bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected,
+Q_TESTLIB_EXPORT bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected,
const char *file, int line)
{
return qFuzzyCompare(t1, t2)
@@ -1778,7 +2010,7 @@ bool QTest::qCompare<double>(double const &t1, double const &t2, const char *act
}
#define COMPARE_IMPL2(TYPE, FORMAT) \
-template <> char *QTest::toString<TYPE >(const TYPE &t) \
+template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE >(const TYPE &t) \
{ \
char *msg = new char[128]; \
qt_snprintf(msg, 128, #FORMAT, t); \
@@ -1800,8 +2032,8 @@ COMPARE_IMPL2(quint64, %llu)
#endif
COMPARE_IMPL2(bool, %d)
COMPARE_IMPL2(char, %c)
-COMPARE_IMPL2(float, %g);
-COMPARE_IMPL2(double, %lg);
+COMPARE_IMPL2(float, %g)
+COMPARE_IMPL2(double, %lg)
/*! \internal
*/
@@ -1910,6 +2142,10 @@ bool QTest::compare_string_helper(const char *t1, const char *t2, const char *ac
\internal
*/
+/*! \fn bool QTest::qCompare(bool const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
+ \internal
+ */
+
/*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line)
\internal
*/
@@ -1926,8 +2162,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/qtestcase.h b/src/testlib/qtestcase.h
index 4f11f66..1831728 100644
--- a/src/testlib/qtestcase.h
+++ b/src/testlib/qtestcase.h
@@ -125,6 +125,7 @@ namespace QTest
return 0;
}
+
Q_TESTLIB_EXPORT char *toHexRepresentation(const char *ba, int length);
Q_TESTLIB_EXPORT char *toString(const char *);
Q_TESTLIB_EXPORT char *toString(const void *);
@@ -178,6 +179,7 @@ namespace QTest
toString<T>(t1), toString<T>(t2), actual, expected, file, line);
}
+
template <>
Q_TESTLIB_EXPORT bool qCompare<float>(float const &t1, float const &t2,
const char *actual, const char *expected, const char *file, int line);
@@ -233,7 +235,7 @@ namespace QTest
return qCompare<qreal>(qreal(t1), t2, actual, expected, file, line);
}
-#elif defined(QT_COORD_TYPE) || defined(QT_ARCH_ARM) || defined(QT_NO_FPU) || defined(QT_ARCH_WINDOWSCE)
+#elif defined(QT_COORD_TYPE) || defined(QT_ARCH_ARM) || defined(QT_NO_FPU) || defined(QT_ARCH_WINDOWSCE) || defined(QT_ARCH_SYMBIAN)
template <>
inline bool qCompare<qreal, double>(qreal const &t1, double const &t2, const char *actual,
const char *expected, const char *file, int line)
@@ -289,6 +291,28 @@ namespace QTest
return compare_string_helper(t1, t2, actual, expected, file, line);
}
#else /* QTEST_NO_SPECIALIZATIONS */
+
+// In Symbian we have QTEST_NO_SPECIALIZATIONS defined, but still float related specialization
+// should be used. If QTEST_NO_SPECIALIZATIONS is enabled we get ambiguous overload errors.
+#if defined(QT_ARCH_SYMBIAN)
+ template <typename T1, typename T2>
+ bool qCompare(T1 const &, T2 const &, const char *, const char *, const char *, int);
+
+ template <>
+ inline bool qCompare<qreal, double>(qreal const &t1, double const &t2, const char *actual,
+ const char *expected, const char *file, int line)
+ {
+ return qCompare<float>(float(t1), float(t2), actual, expected, file, line);
+ }
+
+ template <>
+ inline bool qCompare<double, qreal>(double const &t1, qreal const &t2, const char *actual,
+ const char *expected, const char *file, int line)
+ {
+ return qCompare<float>(float(t1), float(t2), actual, expected, file, line);
+ }
+#endif
+
inline bool qCompare(const char *t1, const char *t2, const char *actual,
const char *expected, const char *file, int line)
{
@@ -322,6 +346,17 @@ namespace QTest
return compare_string_helper(t1, t2, actual, expected, file, line);
}
+ // NokiaX86 and RVCT do not like implicitly comparing bool with int
+#ifndef QTEST_NO_SPECIALIZATIONS
+ template <>
+#endif
+ inline bool qCompare(bool const &t1, int const &t2,
+ const char *actual, const char *expected, const char *file, int line)
+ {
+ return qCompare<int>(int(t1), t2, actual, expected, file, line);
+ }
+
+
template <class T>
inline bool qTest(const T& actual, const char *elementName, const char *actualStr,
const char *expected, const char *file, int line)
diff --git a/src/testlib/qtestcoreelement.h b/src/testlib/qtestcoreelement.h
new file mode 100644
index 0000000..b5e5d0f
--- /dev/null
+++ b/src/testlib/qtestcoreelement.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTCOREELEMENT_H
+#define QTESTCOREELEMENT_H
+
+#include <QtTest/qtestcorelist.h>
+#include <QtTest/qtestelementattribute.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+template <class ElementType>
+class QTestCoreElement: public QTestCoreList<ElementType>
+{
+ public:
+ QTestCoreElement( int type = -1 );
+ virtual ~QTestCoreElement();
+
+ void addAttribute(const QTest::AttributeIndex index, const char *value);
+ QTestElementAttribute *attributes() const;
+ const char *attributeValue(QTest::AttributeIndex index) const;
+ const char *attributeName(QTest::AttributeIndex index) const;
+ const QTestElementAttribute *attribute(QTest::AttributeIndex index) const;
+
+ const char *elementName() const;
+ QTest::LogElementType elementType() const;
+
+ private:
+ QTestElementAttribute *listOfAttributes;
+ QTest::LogElementType type;
+};
+
+template<class ElementType>
+QTestCoreElement<ElementType>::QTestCoreElement(int t)
+ :listOfAttributes(0), type(QTest::LogElementType(t))
+{
+}
+
+template<class ElementType>
+QTestCoreElement<ElementType>::~QTestCoreElement()
+{
+ delete listOfAttributes;
+}
+
+template <class ElementType>
+void QTestCoreElement<ElementType>::addAttribute(const QTest::AttributeIndex attributeIndex, const char *value)
+{
+ if(attributeIndex == -1)
+ return;
+
+ if (attribute(attributeIndex))
+ return;
+
+ QTestElementAttribute *testAttribute = new QTestElementAttribute;
+ testAttribute->setPair(attributeIndex, value);
+ testAttribute->addToList(&listOfAttributes);
+}
+
+template <class ElementType>
+QTestElementAttribute *QTestCoreElement<ElementType>::attributes() const
+{
+ return listOfAttributes;
+}
+
+template <class ElementType>
+const char *QTestCoreElement<ElementType>::attributeValue(QTest::AttributeIndex index) const
+{
+ const QTestElementAttribute *attrb = attribute(index);
+ if(attrb)
+ return attrb->value();
+
+ return 0;
+}
+
+template <class ElementType>
+const char *QTestCoreElement<ElementType>::attributeName(QTest::AttributeIndex index) const
+{
+ const QTestElementAttribute *attrb = attribute(index);
+ if(attrb)
+ return attrb->name();
+
+ return 0;
+}
+
+template <class ElementType>
+const char *QTestCoreElement<ElementType>::elementName() const
+{
+ const char *xmlElementNames[] =
+ {
+ "property",
+ "properties",
+ "failure",
+ "error",
+ "testcase",
+ "testsuite",
+ "benchmark",
+ "system-err"
+ };
+
+ if(type != QTest::LET_Undefined)
+ return xmlElementNames[type];
+
+ return 0;
+}
+
+template <class ElementType>
+QTest::LogElementType QTestCoreElement<ElementType>::elementType() const
+{
+ return type;
+}
+
+template <class ElementType>
+const QTestElementAttribute *QTestCoreElement<ElementType>::attribute(QTest::AttributeIndex index) const
+{
+ QTestElementAttribute *iterator = listOfAttributes;
+ while(iterator){
+ if(iterator->index() == index)
+ return iterator;
+
+ iterator = iterator->nextElement();
+ }
+
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/testlib/qtestcorelist.h b/src/testlib/qtestcorelist.h
new file mode 100644
index 0000000..e3642e6
--- /dev/null
+++ b/src/testlib/qtestcorelist.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTCORELIST_H
+#define QTESTCORELIST_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+template <class T>
+class QTestCoreList
+{
+ public:
+ QTestCoreList();
+ virtual ~QTestCoreList();
+
+ void addToList(T **list);
+ T *nextElement();
+ T *previousElement();
+ int count(T *list);
+ int count();
+
+ private:
+ T *next;
+ T *prev;
+};
+
+template <class T>
+QTestCoreList<T>::QTestCoreList()
+:next(0)
+,prev(0)
+{
+}
+
+template <class T>
+QTestCoreList<T>::~QTestCoreList()
+{
+ if (prev) {
+ prev->next = 0;
+ }
+ delete prev;
+
+ if (next) {
+ next->prev = 0;
+ }
+ delete next;
+}
+
+template <class T>
+void QTestCoreList<T>::addToList(T **list)
+{
+ if (next)
+ next->addToList(list);
+ else {
+ next = *list;
+ if (next)
+ next->prev = static_cast<T*>(this);
+ }
+
+ *list = static_cast<T*>(this);
+}
+
+template <class T>
+T *QTestCoreList<T>::nextElement()
+{
+ return next;
+}
+
+template <class T>
+T *QTestCoreList<T>::previousElement()
+{
+ return prev;
+}
+
+template <class T>
+int QTestCoreList<T>::count()
+{
+ int numOfElements = 0;
+ T *it = next;
+
+ while(it){
+ ++numOfElements;
+ it = it->nextElement();
+ }
+
+ return numOfElements;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/testlib/qtestelement.cpp b/src/testlib/qtestelement.cpp
new file mode 100644
index 0000000..7bcf18d
--- /dev/null
+++ b/src/testlib/qtestelement.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestelement.h"
+
+QT_BEGIN_NAMESPACE
+
+QTestElement::QTestElement(int type)
+ :QTestCoreElement<QTestElement>(type),
+ listOfChildren(0),
+ parent(0)
+{
+}
+
+QTestElement::~QTestElement()
+{
+ delete listOfChildren;
+}
+
+bool QTestElement::addLogElement(QTestElement *element)
+{
+ if(!element)
+ return false;
+
+ if(element->elementType() != QTest::LET_Undefined){
+ element->addToList(&listOfChildren);
+ element->setParent(this);
+ return true;
+ }
+
+ return false;
+}
+
+QTestElement *QTestElement::childElements() const
+{
+ return listOfChildren;
+}
+
+const QTestElement *QTestElement::parentElement() const
+{
+ return parent;
+}
+
+void QTestElement::setParent(const QTestElement *p)
+{
+ parent = p;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtestelement.h b/src/testlib/qtestelement.h
new file mode 100644
index 0000000..90ede0c
--- /dev/null
+++ b/src/testlib/qtestelement.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTELEMENT_H
+#define QTESTELEMENT_H
+
+#include <QtTest/qtestcoreelement.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+class QTestElement: public QTestCoreElement<QTestElement>
+{
+ public:
+ QTestElement(int type = -1);
+ ~QTestElement();
+
+ bool addLogElement(QTestElement *element);
+ QTestElement *childElements() const;
+
+ const QTestElement *parentElement() const;
+ void setParent(const QTestElement *p);
+
+ private:
+ QTestElement *listOfChildren;
+ const QTestElement * parent;
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/testlib/qtestelementattribute.cpp b/src/testlib/qtestelementattribute.cpp
new file mode 100644
index 0000000..df13131
--- /dev/null
+++ b/src/testlib/qtestelementattribute.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestelementattribute.h"
+#include <QtCore/qbytearray.h>
+#include <string.h>
+#include <stdlib.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \enum QTest::AttributeIndex
+ This enum numbers the different tests.
+
+ \value AI_Undefined
+
+ \value AI_Name
+
+ \value AI_Result
+
+ \value AI_Tests
+
+ \value AI_Failures
+
+ \value AI_Errors
+
+ \value AI_Type
+
+ \value AI_Description
+
+ \value AI_PropertyValue
+
+ \value AI_QTestVersion
+
+ \value AI_QtVersion
+
+ \value AI_File
+
+ \value AI_Line
+
+ \value AI_Metric
+
+ \value AI_Tag
+
+ \value AI_Value
+
+ \value AI_Iterations
+*/
+
+/*! \enum QTest::LogElementType
+ The enum specifies the kinds of test log messages.
+
+ \value LET_Undefined
+
+ \value LET_Property
+
+ \value LET_Properties
+
+ \value LET_Failure
+
+ \value LET_Error
+
+ \value LET_TestCase
+
+ \value LET_TestSuite
+
+ \value LET_Benchmark
+
+ \value LET_SystemError
+*/
+
+QTestElementAttribute::QTestElementAttribute()
+ :attributeValue(0),
+ attributeIndex(QTest::AI_Undefined)
+{
+}
+
+QTestElementAttribute::~QTestElementAttribute()
+{
+ delete[] attributeValue;
+}
+
+const char *QTestElementAttribute::value() const
+{
+ return attributeValue;
+}
+
+const char *QTestElementAttribute::name() const
+{
+ const char *AttributeNames[] =
+ {
+ "name",
+ "result",
+ "tests",
+ "failures",
+ "errors",
+ "type",
+ "description",
+ "value",
+ "qtestversion",
+ "qtversion",
+ "file",
+ "line",
+ "metric",
+ "tag",
+ "value",
+ "iterations"
+ };
+
+ if(attributeIndex != QTest::AI_Undefined)
+ return AttributeNames[attributeIndex];
+
+ return 0;
+}
+
+QTest::AttributeIndex QTestElementAttribute::index() const
+{
+ return attributeIndex;
+}
+
+bool QTestElementAttribute::isNull() const
+{
+ return attributeIndex == QTest::AI_Undefined;
+}
+
+bool QTestElementAttribute::setPair(QTest::AttributeIndex index, const char *value)
+{
+ if(!value)
+ return false;
+
+ delete[] attributeValue;
+
+ attributeIndex = index;
+ attributeValue = qstrdup(value);
+
+ return (attributeValue!=0) ? true:false;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtestelementattribute.h b/src/testlib/qtestelementattribute.h
new file mode 100644
index 0000000..a31cd50
--- /dev/null
+++ b/src/testlib/qtestelementattribute.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTELEMENTATTRIBUTE_H
+#define QTESTELEMENTATTRIBUTE_H
+
+#include <QtTest/qtestcorelist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+namespace QTest {
+
+ enum AttributeIndex
+ {
+ AI_Undefined = -1,
+ AI_Name = 0,
+ AI_Result = 1,
+ AI_Tests = 2,
+ AI_Failures = 3,
+ AI_Errors = 4,
+ AI_Type = 5,
+ AI_Description = 6,
+ AI_PropertyValue = 7,
+ AI_QTestVersion = 8,
+ AI_QtVersion = 9,
+ AI_File = 10,
+ AI_Line = 11,
+ AI_Metric = 12,
+ AI_Tag = 13,
+ AI_Value = 14,
+ AI_Iterations = 15
+ };
+
+ enum LogElementType
+ {
+ LET_Undefined = -1,
+ LET_Property = 0,
+ LET_Properties = 1,
+ LET_Failure = 2,
+ LET_Error = 3,
+ LET_TestCase = 4,
+ LET_TestSuite = 5,
+ LET_Benchmark = 6,
+ LET_SystemError = 7
+ };
+}
+
+class QTestElementAttribute: public QTestCoreList<QTestElementAttribute>
+{
+ public:
+ QTestElementAttribute();
+ ~QTestElementAttribute();
+
+ const char *value() const;
+ const char *name() const;
+ QTest::AttributeIndex index() const;
+ bool isNull() const;
+ bool setPair(QTest::AttributeIndex attributeIndex, const char *value);
+
+ private:
+ char *attributeValue;
+ QTest::AttributeIndex attributeIndex;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/testlib/qtestevent.h b/src/testlib/qtestevent.h
index cd9f131..55df572 100644
--- a/src/testlib/qtestevent.h
+++ b/src/testlib/qtestevent.h
@@ -48,8 +48,10 @@
#endif
#include <QtTest/qtest_global.h>
+#ifdef QT_GUI_LIB
#include <QtTest/qtestkeyboard.h>
#include <QtTest/qtestmouse.h>
+#endif
#include <QtTest/qtestsystem.h>
#include <QtCore/qlist.h>
@@ -71,6 +73,7 @@ public:
virtual ~QTestEvent() {}
};
+#ifdef QT_GUI_LIB
class QTestKeyEvent: public QTestEvent
{
public:
@@ -135,6 +138,8 @@ private:
QPoint _pos;
int _delay;
};
+#endif //QT_GUI_LIB
+
class QTestDelayEvent: public QTestEvent
{
@@ -159,6 +164,7 @@ public:
inline void clear()
{ qDeleteAll(*this); QList<QTestEvent *>::clear(); }
+#ifdef QT_GUI_LIB
inline void addKeyClick(Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
{ addKeyEvent(QTest::Click, qtKey, modifiers, msecs); }
inline void addKeyPress(Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
@@ -194,6 +200,7 @@ public:
{ append(new QTestMouseEvent(QTest::MouseDClick, button, stateKey, pos, delay)); }
inline void addMouseMove(QPoint pos = QPoint(), int delay=-1)
{ append(new QTestMouseEvent(QTest::MouseMove, Qt::NoButton, 0, pos, delay)); }
+#endif //QT_GUI_LIB
inline void addDelay(int msecs)
{ append(new QTestDelayEvent(msecs)); }
diff --git a/src/testlib/qtestevent.qdoc b/src/testlib/qtestevent.qdoc
new file mode 100644
index 0000000..613f941
--- /dev/null
+++ b/src/testlib/qtestevent.qdoc
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QTestEventList
+ \inmodule QtTest
+
+ \brief The QTestEventList class provides a list of GUI events.
+
+ QTestEventList inherits from QList<QTestEvent *>, and provides
+ convenience functions for populating the list.
+
+ A QTestEventList can be populated with GUI events that can be
+ stored as test data for later usage, or be replayed on any
+ QWidget.
+
+ Example:
+ \snippet doc/src/snippets/code/doc_src_qtestevent.qdoc 0
+
+ The example above simulates the user entering the character \c a
+ followed by a backspace, waiting for 200 milliseconds and
+ repeating it.
+*/
+
+/*! \fn QTestEventList::QTestEventList()
+
+ Constructs an empty QTestEventList.
+*/
+
+/*! \fn QTestEventList::QTestEventList(const QTestEventList &other)
+
+ Constructs a new QTestEventList as a copy of \a other.
+*/
+
+/*! \fn QTestEventList::~QTestEventList()
+
+ Empties the list and destroys all stored events.
+*/
+
+/*! \fn void QTestEventList::clear()
+
+ Removes all events from the list.
+*/
+
+/*! \fn void QTestEventList::addKeyClick(Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+
+ Adds a new key click to the list. The event will simulate the key \a qtKey with the modifier \a modifiers and then wait for \a msecs milliseconds.
+
+ \sa QTest::keyClick()
+*/
+
+/*! \fn void QTestEventList::addKeyPress(Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+
+ Adds a new key press to the list. The event will press the key \a qtKey with the modifier \a modifiers and then wait for \a msecs milliseconds.
+
+ \sa QTest::keyPress()
+*/
+
+/*! \fn void QTestEventList::addKeyRelease(Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+
+ Adds a new key release to the list. The event will release the key \a qtKey with the modifier \a modifiers and then wait for \a msecs milliseconds.
+
+ \sa QTest::keyRelease()
+
+*/
+
+/*! \fn void QTestEventList::addKeyEvent(QTest::KeyAction action, Qt::Key qtKey, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ \internal
+*/
+
+/*! \fn void QTestEventList::addKeyClick(char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+
+ \overload
+
+ Adds a new key click to the list. The event will simulate the key \a ascii with the modifier \a modifiers and then wait for \a msecs milliseconds.
+
+ \sa QTest::keyClick()
+
+*/
+
+/*! \fn void QTestEventList::addKeyPress(char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+
+ \overload
+
+ Adds a new key press to the list. The event will press the key \a ascii with the modifier \a modifiers and then wait for \a msecs milliseconds.
+
+ \sa QTest::keyPress()
+*/
+
+/*! \fn void QTestEventList::addKeyRelease(char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+
+ \overload
+
+ Adds a new key release to the list. The event will release the key \a ascii with the modifier \a modifiers and then wait for \a msecs milliseconds.
+
+ \sa QTest::keyRelease()
+*/
+
+/*! \fn void QTestEventList::addKeyClicks(const QString &keys, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+
+ Adds new keyboard entries to the list. The event will press the \a keys with the \a modifiers and wait \a msecs milliseconds between each key.
+
+ \sa QTest::keyClicks()
+*/
+
+/*! \fn void QTestEventList::addKeyEvent(QTest::KeyAction action, char ascii, Qt::KeyboardModifiers modifiers = Qt::NoModifier, int msecs = -1)
+ \internal
+*/
+
+/*! \fn void QTestEventList::addDelay(int msecs)
+
+ Adds a \a msecs milliseconds delay.
+
+ \sa QTest::qWait()
+*/
+
+/*! \fn void QTestEventList::simulate(QWidget *w)
+
+ Simulates the events from the list one by one on the widget \a w.
+ For an example, please read the \l QTestEventList class documentation.
+*/
+
+/*! \fn void QTestEventList::addMousePress(Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay=-1)
+
+ Add a mouse press to the list. The event will press the \a button with optional \a modifiers at the position \a pos with an optional \a delay. The default position is the center of the widget.
+
+ \sa QTest::mousePress()
+*/
+/*! \fn void QTestEventList::addMouseRelease(Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay=-1)
+
+ Add a mouse release to the list. The event will release the \a button with optional \a modifiers at the position \a pos with an optional \a delay. The default position is the center of the widget.
+
+ \sa QTest::mouseRelease()
+*/
+/*! \fn void QTestEventList::addMouseClick(Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay=-1)
+
+ Add a mouse click to the list. The event will click the \a button with optional \a modifiers at the position \a pos with an optional \a delay. The default position is the center of the widget.
+
+ \sa QTest::mouseClick()
+*/
+/*! \fn void QTestEventList::addMouseDClick(Qt::MouseButton button, Qt::KeyboardModifiers modifiers = 0, QPoint pos = QPoint(), int delay=-1)
+
+ Add a double mouse click to the list. The event will double click the \a button with optional \a modifiers at the position \a pos with an optional \a delay. The default position is the center of the widget.
+
+ \sa QTest::mousePress()
+*/
+/*! \fn void QTestEventList::addMouseMove(QPoint pos = QPoint(), int delay=-1)
+
+ Adds a mouse move to the list. The event will move the mouse to the position \a pos. If a \a delay (in milliseconds) is set, the test will wait after moving the mouse. The default position is the center of the widget.
+
+ \sa QTest::mousePress()
+*/
+
diff --git a/src/testlib/qtestfilelogger.cpp b/src/testlib/qtestfilelogger.cpp
new file mode 100644
index 0000000..7e550a6
--- /dev/null
+++ b/src/testlib/qtestfilelogger.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestfilelogger.h"
+#include "qtestassert.h"
+#include "QtTest/private/qtestlog_p.h"
+#include "QtTest/private/qtestresult_p.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QTest
+{
+ static FILE *stream = 0;
+}
+
+QTestFileLogger::QTestFileLogger()
+{
+}
+
+QTestFileLogger::~QTestFileLogger()
+{
+ if(QTest::stream)
+ fclose(QTest::stream);
+
+ QTest::stream = 0;
+}
+
+void QTestFileLogger::init()
+{
+ char filename[100];
+ QTest::qt_snprintf(filename, sizeof(filename), "%s.log",
+ QTestResult::currentTestObjectName());
+
+ // Keep filenames simple
+ for (uint 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)
+{
+ QTEST_ASSERT(QTest::stream);
+
+ ::fputs(msg, QTest::stream);
+ ::fflush(QTest::stream);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtestfilelogger.h b/src/testlib/qtestfilelogger.h
new file mode 100644
index 0000000..adceeb1
--- /dev/null
+++ b/src/testlib/qtestfilelogger.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTFILELOGGER_H
+#define QTESTFILELOGGER_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+class QTestFileLogger
+{
+ public:
+ QTestFileLogger();
+ ~QTestFileLogger();
+
+ void init();
+ void flush(const char *msg);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTESTFILELOGGER_H
diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h
index 5d95bf2..11c3b70 100644
--- a/src/testlib/qtestkeyboard.h
+++ b/src/testlib/qtestkeyboard.h
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#ifndef QTESTKEYBOARD_H
+#if !defined(QTESTKEYBOARD_H)
#define QTESTKEYBOARD_H
#if 0
diff --git a/src/testlib/qtestlightxmlstreamer.cpp b/src/testlib/qtestlightxmlstreamer.cpp
new file mode 100644
index 0000000..f75d8f7
--- /dev/null
+++ b/src/testlib/qtestlightxmlstreamer.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestlightxmlstreamer.h"
+#include "qtestelement.h"
+#include "qtestelementattribute.h"
+
+#include "QtTest/private/qtestlog_p.h"
+#include "QtTest/private/qtestresult_p.h"
+#include "QtTest/private/qxmltestlogger_p.h"
+
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+QTestLightXmlStreamer::QTestLightXmlStreamer()
+ :QTestBasicStreamer()
+{
+}
+
+QTestLightXmlStreamer::~QTestLightXmlStreamer()
+{}
+
+void QTestLightXmlStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted)
+ return;
+
+ switch(element->elementType()){
+ case QTest::LET_TestCase: {
+ QTestCharBuffer quotedTf;
+ QXmlTestLogger::xmlQuote(&quotedTf, element->attributeValue(QTest::AI_Name));
+
+ QTest::qt_asprintf(formatted, "<TestFunction name=\"%s\">\n", quotedTf.constData());
+ break;
+ }
+ case QTest::LET_Failure: {
+ QTestCharBuffer cdataDesc;
+ QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description));
+
+ QTest::qt_asprintf(formatted, " <Description><![CDATA[%s]]></Description>\n",
+ cdataDesc.constData());
+ break;
+ }
+ case QTest::LET_Error: {
+ // assuming type and attribute names don't need quoting
+ QTestCharBuffer quotedFile;
+ QTestCharBuffer cdataDesc;
+ QXmlTestLogger::xmlQuote(&quotedFile, element->attributeValue(QTest::AI_File));
+ QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description));
+
+ QTest::qt_asprintf(formatted, "<Message type=\"%s\" %s=\"%s\" %s=\"%s\">\n <Description><![CDATA[%s]]></Description>\n</Message>\n",
+ element->attributeValue(QTest::AI_Type),
+ element->attributeName(QTest::AI_File),
+ quotedFile.constData(),
+ element->attributeName(QTest::AI_Line),
+ element->attributeValue(QTest::AI_Line),
+ cdataDesc.constData());
+ break;
+ }
+ case QTest::LET_Benchmark: {
+ // assuming value and iterations don't need quoting
+ QTestCharBuffer quotedMetric;
+ QTestCharBuffer quotedTag;
+ QXmlTestLogger::xmlQuote(&quotedMetric, element->attributeValue(QTest::AI_Metric));
+ QXmlTestLogger::xmlQuote(&quotedTag, element->attributeValue(QTest::AI_Tag));
+
+ QTest::qt_asprintf(formatted, "<BenchmarkResult %s=\"%s\" %s=\"%s\" %s=\"%s\" %s=\"%s\" />\n",
+ element->attributeName(QTest::AI_Metric),
+ quotedMetric.constData(),
+ element->attributeName(QTest::AI_Tag),
+ quotedTag.constData(),
+ element->attributeName(QTest::AI_Value),
+ element->attributeValue(QTest::AI_Value),
+ element->attributeName(QTest::AI_Iterations),
+ element->attributeValue(QTest::AI_Iterations) );
+ break;
+ }
+ default:
+ formatted->data()[0] = '\0';
+ }
+}
+
+void QTestLightXmlStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted)
+ return;
+
+ if (element->elementType() == QTest::LET_TestCase) {
+ if( element->attribute(QTest::AI_Result) && element->childElements())
+ QTest::qt_asprintf(formatted, "</Incident>\n</TestFunction>\n");
+ else
+ QTest::qt_asprintf(formatted, "</TestFunction>\n");
+ } else {
+ formatted->data()[0] = '\0';
+ }
+}
+
+void QTestLightXmlStreamer::formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted)
+ return;
+
+ if (element->elementType() == QTest::LET_TestCase && element->attribute(QTest::AI_Result)) {
+ QTestCharBuffer buf;
+ QTestCharBuffer quotedFile;
+ QXmlTestLogger::xmlQuote(&quotedFile, element->attributeValue(QTest::AI_File));
+
+ QTest::qt_asprintf(&buf, "%s=\"%s\" %s=\"%s\"",
+ element->attributeName(QTest::AI_File),
+ quotedFile.constData(),
+ element->attributeName(QTest::AI_Line),
+ element->attributeValue(QTest::AI_Line));
+
+ if( !element->childElements() )
+ QTest::qt_asprintf(formatted, "<Incident type=\"%s\" %s/>\n",
+ element->attributeValue(QTest::AI_Result), buf.constData());
+ else
+ QTest::qt_asprintf(formatted, "<Incident type=\"%s\" %s>\n",
+ element->attributeValue(QTest::AI_Result), buf.constData());
+ } else {
+ formatted->data()[0] = '\0';
+ }
+}
+
+void QTestLightXmlStreamer::output(QTestElement *element) const
+{
+ QTestCharBuffer buf;
+ QTest::qt_asprintf(&buf, "<Environment>\n <QtVersion>%s</QtVersion>\n <QTestVersion>%s</QTestVersion>\n",
+ qVersion(), QTEST_VERSION_STR );
+ outputString(buf.constData());
+
+ QTest::qt_asprintf(&buf, "</Environment>\n");
+ outputString(buf.constData());
+
+ QTestBasicStreamer::output(element);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtestlightxmlstreamer.h b/src/testlib/qtestlightxmlstreamer.h
new file mode 100644
index 0000000..5e58da9
--- /dev/null
+++ b/src/testlib/qtestlightxmlstreamer.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTLIGHTXMLSTREAMER_H
+#define QTESTLIGHTXMLSTREAMER_H
+
+#include <QtTest/qtestbasicstreamer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+class QTestElement;
+class QTestElementAttribute;
+
+class QTestLightXmlStreamer: public QTestBasicStreamer
+{
+ public:
+ QTestLightXmlStreamer();
+ ~QTestLightXmlStreamer();
+
+ void formatStart(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void output(QTestElement *element) const;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 687c072..da695dc 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -46,7 +46,6 @@
#include "QtTest/private/qabstracttestlogger_p.h"
#include "QtTest/private/qplaintestlogger_p.h"
#include "QtTest/private/qxmltestlogger_p.h"
-
#include <QtCore/qatomic.h>
#include <QtCore/qbytearray.h>
@@ -54,6 +53,9 @@
#include <string.h>
#include <limits.h>
+
+#include "qtestlogger_p.h"
+
QT_BEGIN_NAMESPACE
namespace QTest {
@@ -83,6 +85,7 @@ namespace QTest {
static IgnoreResultList *ignoreResultList = 0;
static QTestLog::LogMode logMode = QTestLog::Plain;
+ static QTestLog::FlushMode flushMode = QTestLog::NoFlush;
static int verbosity = 0;
static int maxWarnings = 2002;
@@ -136,7 +139,7 @@ namespace QTest {
if (!counter.deref()) {
QTest::testLogger->addMessage(QAbstractTestLogger::QSystem,
- "Maximum amount of warnings exceeded.");
+ "Maximum amount of warnings exceeded. Use -maxwarnings to override.");
return;
}
}
@@ -270,15 +273,24 @@ void QTestLog::startLogging()
QTEST_ASSERT(!QTest::testLogger);
switch (QTest::logMode) {
- case QTestLog::Plain:
- QTest::testLogger = new QPlainTestLogger();
- break;
- case QTestLog::XML:
- QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Complete);
- break;
- case QTestLog::LightXML:
- QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Light);
- }
+ case QTestLog::Plain:
+ QTest::testLogger = new QPlainTestLogger;
+ break;
+ case QTestLog::XML:{
+ if(QTest::flushMode == QTestLog::FLushOn)
+ QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Complete);
+ else
+ QTest::testLogger = new QTestLogger(QTestLogger::TLF_XML);
+ break;
+ }case QTestLog::LightXML:{
+ if(QTest::flushMode == QTestLog::FLushOn)
+ QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Light);
+ else
+ QTest::testLogger = new QTestLogger(QTestLogger::TLF_LightXml);
+ break;
+ }case QTestLog::XunitXML:
+ QTest::testLogger = new QTestLogger(QTestLogger::TLF_XunitXml);
+ }
QTest::testLogger->startLogging();
@@ -305,11 +317,10 @@ void QTestLog::warn(const char *msg)
void QTestLog::info(const char *msg, const char *file, int line)
{
- QTEST_ASSERT(QTest::testLogger);
QTEST_ASSERT(msg);
- QTEST_ASSERT(file);
- QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg, file, line);
+ if (QTest::testLogger)
+ QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg, file, line);
}
void QTestLog::setLogMode(LogMode mode)
@@ -363,4 +374,9 @@ void QTestLog::setMaxWarnings(int m)
QTest::maxWarnings = m <= 0 ? INT_MAX : m + 2;
}
+void QTestLog::setFlushMode(FlushMode mode)
+{
+ QTest::flushMode = mode;
+}
+
QT_END_NAMESPACE
diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h
index 19e8d61..8b8a6ad 100644
--- a/src/testlib/qtestlog_p.h
+++ b/src/testlib/qtestlog_p.h
@@ -62,7 +62,8 @@ class QBenchmarkResult;
class QTestLog
{
public:
- enum LogMode { Plain = 0, XML, LightXML };
+ enum LogMode { Plain = 0, XML, LightXML, XunitXML };
+ enum FlushMode { NoFlush = 0, FLushOn };
static void enterTestFunction(const char* function);
static void leaveTestFunction();
@@ -95,6 +96,8 @@ public:
static void setMaxWarnings(int max);
+ static void setFlushMode(FlushMode mode);
+
private:
QTestLog();
~QTestLog();
diff --git a/src/testlib/qtestlogger.cpp b/src/testlib/qtestlogger.cpp
new file mode 100644
index 0000000..3e89ff7
--- /dev/null
+++ b/src/testlib/qtestlogger.cpp
@@ -0,0 +1,403 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestlogger_p.h"
+#include "qtestelement.h"
+#include "qtestxunitstreamer.h"
+#include "qtestxmlstreamer.h"
+#include "qtestlightxmlstreamer.h"
+#include "qtestfilelogger.h"
+
+#include "QtTest/qtestcase.h"
+#include "QtTest/private/qtestresult_p.h"
+#include "QtTest/private/qbenchmark_p.h"
+
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+QTestLogger::QTestLogger(int fm)
+ :listOfTestcases(0), currentLogElement(0), errorLogElement(0),
+ logFormatter(0), format( (TestLoggerFormat)fm ), filelogger(new QTestFileLogger),
+ testCounter(0), passCounter(0),
+ failureCounter(0), errorCounter(0),
+ warningCounter(0), skipCounter(0),
+ systemCounter(0), qdebugCounter(0),
+ qwarnCounter(0), qfatalCounter(0),
+ infoCounter(0)
+{
+}
+
+QTestLogger::~QTestLogger()
+{
+ if(format == TLF_XunitXml)
+ delete currentLogElement;
+ else
+ delete listOfTestcases;
+
+ delete logFormatter;
+ delete filelogger;
+}
+
+void QTestLogger::startLogging()
+{
+ switch(format){
+ case TLF_LightXml:{
+ logFormatter = new QTestLightXmlStreamer;
+ filelogger->init();
+ break;
+ }case TLF_XML:{
+ logFormatter = new QTestXmlStreamer;
+ filelogger->init();
+ break;
+ }case TLF_XunitXml:{
+ logFormatter = new QTestXunitStreamer;
+ delete errorLogElement;
+ errorLogElement = new QTestElement(QTest::LET_SystemError);
+ filelogger->init();
+ break;
+ }
+ }
+
+ logFormatter->setLogger(this);
+ logFormatter->startStreaming();
+}
+
+void QTestLogger::stopLogging()
+{
+ QTestElement *iterator = listOfTestcases;
+
+ if(format == TLF_XunitXml ){
+ char buf[10];
+
+ currentLogElement = new QTestElement(QTest::LET_TestSuite);
+ currentLogElement->addAttribute(QTest::AI_Name, QTestResult::currentTestObjectName());
+
+ QTest::qt_snprintf(buf, sizeof(buf), "%i", testCounter);
+ currentLogElement->addAttribute(QTest::AI_Tests, buf);
+
+ QTest::qt_snprintf(buf, sizeof(buf), "%i", failureCounter);
+ currentLogElement->addAttribute(QTest::AI_Failures, buf);
+
+ QTest::qt_snprintf(buf, sizeof(buf), "%i", errorCounter);
+ currentLogElement->addAttribute(QTest::AI_Errors, buf);
+
+ QTestElement *property;
+ QTestElement *properties = new QTestElement(QTest::LET_Properties);
+
+ property = new QTestElement(QTest::LET_Property);
+ property->addAttribute(QTest::AI_Name, "QTestVersion");
+ property->addAttribute(QTest::AI_PropertyValue, QTEST_VERSION_STR);
+ properties->addLogElement(property);
+
+ property = new QTestElement(QTest::LET_Property);
+ property->addAttribute(QTest::AI_Name, "QtVersion");
+ property->addAttribute(QTest::AI_PropertyValue, qVersion());
+ properties->addLogElement(property);
+
+ currentLogElement->addLogElement(properties);
+
+ currentLogElement->addLogElement(iterator);
+
+ /* For correct indenting, make sure every testcase knows its parent */
+ QTestElement* testcase = iterator;
+ while (testcase) {
+ testcase->setParent(currentLogElement);
+ testcase = testcase->nextElement();
+ }
+
+ currentLogElement->addLogElement(errorLogElement);
+
+ QTestElement *it = currentLogElement;
+ logFormatter->output(it);
+ }else{
+ logFormatter->output(iterator);
+ }
+
+ logFormatter->stopStreaming();
+}
+
+void QTestLogger::enterTestFunction(const char *function)
+{
+ char buf[1024];
+ QTest::qt_snprintf(buf, sizeof(buf), "Entered test-function: %s\n", function);
+ filelogger->flush(buf);
+
+ currentLogElement = new QTestElement(QTest::LET_TestCase);
+ currentLogElement->addAttribute(QTest::AI_Name, function);
+ currentLogElement->addToList(&listOfTestcases);
+
+ ++testCounter;
+}
+
+void QTestLogger::leaveTestFunction()
+{
+}
+
+void QTestLogger::addIncident(IncidentTypes type, const char *description,
+ const char *file, int line)
+{
+ const char *typeBuf = 0;
+ char buf[100];
+
+ switch (type) {
+ case QAbstractTestLogger::XPass:
+ ++failureCounter;
+ typeBuf = "xpass";
+ break;
+ case QAbstractTestLogger::Pass:
+ ++passCounter;
+ typeBuf = "pass";
+ break;
+ case QAbstractTestLogger::XFail:
+ ++passCounter;
+ typeBuf = "xfail";
+ break;
+ case QAbstractTestLogger::Fail:
+ ++failureCounter;
+ typeBuf = "fail";
+ break;
+ default:
+ typeBuf = "??????";
+ break;
+ }
+
+ if (type == QAbstractTestLogger::Fail || type == QAbstractTestLogger::XPass
+ || ((format != TLF_XunitXml) && (type == QAbstractTestLogger::XFail))) {
+ QTestElement *failureElement = new QTestElement(QTest::LET_Failure);
+ failureElement->addAttribute(QTest::AI_Result, typeBuf);
+ if(file)
+ failureElement->addAttribute(QTest::AI_File, file);
+ else
+ failureElement->addAttribute(QTest::AI_File, "");
+ QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
+ failureElement->addAttribute(QTest::AI_Line, buf);
+ failureElement->addAttribute(QTest::AI_Description, description);
+ const char* tag = QTestResult::currentDataTag();
+ if (tag) {
+ failureElement->addAttribute(QTest::AI_Tag, tag);
+ }
+ currentLogElement->addLogElement(failureElement);
+ }
+
+ /*
+ Only one result can be shown for the whole testfunction.
+ Check if we currently have a result, and if so, overwrite it
+ iff the new result is worse.
+ */
+ QTestElementAttribute* resultAttr =
+ const_cast<QTestElementAttribute*>(currentLogElement->attribute(QTest::AI_Result));
+ if (resultAttr) {
+ const char* oldResult = resultAttr->value();
+ bool overwrite = false;
+ if (!strcmp(oldResult, "pass")) {
+ overwrite = true;
+ }
+ else if (!strcmp(oldResult, "xfail")) {
+ overwrite = (type == QAbstractTestLogger::XPass || type == QAbstractTestLogger::Fail);
+ }
+ else if (!strcmp(oldResult, "xpass")) {
+ overwrite = (type == QAbstractTestLogger::Fail);
+ }
+ if (overwrite) {
+ resultAttr->setPair(QTest::AI_Result, typeBuf);
+ }
+ }
+ else {
+ currentLogElement->addAttribute(QTest::AI_Result, typeBuf);
+ }
+
+ if(file)
+ currentLogElement->addAttribute(QTest::AI_File, file);
+ else
+ currentLogElement->addAttribute(QTest::AI_File, "");
+
+ QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
+ currentLogElement->addAttribute(QTest::AI_Line, buf);
+
+ /*
+ Since XFAIL does not add a failure to the testlog in xunitxml, add a message, so we still
+ have some information about the expected failure.
+ */
+ if (format == TLF_XunitXml && type == QAbstractTestLogger::XFail) {
+ QTestLogger::addMessage(QAbstractTestLogger::Info, description, file, line);
+ }
+}
+
+void QTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
+{
+ QTestElement *benchmarkElement = new QTestElement(QTest::LET_Benchmark);
+// printf("element %i", benchmarkElement->elementType());
+
+ benchmarkElement->addAttribute(QTest::AI_Metric, QBenchmarkGlobalData::current->measurer->metricText().toAscii().data());
+ benchmarkElement->addAttribute(QTest::AI_Tag, result.context.tag.toAscii().data());
+ benchmarkElement->addAttribute(QTest::AI_Value, QByteArray::number(result.value).constData());
+
+ char buf[100];
+ QTest::qt_snprintf(buf, sizeof(buf), "%i", result.iterations);
+ benchmarkElement->addAttribute(QTest::AI_Iterations, buf);
+ currentLogElement->addLogElement(benchmarkElement);
+}
+
+void QTestLogger::addMessage(MessageTypes type, const char *message, const char *file, int line)
+{
+ QTestElement *errorElement = new QTestElement(QTest::LET_Error);
+ const char *typeBuf = 0;
+
+ switch (type) {
+ case QAbstractTestLogger::Warn:
+ ++warningCounter;
+ typeBuf = "warn";
+ break;
+ case QAbstractTestLogger::QSystem:
+ ++systemCounter;
+ typeBuf = "system";
+ break;
+ case QAbstractTestLogger::QDebug:
+ ++qdebugCounter;
+ typeBuf = "qdebug";
+ break;
+ case QAbstractTestLogger::QWarning:
+ ++qwarnCounter;
+ typeBuf = "qwarning";
+ break;
+ case QAbstractTestLogger::QFatal:
+ ++qfatalCounter;
+ typeBuf = "qfatal";
+ break;
+ case QAbstractTestLogger::Skip:
+ ++skipCounter;
+ typeBuf = "skip";
+ break;
+ case QAbstractTestLogger::Info:
+ ++infoCounter;
+ typeBuf = "info";
+ break;
+ default:
+ typeBuf = "??????";
+ break;
+ }
+
+ errorElement->addAttribute(QTest::AI_Type, typeBuf);
+ errorElement->addAttribute(QTest::AI_Description, message);
+
+ if(file)
+ errorElement->addAttribute(QTest::AI_File, file);
+ else
+ errorElement->addAttribute(QTest::AI_File, "");
+
+ char buf[100];
+ QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
+ errorElement->addAttribute(QTest::AI_Line, buf);
+
+ currentLogElement->addLogElement(errorElement);
+ ++errorCounter;
+
+ // Also add the message to the system error log (i.e. stderr), if one exists
+ if (errorLogElement) {
+ QTestElement *systemErrorElement = new QTestElement(QTest::LET_Error);
+ systemErrorElement->addAttribute(QTest::AI_Description, message);
+ errorLogElement->addLogElement(systemErrorElement);
+ }
+}
+
+void QTestLogger::setLogFormat(TestLoggerFormat fm)
+{
+ format = fm;
+}
+
+QTestLogger::TestLoggerFormat QTestLogger::logFormat()
+{
+ return format;
+}
+
+int QTestLogger::passCount() const
+{
+ return passCounter;
+}
+
+int QTestLogger::failureCount() const
+{
+ return failureCounter;
+}
+
+int QTestLogger::errorCount() const
+{
+ return errorCounter;
+}
+
+int QTestLogger::warningCount() const
+{
+ return warningCounter;
+}
+
+int QTestLogger::skipCount() const
+{
+ return skipCounter;
+}
+
+int QTestLogger::systemCount() const
+{
+ return systemCounter;
+}
+
+int QTestLogger::qdebugCount() const
+{
+ return qdebugCounter;
+}
+
+int QTestLogger::qwarnCount() const
+{
+ return qwarnCounter;
+}
+
+int QTestLogger::qfatalCount() const
+{
+ return qfatalCounter;
+}
+
+int QTestLogger::infoCount() const
+{
+ return infoCounter;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtestlogger_p.h b/src/testlib/qtestlogger_p.h
new file mode 100644
index 0000000..5d943ba
--- /dev/null
+++ b/src/testlib/qtestlogger_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTLOGGER_P_H
+#define QTESTLOGGER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtTest/private/qabstracttestlogger_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTestBasicStreamer;
+class QTestElement;
+class QTestFileLogger;
+
+class QTestLogger : public QAbstractTestLogger
+{
+ public:
+ QTestLogger(int fm = 0);
+ ~QTestLogger();
+
+ enum TestLoggerFormat
+ {
+ TLF_XML = 0,
+ TLF_LightXml = 1,
+ TLF_XunitXml = 2
+ };
+
+ void startLogging();
+ void stopLogging();
+
+ void enterTestFunction(const char *function);
+ void leaveTestFunction();
+
+ void addIncident(IncidentTypes type, const char *description,
+ const char *file = 0, int line = 0);
+ void addBenchmarkResult(const QBenchmarkResult &result);
+
+ void addMessage(MessageTypes type, const char *message,
+ const char *file = 0, int line = 0);
+
+ void setLogFormat(TestLoggerFormat fm);
+ TestLoggerFormat logFormat();
+
+ int passCount() const;
+ int failureCount() const;
+ int errorCount() const;
+ int warningCount() const;
+ int skipCount() const;
+ int systemCount() const;
+ int qdebugCount() const;
+ int qwarnCount() const;
+ int qfatalCount() const;
+ int infoCount() const;
+
+ private:
+ QTestElement *listOfTestcases;
+ QTestElement *currentLogElement;
+ QTestElement *errorLogElement;
+ QTestBasicStreamer *logFormatter;
+ TestLoggerFormat format;
+ QTestFileLogger *filelogger;
+
+ int testCounter;
+ int passCounter;
+ int failureCounter;
+ int errorCounter;
+ int warningCounter;
+ int skipCounter;
+ int systemCounter;
+ int qdebugCounter;
+ int qwarnCounter;
+ int qfatalCounter;
+ int infoCounter;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTESTLOGGER_P_H
diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h
index 071cd40..f339a5a 100644
--- a/src/testlib/qtestmouse.h
+++ b/src/testlib/qtestmouse.h
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#ifndef QTESTMOUSE_H
+#if !defined(QTESTMOUSE_H)
#define QTESTMOUSE_H
#if 0
@@ -113,8 +113,12 @@ namespace QTest
QTEST_ASSERT(false);
}
QSpontaneKeyEvent::setSpontaneous(&me);
- if (!qApp->notify(widget, &me))
- QTest::qWarn("Mouse event not accepted by receiving widget");
+ if (!qApp->notify(widget, &me)) {
+ static const char *mouseActionNames[] =
+ { "MousePress", "MouseRelease", "MouseClick", "MouseDClick", "MouseMove" };
+ QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving widget");
+ QTest::qWarn(warning.arg(QString::fromLatin1(mouseActionNames[static_cast<int>(action)])).toAscii().data());
+ }
}
diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp
index 92026e2..a62975e 100644
--- a/src/testlib/qtestresult.cpp
+++ b/src/testlib/qtestresult.cpp
@@ -68,7 +68,7 @@ namespace QTest
static const char *expectFailComment = 0;
static int expectFailMode = 0;
-};
+}
void QTestResult::reset()
{
diff --git a/src/testlib/qtestspontaneevent.h b/src/testlib/qtestspontaneevent.h
index 0c670f8..2f00414 100644
--- a/src/testlib/qtestspontaneevent.h
+++ b/src/testlib/qtestspontaneevent.h
@@ -74,9 +74,9 @@ public:
class QSpontaneKeyEvent
{
public:
- void setSpontaneous() { spont = 1; };
- bool spontaneous() { return spont; };
- virtual void dummyFunc() { };
+ void setSpontaneous() { spont = 1; }
+ bool spontaneous() { return spont; }
+ virtual void dummyFunc() {}
virtual ~QSpontaneKeyEvent() {}
#ifndef QTEST_NO_SIZEOF_CHECK
diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h
index bdcc826..8caec76 100644
--- a/src/testlib/qtestsystem.h
+++ b/src/testlib/qtestsystem.h
@@ -52,6 +52,11 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Test)
+class QWidget;
+#ifdef Q_WS_X11
+extern void qt_x11_wait_for_window_manager(QWidget *w);
+#endif
+
namespace QTest
{
inline static void qWait(int ms)
@@ -65,6 +70,22 @@ namespace QTest
QTest::qSleep(10);
} while (timer.elapsed() < ms);
}
+
+ inline static bool qWaitForWindowShown(QWidget *window)
+ {
+#if defined(Q_WS_X11)
+ qt_x11_wait_for_window_manager(window);
+ QCoreApplication::processEvents();
+#elif defined(Q_WS_QWS)
+ Q_UNUSED(window);
+ qWait(100);
+#else
+ Q_UNUSED(window);
+ qWait(50);
+#endif
+ return true;
+ }
+
}
QT_END_NAMESPACE
diff --git a/src/testlib/qtesttouch.h b/src/testlib/qtesttouch.h
new file mode 100644
index 0000000..3e6c31d
--- /dev/null
+++ b/src/testlib/qtesttouch.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTTOUCH_H
+#define QTESTTOUCH_H
+
+#if 0
+// inform syncqt
+#pragma qt_no_master_include
+#endif
+
+#include <QtTest/qtest_global.h>
+#include <QtTest/qtestassert.h>
+#include <QtTest/qtestsystem.h>
+#include <QtTest/qtestspontaneevent.h>
+
+#include <QtCore/qmap.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+extern Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
+ QTouchEvent::DeviceType deviceType,
+ const QList<QTouchEvent::TouchPoint> &touchPoints);
+
+namespace QTest
+{
+
+ class QTouchEventSequence
+ {
+ public:
+ ~QTouchEventSequence()
+ {
+ commit();
+ points.clear();
+ }
+ QTouchEventSequence& press(int touchId, const QPoint &pt, QWidget *widget = 0)
+ {
+ QTouchEvent::TouchPoint &p = point(touchId);
+ p.setScreenPos(mapToScreen(widget, pt));
+ p.setState(Qt::TouchPointPressed);
+ return *this;
+ }
+ QTouchEventSequence& move(int touchId, const QPoint &pt, QWidget *widget = 0)
+ {
+ QTouchEvent::TouchPoint &p = point(touchId);
+ p.setScreenPos(mapToScreen(widget, pt));
+ p.setState(Qt::TouchPointMoved);
+ return *this;
+ }
+ QTouchEventSequence& release(int touchId, const QPoint &pt, QWidget *widget = 0)
+ {
+ QTouchEvent::TouchPoint &p = point(touchId);
+ p.setScreenPos(mapToScreen(widget, pt));
+ p.setState(Qt::TouchPointReleased);
+ return *this;
+ }
+ QTouchEventSequence& stationary(int touchId)
+ {
+ QTouchEvent::TouchPoint &p = point(touchId);
+ p.setState(Qt::TouchPointStationary);
+ return *this;
+ }
+
+ private:
+ QTouchEventSequence(QWidget *widget, QTouchEvent::DeviceType deviceType)
+ : targetWidget(widget), deviceType(deviceType)
+ {
+ }
+ QTouchEventSequence(const QTouchEventSequence &v);
+ void operator=(const QTouchEventSequence&);
+
+ QTouchEvent::TouchPoint &point(int touchId)
+ {
+ if (!points.contains(touchId))
+ points[touchId] = QTouchEvent::TouchPoint(touchId);
+ return points[touchId];
+ }
+ QPoint mapToScreen(QWidget *widget, const QPoint &pt)
+ {
+ if (widget)
+ return widget->mapToGlobal(pt);
+ return targetWidget ? targetWidget->mapToGlobal(pt) : pt;
+ }
+ void commit()
+ {
+ qt_translateRawTouchEvent(targetWidget, deviceType, points.values());
+ targetWidget = 0;
+ }
+
+ QMap<int, QTouchEvent::TouchPoint> points;
+ QWidget *targetWidget;
+ QTouchEvent::DeviceType deviceType;
+ friend QTouchEventSequence touchEvent(QWidget *, QTouchEvent::DeviceType);
+ };
+
+ inline
+ QTouchEventSequence touchEvent(QWidget *widget = 0,
+ QTouchEvent::DeviceType deviceType = QTouchEvent::TouchScreen)
+ {
+ return QTouchEventSequence(widget, deviceType);
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTESTTOUCH_H
diff --git a/src/testlib/qtestxmlstreamer.cpp b/src/testlib/qtestxmlstreamer.cpp
new file mode 100644
index 0000000..990bbfc
--- /dev/null
+++ b/src/testlib/qtestxmlstreamer.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestxmlstreamer.h"
+#include "qtestelement.h"
+#include "qtestelementattribute.h"
+
+#include "QtTest/private/qtestlog_p.h"
+#include "QtTest/private/qtestresult_p.h"
+#include "QtTest/private/qxmltestlogger_p.h"
+
+#include <string.h>
+#include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+QTestXmlStreamer::QTestXmlStreamer()
+ :QTestBasicStreamer()
+{
+}
+
+QTestXmlStreamer::~QTestXmlStreamer()
+{}
+
+void QTestXmlStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted)
+ return;
+
+ switch(element->elementType()){
+ case QTest::LET_TestCase: {
+ QTestCharBuffer quotedTf;
+ QXmlTestLogger::xmlQuote(&quotedTf, element->attributeValue(QTest::AI_Name));
+
+ QTest::qt_asprintf(formatted, "<TestFunction name=\"%s\">\n", quotedTf.constData());
+ break;
+ }
+ case QTest::LET_Failure: {
+ QTestCharBuffer cdataDesc;
+ QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description));
+
+ QTestCharBuffer location;
+ QTestCharBuffer quotedFile;
+ QXmlTestLogger::xmlQuote(&quotedFile, element->attributeValue(QTest::AI_File));
+
+ QTest::qt_asprintf(&location, "%s=\"%s\" %s=\"%s\"",
+ element->attributeName(QTest::AI_File),
+ quotedFile.constData(),
+ element->attributeName(QTest::AI_Line),
+ element->attributeValue(QTest::AI_Line));
+
+ if (element->attribute(QTest::AI_Tag)) {
+ QTestCharBuffer cdataTag;
+ QXmlTestLogger::xmlCdata(&cdataTag, element->attributeValue(QTest::AI_Tag));
+ QTest::qt_asprintf(formatted, "<Incident type=\"%s\" %s>\n"
+ " <DataTag><![CDATA[%s]]></DataTag>\n"
+ " <Description><![CDATA[%s]]></Description>\n"
+ "</Incident>\n", element->attributeValue(QTest::AI_Result),
+ location.constData(), cdataTag.constData(), cdataDesc.constData());
+ }
+ else {
+ QTest::qt_asprintf(formatted, "<Incident type=\"%s\" %s>\n"
+ " <Description><![CDATA[%s]]></Description>\n"
+ "</Incident>\n", element->attributeValue(QTest::AI_Result),
+ location.constData(), cdataDesc.constData());
+ }
+ break;
+ }
+ case QTest::LET_Error: {
+ // assuming type and attribute names don't need quoting
+ QTestCharBuffer quotedFile;
+ QTestCharBuffer cdataDesc;
+ QXmlTestLogger::xmlQuote(&quotedFile, element->attributeValue(QTest::AI_File));
+ QXmlTestLogger::xmlCdata(&cdataDesc, element->attributeValue(QTest::AI_Description));
+
+ QTest::qt_asprintf(formatted, "<Message type=\"%s\" %s=\"%s\" %s=\"%s\">\n <Description><![CDATA[%s]]></Description>\n</Message>\n",
+ element->attributeValue(QTest::AI_Type),
+ element->attributeName(QTest::AI_File),
+ quotedFile.constData(),
+ element->attributeName(QTest::AI_Line),
+ element->attributeValue(QTest::AI_Line),
+ cdataDesc.constData());
+ break;
+ }
+ case QTest::LET_Benchmark: {
+ // assuming value and iterations don't need quoting
+ QTestCharBuffer quotedMetric;
+ QTestCharBuffer quotedTag;
+ QXmlTestLogger::xmlQuote(&quotedMetric, element->attributeValue(QTest::AI_Metric));
+ QXmlTestLogger::xmlQuote(&quotedTag, element->attributeValue(QTest::AI_Tag));
+
+ QTest::qt_asprintf(formatted, "<BenchmarkResult %s=\"%s\" %s=\"%s\" %s=\"%s\" %s=\"%s\" />\n",
+ element->attributeName(QTest::AI_Metric),
+ quotedMetric.constData(),
+ element->attributeName(QTest::AI_Tag),
+ quotedTag.constData(),
+ element->attributeName(QTest::AI_Value),
+ element->attributeValue(QTest::AI_Value),
+ element->attributeName(QTest::AI_Iterations),
+ element->attributeValue(QTest::AI_Iterations) );
+ break;
+ }
+ default:
+ formatted->data()[0] = '\0';
+ }
+}
+
+void QTestXmlStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted)
+ return;
+
+ if (element->elementType() == QTest::LET_TestCase) {
+ QTest::qt_asprintf(formatted, "</TestFunction>\n");
+ } else {
+ formatted->data()[0] = '\0';
+ }
+}
+
+void QTestXmlStreamer::formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted)
+ return;
+
+ if (element->elementType() == QTest::LET_TestCase && element->attribute(QTest::AI_Result)){
+ QTestCharBuffer buf;
+ QTestCharBuffer quotedFile;
+ QXmlTestLogger::xmlQuote(&quotedFile, element->attributeValue(QTest::AI_File));
+
+ QTest::qt_asprintf(&buf, "%s=\"%s\" %s=\"%s\"",
+ element->attributeName(QTest::AI_File),
+ quotedFile.constData(),
+ element->attributeName(QTest::AI_Line),
+ element->attributeValue(QTest::AI_Line));
+
+ if( !element->childElements() ) {
+ QTest::qt_asprintf(formatted, "<Incident type=\"%s\" %s/>\n",
+ element->attributeValue(QTest::AI_Result), buf.constData());
+ } else {
+ formatted->data()[0] = '\0';
+ }
+ } else {
+ formatted->data()[0] = '\0';
+ }
+}
+
+void QTestXmlStreamer::output(QTestElement *element) const
+{
+ QTestCharBuffer buf;
+ QTestCharBuffer quotedTc;
+ QXmlTestLogger::xmlQuote(&quotedTc, QTestResult::currentTestObjectName());
+
+ QTest::qt_asprintf(&buf, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<TestCase name=\"%s\">\n",
+ quotedTc.constData());
+ outputString(buf.constData());
+
+ QTest::qt_asprintf(&buf, "<Environment>\n <QtVersion>%s</QtVersion>\n <QTestVersion>%s</QTestVersion>\n",
+ qVersion(), QTEST_VERSION_STR );
+ outputString(buf.constData());
+
+ QTest::qt_asprintf(&buf, "</Environment>\n");
+ outputString(buf.constData());
+
+ QTestBasicStreamer::output(element);
+
+ QTest::qt_asprintf(&buf, "</TestCase>\n");
+ outputString(buf.constData());
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtestxmlstreamer.h b/src/testlib/qtestxmlstreamer.h
new file mode 100644
index 0000000..a4611c2
--- /dev/null
+++ b/src/testlib/qtestxmlstreamer.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTXMLSTREAMER_H
+#define QTESXMLSTREAMER_H
+
+#include <QtTest/qtestbasicstreamer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+class QTestElement;
+class QTestElementAttribute;
+
+class QTestXmlStreamer: public QTestBasicStreamer
+{
+ public:
+ QTestXmlStreamer();
+ ~QTestXmlStreamer();
+
+ void formatStart(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void formatBeforeAttributes(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void output(QTestElement *element) const;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/testlib/qtestxunitstreamer.cpp b/src/testlib/qtestxunitstreamer.cpp
new file mode 100644
index 0000000..cb97267
--- /dev/null
+++ b/src/testlib/qtestxunitstreamer.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestxunitstreamer.h"
+#include "qtestelement.h"
+
+#include "QtTest/private/qtestlog_p.h"
+#include "QtTest/private/qtestresult_p.h"
+#include "QtTest/private/qxmltestlogger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QTestXunitStreamer::QTestXunitStreamer()
+ :QTestBasicStreamer()
+{}
+
+QTestXunitStreamer::~QTestXunitStreamer()
+{}
+
+void QTestXunitStreamer::indentForElement(const QTestElement* element, char* buf, int size)
+{
+ if (size == 0) return;
+
+ buf[0] = 0;
+
+ if (!element) return;
+
+ char* endbuf = buf + size;
+ element = element->parentElement();
+ while (element && buf+2 < endbuf) {
+ *(buf++) = ' ';
+ *(buf++) = ' ';
+ *buf = 0;
+ element = element->parentElement();
+ }
+}
+
+void QTestXunitStreamer::formatStart(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted )
+ return;
+
+ char indent[20];
+ indentForElement(element, indent, sizeof(indent));
+
+ // Errors are written as CDATA within system-err, comments elsewhere
+ if (element->elementType() == QTest::LET_Error) {
+ if (element->parentElement()->elementType() == QTest::LET_SystemError) {
+ QTest::qt_asprintf(formatted, "<![CDATA[");
+ } else {
+ QTest::qt_asprintf(formatted, "%s<!--", indent);
+ }
+ return;
+ }
+
+ QTest::qt_asprintf(formatted, "%s<%s", indent, element->elementName());
+}
+
+void QTestXunitStreamer::formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if (!element || !formatted )
+ return;
+
+ if (!element->childElements()){
+ formatted->data()[0] = '\0';
+ return;
+ }
+
+ char indent[20];
+ indentForElement(element, indent, sizeof(indent));
+
+ QTest::qt_asprintf(formatted, "%s</%s>\n", indent, element->elementName());
+}
+
+void QTestXunitStreamer::formatAttributes(const QTestElement* element, const QTestElementAttribute *attribute, QTestCharBuffer *formatted) const
+{
+ if(!attribute || !formatted )
+ return;
+
+ QTest::AttributeIndex attrindex = attribute->index();
+
+ // For errors within system-err, we only want to output `message'
+ if (element && element->elementType() == QTest::LET_Error
+ && element->parentElement()->elementType() == QTest::LET_SystemError) {
+
+ if (attrindex != QTest::AI_Description) return;
+
+ QXmlTestLogger::xmlCdata(formatted, attribute->value());
+ return;
+ }
+
+ char const* key = 0;
+ if (attrindex == QTest::AI_Description)
+ key = "message";
+ else if (attrindex != QTest::AI_File && attrindex != QTest::AI_Line)
+ key = attribute->name();
+
+ if (key) {
+ QTestCharBuffer quotedValue;
+ QXmlTestLogger::xmlQuote(&quotedValue, attribute->value());
+ QTest::qt_asprintf(formatted, " %s=\"%s\"", key, quotedValue.constData());
+ } else {
+ formatted->data()[0] = '\0';
+ }
+}
+
+void QTestXunitStreamer::formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const
+{
+ if(!element || !formatted )
+ return;
+
+ // Errors are written as CDATA within system-err, comments elsewhere
+ if (element->elementType() == QTest::LET_Error) {
+ if (element->parentElement()->elementType() == QTest::LET_SystemError) {
+ QTest::qt_asprintf(formatted, "]]>\n");
+ } else {
+ QTest::qt_asprintf(formatted, " -->\n");
+ }
+ return;
+ }
+
+ if(!element->childElements())
+ QTest::qt_asprintf(formatted, "/>\n");
+ else
+ QTest::qt_asprintf(formatted, ">\n");
+}
+
+void QTestXunitStreamer::output(QTestElement *element) const
+{
+ outputString("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+ QTestBasicStreamer::output(element);
+}
+
+void QTestXunitStreamer::outputElements(QTestElement *element, bool) const
+{
+ QTestCharBuffer buf;
+ bool hasChildren;
+ /*
+ Elements are in reverse order of occurrence, so start from the end and work
+ our way backwards.
+ */
+ while (element && element->nextElement()) {
+ element = element->nextElement();
+ }
+ while (element) {
+ hasChildren = element->childElements();
+
+ if(element->elementType() != QTest::LET_Benchmark){
+ formatStart(element, &buf);
+ outputString(buf.data());
+
+ formatBeforeAttributes(element, &buf);
+ outputString(buf.data());
+
+ outputElementAttributes(element, element->attributes());
+
+ formatAfterAttributes(element, &buf);
+ outputString(buf.data());
+
+ if(hasChildren)
+ outputElements(element->childElements(), true);
+
+ formatEnd(element, &buf);
+ outputString(buf.data());
+ }
+ element = element->previousElement();
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtestxunitstreamer.h b/src/testlib/qtestxunitstreamer.h
new file mode 100644
index 0000000..22cabec
--- /dev/null
+++ b/src/testlib/qtestxunitstreamer.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTXUNITSTREAMER_H
+#define QTESTXUNITSTREAMER_H
+
+#include <QtTest/qtestbasicstreamer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Test)
+
+class QTestLogger;
+
+class QTestXunitStreamer: public QTestBasicStreamer
+{
+ public:
+ QTestXunitStreamer();
+ ~QTestXunitStreamer();
+
+ void formatStart(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void formatEnd(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void formatAfterAttributes(const QTestElement *element, QTestCharBuffer *formatted) const;
+ void formatAttributes(const QTestElement *element, const QTestElementAttribute *attribute, QTestCharBuffer *formatted) const;
+ void output(QTestElement *element) const;
+ void outputElements(QTestElement *element, bool isChildElement = false) const;
+
+ private:
+ void displayXunitXmlHeader() const;
+ static void indentForElement(const QTestElement* element, char* buf, int size);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp
index ab141b6..fac3663 100644
--- a/src/testlib/qxmltestlogger.cpp
+++ b/src/testlib/qxmltestlogger.cpp
@@ -46,6 +46,7 @@
#include "QtTest/private/qxmltestlogger_p.h"
#include "QtTest/private/qtestresult_p.h"
#include "QtTest/private/qbenchmark_p.h"
+#include "QtTest/qtestcase.h"
QT_BEGIN_NAMESPACE
@@ -90,36 +91,36 @@ namespace QTest {
}
-QXmlTestLogger::QXmlTestLogger(XmlMode mode ):
- xmlmode(mode)
+QXmlTestLogger::QXmlTestLogger(XmlMode mode )
+ :xmlmode(mode)
{
}
QXmlTestLogger::~QXmlTestLogger()
{
-
}
-
void QXmlTestLogger::startLogging()
{
QAbstractTestLogger::startLogging();
- char buf[1024];
+ QTestCharBuffer buf;
if (xmlmode == QXmlTestLogger::Complete) {
- QTest::qt_snprintf(buf, sizeof(buf),
+ QTestCharBuffer quotedTc;
+ xmlQuote(&quotedTc, QTestResult::currentTestObjectName());
+ QTest::qt_asprintf(&buf,
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
- "<TestCase name=\"%s\">\n", QTestResult::currentTestObjectName());
- outputString(buf);
+ "<TestCase name=\"%s\">\n", quotedTc.constData());
+ outputString(buf.constData());
}
- QTest::qt_snprintf(buf, sizeof(buf),
+ QTest::qt_asprintf(&buf,
"<Environment>\n"
" <QtVersion>%s</QtVersion>\n"
" <QTestVersion>"QTEST_VERSION_STR"</QTestVersion>\n"
"</Environment>\n", qVersion());
- outputString(buf);
+ outputString(buf.constData());
}
void QXmlTestLogger::stopLogging()
@@ -133,9 +134,11 @@ void QXmlTestLogger::stopLogging()
void QXmlTestLogger::enterTestFunction(const char *function)
{
- char buf[1024];
- QTest::qt_snprintf(buf, sizeof(buf), "<TestFunction name=\"%s\">\n", function);
- outputString(buf);
+ QTestCharBuffer buf;
+ QTestCharBuffer quotedFunction;
+ xmlQuote(&quotedFunction, function);
+ QTest::qt_asprintf(&buf, "<TestFunction name=\"%s\">\n", quotedFunction.constData());
+ outputString(buf.constData());
}
void QXmlTestLogger::leaveTestFunction()
@@ -158,18 +161,18 @@ static const char *incidentFormatString(bool noDescription, bool noTag)
return "<Incident type=\"%s\" file=\"%s\" line=\"%d\" />\n";
else
return "<Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
- "</Incident>\n";
+ " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
+ "</Incident>\n";
} else {
if (noTag)
return "<Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <Description><![CDATA[%s%s%s%s]]></Description>\n"
- "</Incident>\n";
+ " <Description><![CDATA[%s%s%s%s]]></Description>\n"
+ "</Incident>\n";
else
return "<Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
- " <Description><![CDATA[%s]]></Description>\n"
- "</Incident>\n";
+ " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
+ " <Description><![CDATA[%s]]></Description>\n"
+ "</Incident>\n";
}
}
@@ -185,80 +188,256 @@ static const char *messageFormatString(bool noDescription, bool noTag)
return "<Message type=\"%s\" file=\"%s\" line=\"%d\" />\n";
else
return "<Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
- "</Message>\n";
+ " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
+ "</Message>\n";
} else {
if (noTag)
return "<Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <Description><![CDATA[%s%s%s%s]]></Description>\n"
- "</Message>\n";
+ " <Description><![CDATA[%s%s%s%s]]></Description>\n"
+ "</Message>\n";
else
return "<Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
- " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
- " <Description><![CDATA[%s]]></Description>\n"
- "</Message>\n";
+ " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
+ " <Description><![CDATA[%s]]></Description>\n"
+ "</Message>\n";
}
}
} // namespace
void QXmlTestLogger::addIncident(IncidentTypes type, const char *description,
- const char *file, int line)
+ const char *file, int line)
{
- char buf[1536];
+ QTestCharBuffer buf;
const char *tag = QTestResult::currentDataTag();
const char *gtag = QTestResult::currentGlobalDataTag();
const char *filler = (tag && gtag) ? ":" : "";
const bool notag = QTest::isEmpty(tag) && QTest::isEmpty(gtag);
- QTest::qt_snprintf(buf, sizeof(buf),
+ QTestCharBuffer quotedFile;
+ QTestCharBuffer cdataGtag;
+ QTestCharBuffer cdataTag;
+ QTestCharBuffer cdataDescription;
+
+ xmlQuote(&quotedFile, file);
+ xmlCdata(&cdataGtag, gtag);
+ xmlCdata(&cdataTag, tag);
+ xmlCdata(&cdataDescription, description);
+
+ QTest::qt_asprintf(&buf,
QTest::incidentFormatString(QTest::isEmpty(description), notag),
QTest::xmlIncidentType2String(type),
- file ? file : "", line,
- gtag ? gtag : "",
+ quotedFile.constData(), line,
+ cdataGtag.constData(),
filler,
- tag ? tag : "",
- description ? description : "");
+ cdataTag.constData(),
+ cdataDescription.constData());
- outputString(buf);
+ outputString(buf.constData());
}
void QXmlTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
{
- char buf[1536];
- QTest::qt_snprintf(
- buf, sizeof(buf),
+ QTestCharBuffer buf;
+ QTestCharBuffer quotedMetric;
+ QTestCharBuffer quotedTag;
+
+ xmlQuote(&quotedMetric,
+ QBenchmarkGlobalData::current->measurer->metricText().toAscii().constData());
+ xmlQuote(&quotedTag, result.context.tag.toAscii().constData());
+
+ QTest::qt_asprintf(
+ &buf,
QTest::benchmarkResultFormatString(),
- QBenchmarkGlobalData::current->measurer->metricText().toAscii().data(),
- result.context.tag.toAscii().data(),
+ quotedMetric.constData(),
+ quotedTag.constData(),
QByteArray::number(result.value).constData(), //no 64-bit qt_snprintf support
- result.iterations);
- outputString(buf);
+ result.iterations);
+ outputString(buf.constData());
}
void QXmlTestLogger::addMessage(MessageTypes type, const char *message,
const char *file, int line)
{
- char buf[1536];
- char msgbuf[1024];
+ QTestCharBuffer buf;
const char *tag = QTestResult::currentDataTag();
const char *gtag = QTestResult::currentGlobalDataTag();
const char *filler = (tag && gtag) ? ":" : "";
const bool notag = QTest::isEmpty(tag) && QTest::isEmpty(gtag);
- QTest::qt_snprintf(msgbuf, sizeof(msgbuf), "%s",
- message ? message : "");
+ QTestCharBuffer quotedFile;
+ QTestCharBuffer cdataGtag;
+ QTestCharBuffer cdataTag;
+ QTestCharBuffer cdataDescription;
+
+ xmlQuote(&quotedFile, file);
+ xmlCdata(&cdataGtag, gtag);
+ xmlCdata(&cdataTag, tag);
+ xmlCdata(&cdataDescription, message);
- QTest::qt_snprintf(buf, sizeof(buf),
+ QTest::qt_asprintf(&buf,
QTest::messageFormatString(QTest::isEmpty(message), notag),
QTest::xmlMessageType2String(type),
- file ? file : "", line,
- gtag ? gtag : "",
+ quotedFile.constData(), line,
+ cdataGtag.constData(),
filler,
- tag ? tag : "",
- msgbuf);
+ cdataTag.constData(),
+ cdataDescription.constData());
+
+ outputString(buf.constData());
+}
- outputString(buf);
+/*
+ Copy up to n characters from the src string into dest, escaping any special
+ XML characters as necessary so that dest is suitable for use in an XML
+ quoted attribute string.
+*/
+int QXmlTestLogger::xmlQuote(QTestCharBuffer* destBuf, char const* src, size_t n)
+{
+ if (n == 0) return 0;
+
+ char *dest = destBuf->data();
+ *dest = 0;
+ if (!src) return 0;
+
+ char* begin = dest;
+ char* end = dest + n;
+
+ while (dest < end) {
+ switch (*src) {
+
+#define MAP_ENTITY(chr, ent) \
+ case chr: \
+ if (dest + sizeof(ent) < end) { \
+ strcpy(dest, ent); \
+ dest += sizeof(ent) - 1; \
+ } \
+ else { \
+ *dest = 0; \
+ return (dest+sizeof(ent)-begin); \
+ } \
+ ++src; \
+ break;
+
+ MAP_ENTITY('>', "&gt;");
+ MAP_ENTITY('<', "&lt;");
+ MAP_ENTITY('\'', "&apos;");
+ MAP_ENTITY('"', "&quot;");
+ MAP_ENTITY('&', "&amp;");
+
+ // not strictly necessary, but allows handling of comments without
+ // having to explicitly look for `--'
+ MAP_ENTITY('-', "&#x002D;");
+
+#undef MAP_ENTITY
+
+ case 0:
+ *dest = 0;
+ return (dest-begin);
+
+ default:
+ *dest = *src;
+ ++dest;
+ ++src;
+ break;
+ }
+ }
+
+ // If we get here, dest was completely filled (dest == end)
+ *(dest-1) = 0;
+ return (dest-begin);
+}
+
+/*
+ Copy up to n characters from the src string into dest, escaping any
+ special strings such that dest is suitable for use in an XML CDATA section.
+*/
+int QXmlTestLogger::xmlCdata(QTestCharBuffer *destBuf, char const* src, size_t n)
+{
+ if (!n) return 0;
+
+ char *dest = destBuf->data();
+
+ if (!src || n == 1) {
+ *dest = 0;
+ return 0;
+ }
+
+ static char const CDATA_END[] = "]]>";
+ static char const CDATA_END_ESCAPED[] = "]]]><![CDATA[]>";
+
+ char* begin = dest;
+ char* end = dest + n;
+ while (dest < end) {
+ if (!*src) {
+ *dest = 0;
+ return (dest-begin);
+ }
+
+ if (!strncmp(src, CDATA_END, sizeof(CDATA_END)-1)) {
+ if (dest + sizeof(CDATA_END_ESCAPED) < end) {
+ strcpy(dest, CDATA_END_ESCAPED);
+ src += sizeof(CDATA_END)-1;
+ dest += sizeof(CDATA_END_ESCAPED) - 1;
+ }
+ else {
+ *dest = 0;
+ return (dest+sizeof(CDATA_END_ESCAPED)-begin);
+ }
+ continue;
+ }
+
+ *dest = *src;
+ ++src;
+ ++dest;
+ }
+
+ // If we get here, dest was completely filled (dest == end)
+ *(dest-1) = 0;
+ return (dest-begin);
+}
+
+typedef int (*StringFormatFunction)(QTestCharBuffer*,char const*,size_t);
+
+/*
+ A wrapper for string functions written to work with a fixed size buffer so they can be called
+ with a dynamically allocated buffer.
+*/
+int allocateStringFn(QTestCharBuffer* str, char const* src, StringFormatFunction func)
+{
+ static const int MAXSIZE = 1024*1024*2;
+
+ int size = str->size();
+
+ int res = 0;
+
+ for (;;) {
+ res = func(str, src, size);
+ str->data()[size - 1] = '\0';
+ if (res < size) {
+ // We succeeded or fatally failed
+ break;
+ }
+ // buffer wasn't big enough, try again
+ size *= 2;
+ if (size > MAXSIZE) {
+ break;
+ }
+ if (!str->reset(size))
+ break; // ran out of memory - bye
+ }
+
+ return res;
+}
+
+int QXmlTestLogger::xmlQuote(QTestCharBuffer* str, char const* src)
+{
+ return allocateStringFn(str, src, QXmlTestLogger::xmlQuote);
+}
+
+int QXmlTestLogger::xmlCdata(QTestCharBuffer* str, char const* src)
+{
+ return allocateStringFn(str, src, QXmlTestLogger::xmlCdata);
}
QT_END_NAMESPACE
diff --git a/src/testlib/qxmltestlogger_p.h b/src/testlib/qxmltestlogger_p.h
index 89fe6b2..b0e7792 100644
--- a/src/testlib/qxmltestlogger_p.h
+++ b/src/testlib/qxmltestlogger_p.h
@@ -79,6 +79,11 @@ public:
void addMessage(MessageTypes type, const char *message,
const char *file = 0, int line = 0);
+ static int xmlCdata(QTestCharBuffer *dest, char const* src);
+ static int xmlQuote(QTestCharBuffer *dest, char const* src);
+ static int xmlCdata(QTestCharBuffer *dest, char const* src, size_t n);
+ static int xmlQuote(QTestCharBuffer *dest, char const* src, size_t n);
+
private:
XmlMode xmlmode;
};
diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro
index 90bd92d..f68ff35 100644
--- a/src/testlib/testlib.pro
+++ b/src/testlib/testlib.pro
@@ -1,27 +1,80 @@
-TARGET = QtTest
+TARGET = QtTest
QPRO_PWD = $$PWD
-QT = core
+QT = core
INCLUDEPATH += .
-
-unix:!embedded {
- QMAKE_PKGCONFIG_DESCRIPTION = Qt Unit Testing Library
- QMAKE_PKGCONFIG_REQUIRES = QtCore
-}
+unix:!embedded:QMAKE_PKGCONFIG_DESCRIPTION = Qt \
+ Unit \
+ Testing \
+ Library
# Input
-HEADERS = qtest_global.h qtestcase.h qtestdata.h qtesteventloop.h
-SOURCES = qtestcase.cpp qtestlog.cpp qtesttable.cpp qtestdata.cpp qtestresult.cpp qasciikey.cpp qplaintestlogger.cpp qxmltestlogger.cpp qsignaldumper.cpp qabstracttestlogger.cpp qbenchmark.cpp qbenchmarkmeasurement.cpp qbenchmarkvalgrind.cpp qbenchmarkevent.cpp
-
-DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII QTESTLIB_MAKEDLL QT_NO_DATASTREAM
-
-wince*:{
- LIBS += libcmt.lib corelibc.lib ole32.lib oleaut32.lib uuid.lib commctrl.lib coredll.lib winsock.lib
-}
-
-mac {
- LIBS += -framework IOKit -framework Security
-}
-
+HEADERS = qbenchmark.h \
+ qsignalspy.h \
+ qtestaccessible.h \
+ qtestassert.h \
+ qtestbasicstreamer.h \
+ qtestcase.h \
+ qtestcoreelement.h \
+ qtestcorelist.h \
+ qtestdata.h \
+ qtestelementattribute.h \
+ qtestelement.h \
+ qtestevent.h \
+ qtesteventloop.h \
+ qtestfilelogger.h \
+ qtest_global.h \
+ qtest_gui.h \
+ qtest.h \
+ qtestkeyboard.h \
+ qtestlightxmlstreamer.h \
+ qtestmouse.h \
+ qtestspontaneevent.h \
+ qtestsystem.h \
+ qtesttouch.h \
+ qtestxmlstreamer.h \
+ qtestxunitstreamer.h
+SOURCES = qtestcase.cpp \
+ qtestlog.cpp \
+ qtesttable.cpp \
+ qtestdata.cpp \
+ qtestresult.cpp \
+ qasciikey.cpp \
+ qplaintestlogger.cpp \
+ qxmltestlogger.cpp \
+ qsignaldumper.cpp \
+ qabstracttestlogger.cpp \
+ qbenchmark.cpp \
+ qbenchmarkmeasurement.cpp \
+ qbenchmarkvalgrind.cpp \
+ qbenchmarkevent.cpp \
+ qtestelement.cpp \
+ qtestelementattribute.cpp \
+ qtestbasicstreamer.cpp \
+ qtestxunitstreamer.cpp \
+ qtestxmlstreamer.cpp \
+ qtestlightxmlstreamer.cpp \
+ qtestlogger.cpp \
+ qtestfilelogger.cpp
+DEFINES *= QT_NO_CAST_TO_ASCII \
+ QT_NO_CAST_FROM_ASCII \
+ QTESTLIB_MAKEDLL \
+ QT_NO_DATASTREAM
+embedded:QMAKE_CXXFLAGS += -fno-rtti
+wince*::LIBS += libcmt.lib \
+ corelibc.lib \
+ ole32.lib \
+ oleaut32.lib \
+ uuid.lib \
+ commctrl.lib \
+ coredll.lib \
+ winsock.lib
+mac:LIBS += -framework IOKit \
+ -framework ApplicationServices \
+ -framework Security
include(../qbase.pri)
QMAKE_TARGET_PRODUCT = QTestLib
-QMAKE_TARGET_DESCRIPTION = Qt Unit Testing Library
+QMAKE_TARGET_DESCRIPTION = Qt \
+ Unit \
+ Testing \
+ Library
+symbian:TARGET.UID3=0x2001B2DF