diff options
Diffstat (limited to 'src/testlib/qtestcase.cpp')
-rw-r--r-- | src/testlib/qtestcase.cpp | 87 |
1 files changed, 84 insertions, 3 deletions
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. |