summaryrefslogtreecommitdiffstats
path: root/src/testlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/testlib')
-rw-r--r--src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp11
-rw-r--r--src/testlib/qbenchmark_p.h4
-rw-r--r--src/testlib/qteamcitylogger.cpp23
-rw-r--r--src/testlib/qtestcase.cpp87
-rw-r--r--src/testlib/qtestcase.h6
-rw-r--r--src/testlib/qtestsystem.h4
6 files changed, 110 insertions, 25 deletions
diff --git a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
index 2c57550c3d..01ee8102f4 100644
--- a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
+++ b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
@@ -208,6 +208,17 @@ void myTestFunction_data()
//! [20]
+//! [addRow]
+void myTestFunction_data()
+{
+ QTest::addColumn<int>("input");
+ QTest::addColumn<QString>("output");
+ QTest::addRow("%d", 0) << 0 << QString("0");
+ QTest::addRow("%d", 1) << 1 << QString("1");
+}
+//! [addRow]
+
+
//! [21]
void myTestFunction_data() {
QTest::addColumn<int>("intval");
diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h
index 0b16f624df..797071d7a4 100644
--- a/src/testlib/qbenchmark_p.h
+++ b/src/testlib/qbenchmark_p.h
@@ -91,8 +91,8 @@ struct QBenchmarkContext
QString toString() const
{
- QString s = QString::fromLatin1("%1,%2,%3").arg(slotName).arg(tag).arg(checkpointIndex);
- return s;
+ return QString::fromLatin1("%1,%2,%3")
+ .arg(slotName, tag, QString::number(checkpointIndex));
}
QBenchmarkContext() : checkpointIndex(-1) {}
diff --git a/src/testlib/qteamcitylogger.cpp b/src/testlib/qteamcitylogger.cpp
index 1d700d8201..81c2499bcb 100644
--- a/src/testlib/qteamcitylogger.cpp
+++ b/src/testlib/qteamcitylogger.cpp
@@ -167,17 +167,16 @@ void QTeamCityLogger::addIncident(IncidentTypes type, const char *description,
messageText += QString(QLatin1String(" |[Loc: %1(%2)|]")).arg(QString::fromUtf8(file)).arg(line);
buf = QString(QLatin1String("##teamcity[testFailed name='%1' message='%2' details='%3']\n"))
- .arg(tmpFuncName)
- .arg(messageText)
- .arg(detailedText);
+ .arg(tmpFuncName,
+ messageText,
+ detailedText);
outputString(qPrintable(buf));
}
if (!pendingMessages.isEmpty()) {
buf = QString(QLatin1String("##teamcity[testStdOut name='%1' out='%2']\n"))
- .arg(tmpFuncName)
- .arg(pendingMessages);
+ .arg(tmpFuncName, pendingMessages);
outputString(qPrintable(buf));
@@ -209,8 +208,7 @@ void QTeamCityLogger::addMessage(MessageTypes type, const QString &message,
escapedMessage.append(QString(QLatin1String(" |[Loc: %1(%2)|]")).arg(QString::fromUtf8(file)).arg(line));
buf = QString(QLatin1String("##teamcity[testIgnored name='%1' message='%2']\n"))
- .arg(escapedTestFuncName())
- .arg(escapedMessage);
+ .arg(escapedTestFuncName(), escapedMessage);
outputString(qPrintable(buf));
}
@@ -259,10 +257,7 @@ QString QTeamCityLogger::escapedTestFuncName() const
: "UnknownTestFunc";
const char *tag = QTestResult::currentDataTag() ? QTestResult::currentDataTag() : "";
- QString str = QString(QLatin1String("%1(%2)")).arg(QString::fromUtf8(fn)).arg(QString::fromUtf8(tag));
- str = tcEscapedString(str);
-
- return str;
+ return tcEscapedString(QString::asprintf("%s(%s)", fn, tag));
}
void QTeamCityLogger::addPendingMessage(const char *type, const QString &msg, const char *file, int line)
@@ -274,16 +269,14 @@ void QTeamCityLogger::addPendingMessage(const char *type, const QString &msg, co
if (file) {
pendMessage += QString(QLatin1String("%1 |[Loc: %2(%3)|]: %4"))
- .arg(QString::fromUtf8(type))
- .arg(QString::fromUtf8(file))
+ .arg(QString::fromUtf8(type), QString::fromUtf8(file))
.arg(line)
.arg(msg);
}
else {
pendMessage += QString(QLatin1String("%1: %2"))
- .arg(QString::fromUtf8(type))
- .arg(msg);
+ .arg(QString::fromUtf8(type), msg);
}
pendingMessages.append(pendMessage);
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 31ffb36690..19d135e15f 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -99,11 +99,16 @@
#include <errno.h>
#include <signal.h>
#include <time.h>
-#include <sys/resource.h>
+# if !defined(Q_OS_INTEGRITY)
+# include <sys/resource.h>
+# endif
#endif
#if defined(Q_OS_MACX)
#include <IOKit/pwr_mgt/IOPMLib.h>
+#include <mach/task.h>
+#include <mach/mach_init.h>
+#include <CoreFoundation/CFPreferences.h>
#endif
#include <vector>
@@ -138,6 +143,40 @@ static bool debuggerPresent()
return pid != 0;
#elif defined(Q_OS_WIN)
return IsDebuggerPresent();
+#elif defined(Q_OS_MACOS)
+ auto equals = [](CFStringRef str1, CFStringRef str2) -> bool {
+ return CFStringCompare(str1, str2, kCFCompareCaseInsensitive) == kCFCompareEqualTo;
+ };
+
+ // Check if there is an exception handler for the process:
+ mach_msg_type_number_t portCount = 0;
+ exception_mask_t masks[EXC_TYPES_COUNT];
+ mach_port_t ports[EXC_TYPES_COUNT];
+ exception_behavior_t behaviors[EXC_TYPES_COUNT];
+ thread_state_flavor_t flavors[EXC_TYPES_COUNT];
+ exception_mask_t mask = EXC_MASK_ALL & ~(EXC_MASK_RESOURCE | EXC_MASK_GUARD);
+ kern_return_t result = task_get_exception_ports(mach_task_self(), mask, masks, &portCount,
+ ports, behaviors, flavors);
+ if (result == KERN_SUCCESS) {
+ for (mach_msg_type_number_t portIndex = 0; portIndex < portCount; ++portIndex) {
+ if (MACH_PORT_VALID(ports[portIndex])) {
+ return true;
+ }
+ }
+ }
+
+ // Ok, no debugger attached. So, let's see if CrashReporter will throw up a dialog. If so, we
+ // leave it to the OS to do the stack trace.
+ CFStringRef crashReporterType = static_cast<CFStringRef>(
+ CFPreferencesCopyAppValue(CFSTR("DialogType"), CFSTR("com.apple.CrashReporter")));
+ if (crashReporterType == nullptr)
+ return true;
+
+ const bool createsStackTrace =
+ !equals(crashReporterType, CFSTR("server")) &&
+ !equals(crashReporterType, CFSTR("none"));
+ CFRelease(crashReporterType);
+ return createsStackTrace;
#else
// TODO
return false;
@@ -149,7 +188,7 @@ static void disableCoreDump()
bool ok = false;
const int disableCoreDump = qEnvironmentVariableIntValue("QTEST_DISABLE_CORE_DUMP", &ok);
if (ok && disableCoreDump == 1) {
-#if defined(Q_OS_UNIX)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
struct rlimit limit;
limit.rlim_cur = 0;
limit.rlim_max = 0;
@@ -2061,7 +2100,7 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co
// 5. Try current directory
if (found.isEmpty()) {
- QString candidate = QString::fromLatin1("%1/%2").arg(QDir::currentPath()).arg(base);
+ const QString candidate = QDir::currentPath() + QLatin1Char('/') + base;
if (QFileInfo::exists(candidate))
found = candidate;
}
@@ -2160,6 +2199,48 @@ QTestData &QTest::newRow(const char *dataTag)
return *tbl->newData(dataTag);
}
+/*!
+ \since 5.9
+
+ Appends a new row to the current test data. The function's arguments are passed
+ to qsnprintf() for formatting according to \a format. See the qvsnprintf()
+ documentation for caveats and limitations.
+
+ The formatted string will appear as the name of this test data in the test output.
+
+ Returns a QTestData reference that can be used to stream in data.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp addRow
+
+ \b {Note:} This function can only be used in a test's data function
+ that is invoked by the test framework.
+
+ See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
+ a more extensive example.
+
+ \sa addColumn(), QFETCH()
+*/
+QTestData &QTest::addRow(const char *format, ...)
+{
+ QTEST_ASSERT_X(format, "QTest::addRow()", "Format string cannot be null");
+ QTestTable *tbl = QTestTable::currentTestTable();
+ QTEST_ASSERT_X(tbl, "QTest::addRow()", "Cannot add testdata outside of a _data slot.");
+ QTEST_ASSERT_X(tbl->elementCount(), "QTest::addRow()", "Must add columns before attempting to add rows.");
+
+ char buf[1024];
+
+ va_list va;
+ va_start(va, format);
+ // we don't care about failures, we accept truncation, as well as trailing garbage.
+ // Names with more than 1K characters are nonsense, anyway.
+ (void)qvsnprintf(buf, sizeof buf, format, va);
+ buf[sizeof buf - 1] = '\0';
+ va_end(va);
+
+ return *tbl->newData(buf);
+}
+
/*! \fn void QTest::addColumn(const char *name, T *dummy = 0)
Adds a column with type \c{T} to the current test data.
diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h
index 57e0486686..a7e825396a 100644
--- a/src/testlib/qtestcase.h
+++ b/src/testlib/qtestcase.h
@@ -51,7 +51,6 @@
#include <string.h>
-#include <type_traits>
#ifndef QT_NO_EXCEPTIONS
# include <exception>
#endif // QT_NO_EXCEPTIONS
@@ -240,14 +239,14 @@ namespace QTest
namespace Internal {
template<typename T> // Output registered enums
- inline typename QtPrivate::QEnableIf<QtPrivate::IsQEnumHelper<T>::Value, char*>::Type toString(T e)
+ inline typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, char*>::type toString(T e)
{
QMetaEnum me = QMetaEnum::fromType<T>();
return qstrdup(me.valueToKey(int(e))); // int cast is necessary to support enum classes
}
template <typename T> // Fallback
- inline typename QtPrivate::QEnableIf<!QtPrivate::IsQEnumHelper<T>::Value, char*>::Type toString(const T &)
+ inline typename std::enable_if<!QtPrivate::IsQEnumHelper<T>::Value, char*>::type toString(const T &)
{
return Q_NULLPTR;
}
@@ -318,6 +317,7 @@ namespace QTest
addColumnInternal(qMetaTypeId<T>(), name);
}
Q_TESTLIB_EXPORT QTestData &newRow(const char *dataTag);
+ Q_TESTLIB_EXPORT QTestData &addRow(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
template <typename T>
inline bool qCompare(T const &t1, T const &t2, const char *actual, const char *expected,
diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h
index 08e240e25a..4c611aab6b 100644
--- a/src/testlib/qtestsystem.h
+++ b/src/testlib/qtestsystem.h
@@ -116,14 +116,14 @@ namespace QTest
#ifdef QT_WIDGETS_LIB
inline static bool qWaitForWindowActive(QWidget *widget, int timeout = 1000)
{
- if (QWindow *window = widget->windowHandle())
+ if (QWindow *window = widget->window()->windowHandle())
return qWaitForWindowActive(window, timeout);
return false;
}
inline static bool qWaitForWindowExposed(QWidget *widget, int timeout = 1000)
{
- if (QWindow *window = widget->windowHandle())
+ if (QWindow *window = widget->window()->windowHandle())
return qWaitForWindowExposed(window, timeout);
return false;
}