summaryrefslogtreecommitdiffstats
path: root/src/testlib
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@qt.io>2019-04-16 16:32:08 +0200
committerTobias Hunger <tobias.hunger@qt.io>2019-04-16 16:32:08 +0200
commit6630937e63ae5797487b86743a7733c8ae5cc42c (patch)
tree3d53dacf6430f9099e1fb20835881205de674961 /src/testlib
parent37ed6dae00640f9cc980ffda05347c12a7eb5d7e (diff)
parentc7af193d2e49e9f10b86262e63d8d13abf72b5cf (diff)
Merge commit 'dev' into 'wip/cmake-merge'
Diffstat (limited to 'src/testlib')
-rw-r--r--src/testlib/3rdparty/qt_attribution.json2
-rw-r--r--src/testlib/3rdparty/valgrind_p.h269
-rw-r--r--src/testlib/configure.cmake5
-rw-r--r--src/testlib/configure.json6
-rw-r--r--src/testlib/doc/qttestlib.qdocconf10
-rw-r--r--src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp63
-rw-r--r--src/testlib/doc/src/qttest-index.qdoc15
-rw-r--r--src/testlib/qabstractitemmodeltester.h4
-rw-r--r--src/testlib/qabstracttestlogger_p.h10
-rw-r--r--src/testlib/qappletestlogger.cpp142
-rw-r--r--src/testlib/qappletestlogger_p.h18
-rw-r--r--src/testlib/qbenchmarkevent.cpp4
-rw-r--r--src/testlib/qbenchmarkevent_p.h4
-rw-r--r--src/testlib/qbenchmarkvalgrind.cpp18
-rw-r--r--src/testlib/qcsvbenchmarklogger_p.h4
-rw-r--r--src/testlib/qplaintestlogger.cpp4
-rw-r--r--src/testlib/qplaintestlogger_p.h6
-rw-r--r--src/testlib/qsignaldumper.cpp11
-rw-r--r--src/testlib/qsignalspy.h2
-rw-r--r--src/testlib/qsignalspy.qdoc4
-rw-r--r--src/testlib/qtaptestlogger.cpp17
-rw-r--r--src/testlib/qtaptestlogger_p.h4
-rw-r--r--src/testlib/qteamcitylogger.cpp6
-rw-r--r--src/testlib/qteamcitylogger_p.h4
-rw-r--r--src/testlib/qtest.h67
-rw-r--r--src/testlib/qtestblacklist.cpp1
-rw-r--r--src/testlib/qtestcase.cpp382
-rw-r--r--src/testlib/qtestcase.h27
-rw-r--r--src/testlib/qtestcase.qdoc24
-rw-r--r--src/testlib/qtestcoreelement_p.h10
-rw-r--r--src/testlib/qtestcorelist_p.h25
-rw-r--r--src/testlib/qtestevent.qdoc2
-rw-r--r--src/testlib/qtestkeyboard.h4
-rw-r--r--src/testlib/qtestlog.cpp216
-rw-r--r--src/testlib/qtestlog_p.h13
-rw-r--r--src/testlib/qtestresult.cpp13
-rw-r--r--src/testlib/qxmltestlogger.cpp13
-rw-r--r--src/testlib/qxmltestlogger_p.h4
-rw-r--r--src/testlib/qxunittestlogger.cpp13
-rw-r--r--src/testlib/qxunittestlogger_p.h4
-rw-r--r--src/testlib/selfcover.pri28
-rw-r--r--src/testlib/testlib.pro18
42 files changed, 921 insertions, 575 deletions
diff --git a/src/testlib/3rdparty/qt_attribution.json b/src/testlib/3rdparty/qt_attribution.json
index 734a74dbe1..4dd844c232 100644
--- a/src/testlib/3rdparty/qt_attribution.json
+++ b/src/testlib/3rdparty/qt_attribution.json
@@ -8,7 +8,7 @@
"Description": "An instrumentation framework for building dynamic analysis tools.",
"Homepage": "http://valgrind.org/",
- "Version": "3.13.0",
+ "Version": "3.14.0",
"License": "BSD 4-clause \"Original\" or \"Old\" License",
"LicenseId": "BSD-4-Clause",
"LicenseFile": "VALGRIND_LICENSE.txt",
diff --git a/src/testlib/3rdparty/valgrind_p.h b/src/testlib/3rdparty/valgrind_p.h
index 5aed0dfca5..577c8f05e5 100644
--- a/src/testlib/3rdparty/valgrind_p.h
+++ b/src/testlib/3rdparty/valgrind_p.h
@@ -89,7 +89,7 @@
|| (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
*/
#define __VALGRIND_MAJOR__ 3
-#define __VALGRIND_MINOR__ 13
+#define __VALGRIND_MINOR__ 14
#include <stdarg.h>
@@ -5687,15 +5687,17 @@ typedef
"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
"$25", "$31"
-/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
- long) == 4. */
+/* These CALL_FN_ macros assume that on mips64-linux,
+ sizeof(long long) == 8. */
+
+#define MIPS64_LONG2REG_CAST(x) ((long long)(long)x)
#define CALL_FN_W_v(lval, orig) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[1]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
+ volatile unsigned long long _argvec[1]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
__asm__ volatile( \
"ld $25, 0(%1)\n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
@@ -5704,16 +5706,16 @@ typedef
: /*in*/ "0" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_W(lval, orig, arg1) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[2]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
+ volatile unsigned long long _argvec[2]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
__asm__ volatile( \
"ld $4, 8(%1)\n\t" /* arg1*/ \
"ld $25, 0(%1)\n\t" /* target->t9 */ \
@@ -5723,17 +5725,17 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
+ volatile unsigned long long _argvec[3]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = _orig.nraddr; \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
__asm__ volatile( \
"ld $4, 8(%1)\n\t" \
"ld $5, 16(%1)\n\t" \
@@ -5744,18 +5746,19 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
+
#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[4]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
+ volatile unsigned long long _argvec[4]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = _orig.nraddr; \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
__asm__ volatile( \
"ld $4, 8(%1)\n\t" \
"ld $5, 16(%1)\n\t" \
@@ -5767,19 +5770,19 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[5]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
+ volatile unsigned long long _argvec[5]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
__asm__ volatile( \
"ld $4, 8(%1)\n\t" \
"ld $5, 16(%1)\n\t" \
@@ -5792,20 +5795,20 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[6]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
+ volatile unsigned long long _argvec[6]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
+ _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
__asm__ volatile( \
"ld $4, 8(%1)\n\t" \
"ld $5, 16(%1)\n\t" \
@@ -5819,21 +5822,21 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[7]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
+ volatile unsigned long long _argvec[7]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
+ _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
+ _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
__asm__ volatile( \
"ld $4, 8(%1)\n\t" \
"ld $5, 16(%1)\n\t" \
@@ -5848,23 +5851,23 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
arg7) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[8]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
+ volatile unsigned long long _argvec[8]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
+ _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
+ _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
+ _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
__asm__ volatile( \
"ld $4, 8(%1)\n\t" \
"ld $5, 16(%1)\n\t" \
@@ -5880,24 +5883,24 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
arg7,arg8) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[9]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
+ volatile unsigned long long _argvec[9]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
+ _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
+ _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
+ _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
+ _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
__asm__ volatile( \
"ld $4, 8(%1)\n\t" \
"ld $5, 16(%1)\n\t" \
@@ -5914,25 +5917,25 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
arg7,arg8,arg9) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[10]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
+ volatile unsigned long long _argvec[10]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
+ _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
+ _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
+ _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
+ _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
+ _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \
__asm__ volatile( \
"dsubu $29, $29, 8\n\t" \
"ld $4, 72(%1)\n\t" \
@@ -5953,26 +5956,26 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
arg7,arg8,arg9,arg10) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[11]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
+ volatile unsigned long long _argvec[11]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
+ _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
+ _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
+ _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
+ _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
+ _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \
+ _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \
__asm__ volatile( \
"dsubu $29, $29, 16\n\t" \
"ld $4, 72(%1)\n\t" \
@@ -5995,7 +5998,7 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
@@ -6003,20 +6006,20 @@ typedef
arg11) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[12]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
- _argvec[11] = (unsigned long)(arg11); \
+ volatile unsigned long long _argvec[12]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
+ _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
+ _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
+ _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
+ _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
+ _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \
+ _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \
+ _argvec[11] = MIPS64_LONG2REG_CAST(arg11); \
__asm__ volatile( \
"dsubu $29, $29, 24\n\t" \
"ld $4, 72(%1)\n\t" \
@@ -6041,7 +6044,7 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
@@ -6049,21 +6052,21 @@ typedef
arg11,arg12) \
do { \
volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[13]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
- _argvec[11] = (unsigned long)(arg11); \
- _argvec[12] = (unsigned long)(arg12); \
+ volatile unsigned long long _argvec[13]; \
+ volatile unsigned long long _res; \
+ _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \
+ _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \
+ _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \
+ _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \
+ _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \
+ _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \
+ _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \
+ _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \
+ _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \
+ _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \
+ _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \
+ _argvec[11] = MIPS64_LONG2REG_CAST(arg11); \
+ _argvec[12] = MIPS64_LONG2REG_CAST(arg12); \
__asm__ volatile( \
"dsubu $29, $29, 32\n\t" \
"ld $4, 72(%1)\n\t" \
@@ -6090,7 +6093,7 @@ typedef
: /*in*/ "r" (&_argvec[0]) \
: /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
- lval = (__typeof__(lval)) _res; \
+ lval = (__typeof__(lval)) (long)_res; \
} while (0)
#endif /* PLAT_mips64_linux */
diff --git a/src/testlib/configure.cmake b/src/testlib/configure.cmake
index 2509e11330..74d32e9dfc 100644
--- a/src/testlib/configure.cmake
+++ b/src/testlib/configure.cmake
@@ -14,6 +14,11 @@
#### Features
+qt_feature("testlib_selfcover" PUBLIC
+ LABEL "Coverage testing of testlib itself"
+ PURPOSE "Gauges how thoroughly testlib's selftest exercises testlib's code"
+ AUTODETECT OFF
+)
qt_feature("itemmodeltester" PUBLIC
LABEL "Tester for item models"
PURPOSE "Provides a utility to test item models."
diff --git a/src/testlib/configure.json b/src/testlib/configure.json
index c464037205..df6132cdc2 100644
--- a/src/testlib/configure.json
+++ b/src/testlib/configure.json
@@ -5,6 +5,12 @@
],
"features": {
+ "testlib_selfcover": {
+ "label": "Coverage testing of testlib itself",
+ "purpose": "Gauges how thoroughly testlib's selftest exercises testlib's code",
+ "autoDetect": false,
+ "output": [ "publicFeature" ]
+ },
"itemmodeltester": {
"label": "Tester for item models",
"purpose": "Provides a utility to test item models.",
diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf
index 1fdb136e78..5fdf6d9415 100644
--- a/src/testlib/doc/qttestlib.qdocconf
+++ b/src/testlib/doc/qttestlib.qdocconf
@@ -27,12 +27,20 @@ qhp.QtTestLib.subprojects.classes.sortPages = true
tagfile = ../../../doc/qttestlib/qttestlib.tags
-depends += qtcore qtdoc qtwidgets qtgui qmake qtquick
+depends += qtcore qtdoc qtwidgets qtgui qmake qtqmltest
headerdirs += ..
+headers += ../../corelib/kernel/qtestsupport_core.h \
+ ../../gui/kernel/qtestsupport_gui.h \
+ ../../widgets/kernel/qtestsupport_widgets.h
+
sourcedirs += ..
+sources += ../../corelib/kernel/qtestsupport_core.cpp \
+ ../../gui/kernel/qtestsupport_gui.cpp \
+ ../../widgets/kernel/qtestsupport_widgets.cpp
+
exampledirs += ../../../examples/qtestlib \
../ \
snippets
diff --git a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp
new file mode 100644
index 0000000000..e793cb1f55
--- /dev/null
+++ b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+ MyObject obj;
+ obj.startup();
+ QTest::qWaitFor([&]() {
+ return obj.isReady();
+ }, 3000);
+//! [0]
+
+//! [1]
+ int i = 0;
+ while (myNetworkServerNotResponding() && i++ < 50)
+ QTest::qWait(250);
+//! [1]
diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc
index 8c817b3653..23be46b431 100644
--- a/src/testlib/doc/src/qttest-index.qdoc
+++ b/src/testlib/doc/src/qttest-index.qdoc
@@ -35,6 +35,11 @@
and the \l QAbstractItemModelTester allows for non-destructive testing
of item models.
+ \note There is no binary compatibility guarantee for the Qt Test module.
+ This means that an application that uses Qt Test is only guaranteed
+ to work with the Qt version it was developed against. However, source
+ compatibility is guaranteed.
+
\section1 Getting Started
To enable Qt Test in a project, add this directive into the C++ files:
@@ -70,11 +75,15 @@
\section1 Reference
- These are links to the API reference materials.
+ \list
+ \li \l{Qt Test C++ Classes}
+ \endlist
+
+ The \l {Qt Quick Test} module enables unit testing Qt Quick applications.
\list
- \li \l{Qt Test C++ Classes}{C++ Classes}
- \li \l{Qt Quick Test QML Types}{QML Types}
+ \li \l{Qt Quick Test QML Types}
+ \li \l{Qt Quick Test C++ API}
\endlist
*/
diff --git a/src/testlib/qabstractitemmodeltester.h b/src/testlib/qabstractitemmodeltester.h
index 757074c6ae..57b8f283bc 100644
--- a/src/testlib/qabstractitemmodeltester.h
+++ b/src/testlib/qabstractitemmodeltester.h
@@ -123,11 +123,11 @@ do { \
MODELTESTER_VERIFY(variant.canConvert<QFont>());
// General Purpose roles that should return a QColor or a QBrush
- variant = model->data(model->index(0, 0), Qt::BackgroundColorRole);
+ variant = model->data(model->index(0, 0), Qt::BackgroundRole);
if (variant.isValid())
MODELTESTER_VERIFY(variant.canConvert<QColor>() || variant.canConvert<QBrush>());
- variant = model->data(model->index(0, 0), Qt::TextColorRole);
+ variant = model->data(model->index(0, 0), Qt::ForegroundRole);
if (variant.isValid())
MODELTESTER_VERIFY(variant.canConvert<QColor>() || variant.canConvert<QBrush>());
diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h
index 018361b81e..9bb1d1e80c 100644
--- a/src/testlib/qabstracttestlogger_p.h
+++ b/src/testlib/qabstracttestlogger_p.h
@@ -69,7 +69,9 @@ public:
Fail,
XPass,
BlacklistedPass,
- BlacklistedFail
+ BlacklistedFail,
+ BlacklistedXPass,
+ BlacklistedXFail
};
enum MessageTypes {
@@ -95,14 +97,14 @@ public:
virtual void enterTestData(QTestData *) {}
virtual void addIncident(IncidentTypes type, const char *description,
- const char *file = 0, int line = 0) = 0;
+ const char *file = nullptr, int line = 0) = 0;
virtual void addBenchmarkResult(const QBenchmarkResult &result) = 0;
virtual void addMessage(QtMsgType, const QMessageLogContext &,
const QString &);
virtual void addMessage(MessageTypes type, const QString &message,
- const char *file = 0, int line = 0) = 0;
+ const char *file = nullptr, int line = 0) = 0;
void outputString(const char *msg);
@@ -149,7 +151,7 @@ struct QTestCharBuffer
inline bool reset(int newSize)
{
- char *newBuf = 0;
+ char *newBuf = nullptr;
if (buf == staticBuf) {
// if we point to our internal buffer, we need to malloc first
newBuf = reinterpret_cast<char *>(malloc(newSize));
diff --git a/src/testlib/qappletestlogger.cpp b/src/testlib/qappletestlogger.cpp
index 2c1005ad80..dfeadebdef 100644
--- a/src/testlib/qappletestlogger.cpp
+++ b/src/testlib/qappletestlogger.cpp
@@ -55,9 +55,8 @@ bool QAppleTestLogger::debugLoggingEnabled()
return os_log_type_enabled(OS_LOG_DEFAULT, OS_LOG_TYPE_DEBUG);
}
-QAppleTestLogger::QAppleTestLogger(QAbstractTestLogger *logger)
+QAppleTestLogger::QAppleTestLogger()
: QAbstractTestLogger(nullptr)
- , m_logger(logger)
{
}
@@ -65,6 +64,8 @@ static QAppleLogActivity testFunctionActivity;
void QAppleTestLogger::enterTestFunction(const char *function)
{
+ Q_UNUSED(function);
+
// Re-create activity each time
testFunctionActivity = QT_APPLE_LOG_ACTIVITY("Running test function").enter();
@@ -73,75 +74,126 @@ void QAppleTestLogger::enterTestFunction(const char *function)
QString identifier = QString::fromLatin1(testIdentifier.data());
QMessageLogContext context(nullptr, 0, nullptr, "qt.test.enter");
QString message = identifier;
- if (AppleUnifiedLogger::messageHandler(QtDebugMsg, context, message, identifier))
- return; // AUL already printed to stderr
- m_logger->enterTestFunction(function);
+ AppleUnifiedLogger::messageHandler(QtDebugMsg, context, message, identifier);
}
void QAppleTestLogger::leaveTestFunction()
{
- m_logger->leaveTestFunction();
testFunctionActivity.leave();
}
-typedef QPair<QtMsgType, const char *> IncidentClassification;
-static IncidentClassification incidentTypeToClassification(QAbstractTestLogger::IncidentTypes type)
+struct MessageData
{
- switch (type) {
- case QAbstractTestLogger::Pass:
- return IncidentClassification(QtInfoMsg, "pass");
- case QAbstractTestLogger::XFail:
- return IncidentClassification(QtInfoMsg, "xfail");
- case QAbstractTestLogger::Fail:
- return IncidentClassification(QtCriticalMsg, "fail");
- case QAbstractTestLogger::XPass:
- return IncidentClassification(QtInfoMsg, "xpass");
- case QAbstractTestLogger::BlacklistedPass:
- return IncidentClassification(QtWarningMsg, "bpass");
- case QAbstractTestLogger::BlacklistedFail:
- return IncidentClassification(QtInfoMsg, "bfail");
+ QtMsgType messageType = QtFatalMsg;
+ const char *categorySuffix = nullptr;
+
+ void generateCategory(QTestCharBuffer *category)
+ {
+ if (categorySuffix)
+ QTest::qt_asprintf(category, "qt.test.%s", categorySuffix);
+ else
+ QTest::qt_asprintf(category, "qt.test");
}
- return IncidentClassification(QtFatalMsg, nullptr);
-}
+};
+
void QAppleTestLogger::addIncident(IncidentTypes type, const char *description,
const char *file, int line)
{
-
- IncidentClassification incidentClassification = incidentTypeToClassification(type);
+ MessageData messageData = [=]() {
+ switch (type) {
+ case QAbstractTestLogger::Pass:
+ return MessageData{QtInfoMsg, "pass"};
+ case QAbstractTestLogger::XFail:
+ return MessageData{QtInfoMsg, "xfail"};
+ case QAbstractTestLogger::Fail:
+ return MessageData{QtCriticalMsg, "fail"};
+ case QAbstractTestLogger::XPass:
+ return MessageData{QtInfoMsg, "xpass"};
+ case QAbstractTestLogger::BlacklistedPass:
+ return MessageData{QtWarningMsg, "bpass"};
+ case QAbstractTestLogger::BlacklistedFail:
+ return MessageData{QtInfoMsg, "bfail"};
+ case QAbstractTestLogger::BlacklistedXPass:
+ return MessageData{QtWarningMsg, "bxpass"};
+ case QAbstractTestLogger::BlacklistedXFail:
+ return MessageData{QtInfoMsg, "bxfail"};
+ }
+ Q_UNREACHABLE();
+ }();
QTestCharBuffer category;
- QTest::qt_asprintf(&category, "qt.test.%s", incidentClassification.second);
- QMessageLogContext context(file, line, /* function = */ nullptr, category.data());
+ messageData.generateCategory(&category);
- QTestCharBuffer subsystemBuffer;
- // It would be nice to have the data tag as part of the subsystem too, but that
- // will for some tests results in hundreds of thousands of log objects being
- // created, so we limit the subsystem to test functions, which we can hope
- // are reasonably limited.
- generateTestIdentifier(&subsystemBuffer, TestObject | TestFunction);
- QString subsystem = QString::fromLatin1(subsystemBuffer.data());
+ QMessageLogContext context(file, line, /* function = */ nullptr, category.data());
- // We still want the full identifier as part of the message though
- QTestCharBuffer testIdentifier;
- generateTestIdentifier(&testIdentifier);
- QString message = QString::fromLatin1(testIdentifier.data());
+ QString message = testIdentifier();
if (qstrlen(description))
message += QLatin1Char('\n') % QString::fromLatin1(description);
- if (AppleUnifiedLogger::messageHandler(incidentClassification.first, context, message, subsystem))
- return; // AUL already printed to stderr
-
- m_logger->addIncident(type, description, file, line);
+ AppleUnifiedLogger::messageHandler(messageData.messageType, context, message, subsystem());
}
void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
- if (AppleUnifiedLogger::messageHandler(type, context, message))
- return; // AUL already printed to stderr
+ AppleUnifiedLogger::messageHandler(type, context, message);
+}
- m_logger->addMessage(type, context, message);
+void QAppleTestLogger::addMessage(MessageTypes type, const QString &message, const char *file, int line)
+{
+ MessageData messageData = [=]() {
+ switch (type) {
+ case QAbstractTestLogger::Warn:
+ case QAbstractTestLogger::QWarning:
+ return MessageData{QtWarningMsg, nullptr};
+ case QAbstractTestLogger::QDebug:
+ return MessageData{QtDebugMsg, nullptr};
+ case QAbstractTestLogger::QSystem:
+ return MessageData{QtWarningMsg, "system"};
+ case QAbstractTestLogger::QFatal:
+ return MessageData{QtFatalMsg, nullptr};
+ case QAbstractTestLogger::Skip:
+ return MessageData{QtInfoMsg, "skip"};
+ case QAbstractTestLogger::Info:
+ case QAbstractTestLogger::QInfo:
+ return MessageData{QtInfoMsg, nullptr};
+ }
+ Q_UNREACHABLE();
+ }();
+
+ QTestCharBuffer category;
+ messageData.generateCategory(&category);
+
+ QMessageLogContext context(file, line, /* function = */ nullptr, category.data());
+ QString msg = message;
+
+ if (type == Skip) {
+ if (!message.isNull())
+ msg.prepend(testIdentifier() + QLatin1Char('\n'));
+ else
+ msg = testIdentifier();
+ }
+
+ AppleUnifiedLogger::messageHandler(messageData.messageType, context, msg, subsystem());
+}
+
+QString QAppleTestLogger::subsystem() const
+{
+ QTestCharBuffer buffer;
+ // It would be nice to have the data tag as part of the subsystem too, but that
+ // will for some tests result in hundreds of thousands of log objects being
+ // created, so we limit the subsystem to test functions, which we can hope
+ // are reasonably limited.
+ generateTestIdentifier(&buffer, TestObject | TestFunction);
+ return QString::fromLatin1(buffer.data());
+}
+
+QString QAppleTestLogger::testIdentifier() const
+{
+ QTestCharBuffer buffer;
+ generateTestIdentifier(&buffer);
+ return QString::fromLatin1(buffer.data());
}
#endif // QT_USE_APPLE_UNIFIED_LOGGING
diff --git a/src/testlib/qappletestlogger_p.h b/src/testlib/qappletestlogger_p.h
index 5a45fad7a0..62c6d95c5a 100644
--- a/src/testlib/qappletestlogger_p.h
+++ b/src/testlib/qappletestlogger_p.h
@@ -63,12 +63,7 @@ class QAppleTestLogger : public QAbstractTestLogger
public:
static bool debugLoggingEnabled();
- QAppleTestLogger(QAbstractTestLogger *logger);
-
- void startLogging() override
- { m_logger->startLogging(); }
- void stopLogging() override
- { m_logger->stopLogging(); }
+ QAppleTestLogger();
void enterTestFunction(const char *function) override;
void leaveTestFunction() override;
@@ -77,16 +72,15 @@ public:
const char *file = 0, int line = 0) override;
void addMessage(QtMsgType, const QMessageLogContext &,
const QString &) override;
+ void addMessage(MessageTypes type, const QString &message,
+ const char *file = 0, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &result) override
- { m_logger->addBenchmarkResult(result); }
-
- void addMessage(MessageTypes type, const QString &message,
- const char *file = 0, int line = 0) override
- { m_logger->addMessage(type, message, file, line); }
+ { Q_UNUSED(result); }
private:
- QScopedPointer<QAbstractTestLogger> m_logger;
+ QString subsystem() const;
+ QString testIdentifier() const;
};
#endif
diff --git a/src/testlib/qbenchmarkevent.cpp b/src/testlib/qbenchmarkevent.cpp
index f696f8b1eb..a8270219e4 100644
--- a/src/testlib/qbenchmarkevent.cpp
+++ b/src/testlib/qbenchmarkevent.cpp
@@ -96,7 +96,11 @@ QTest::QBenchmarkMetric QBenchmarkEvent::metricType()
}
// This could be done in a much better way, this is just the beginning.
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+bool QBenchmarkEvent::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result)
+#else
bool QBenchmarkEvent::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
+#endif
{
Q_UNUSED(eventType);
Q_UNUSED(message);
diff --git a/src/testlib/qbenchmarkevent_p.h b/src/testlib/qbenchmarkevent_p.h
index af42a17141..0f47aa475c 100644
--- a/src/testlib/qbenchmarkevent_p.h
+++ b/src/testlib/qbenchmarkevent_p.h
@@ -71,7 +71,11 @@ public:
int adjustMedianCount(int suggestion) override;
bool repeatCount() override { return 1; }
QTest::QBenchmarkMetric metricType() override;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
+#else
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override;
+#endif
qint64 eventCounter;
};
diff --git a/src/testlib/qbenchmarkvalgrind.cpp b/src/testlib/qbenchmarkvalgrind.cpp
index 1de149258d..7d24eb8293 100644
--- a/src/testlib/qbenchmarkvalgrind.cpp
+++ b/src/testlib/qbenchmarkvalgrind.cpp
@@ -46,6 +46,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qprocess.h>
#include <QtCore/qdir.h>
+#include <QtCore/qregularexpression.h>
#include <QtCore/qset.h>
#include <QtTest/private/callgrind_p.h>
@@ -90,13 +91,13 @@ qint64 QBenchmarkValgrindUtils::extractResult(const QString &fileName)
qint64 val = -1;
bool valSeen = false;
- QRegExp rxValue(QLatin1String("^summary: (\\d+)"));
+ QRegularExpression rxValue(QLatin1String("^summary: (\\d+)"));
while (!file.atEnd()) {
const QString line(QLatin1String(file.readLine()));
- if (rxValue.indexIn(line) != -1) {
- Q_ASSERT(rxValue.captureCount() == 1);
+ QRegularExpressionMatch match = rxValue.match(line);
+ if (match.hasMatch()) {
bool ok;
- val = rxValue.cap(1).toLongLong(&ok);
+ val = match.captured(1).toLongLong(&ok);
Q_ASSERT(ok);
valSeen = true;
break;
@@ -120,13 +121,12 @@ QString QBenchmarkValgrindUtils::getNewestFileName()
int hiSuffix = -1;
QFileInfo lastFileInfo;
const QString pattern = QString::fromLatin1("%1.(\\d+)").arg(base);
- QRegExp rx(pattern);
+ QRegularExpression rx(pattern);
for (const QFileInfo &fileInfo : fiList) {
- const int index = rx.indexIn(fileInfo.fileName());
- Q_ASSERT(index == 0);
- Q_UNUSED(index);
+ QRegularExpressionMatch match = rx.match(fileInfo.fileName());
+ Q_ASSERT(match.hasMatch());
bool ok;
- const int suffix = rx.cap(1).toInt(&ok);
+ const int suffix = match.captured(1).toInt(&ok);
Q_ASSERT(ok);
Q_ASSERT(suffix >= 0);
if (suffix > hiSuffix) {
diff --git a/src/testlib/qcsvbenchmarklogger_p.h b/src/testlib/qcsvbenchmarklogger_p.h
index 5840aee0f5..83e465c859 100644
--- a/src/testlib/qcsvbenchmarklogger_p.h
+++ b/src/testlib/qcsvbenchmarklogger_p.h
@@ -68,11 +68,11 @@ public:
void leaveTestFunction() override;
void addIncident(IncidentTypes type, const char *description,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &result) override;
void addMessage(MessageTypes type, const QString &message,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
};
QT_END_NAMESPACE
diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp
index 853515f2d9..ed53dcdde8 100644
--- a/src/testlib/qplaintestlogger.cpp
+++ b/src/testlib/qplaintestlogger.cpp
@@ -89,6 +89,10 @@ namespace QTest {
return "BPASS ";
case QAbstractTestLogger::BlacklistedFail:
return "BFAIL ";
+ case QAbstractTestLogger::BlacklistedXPass:
+ return "BXPASS ";
+ case QAbstractTestLogger::BlacklistedXFail:
+ return "BXFAIL ";
}
return "??????";
}
diff --git a/src/testlib/qplaintestlogger_p.h b/src/testlib/qplaintestlogger_p.h
index 55755830b2..80ef4864c1 100644
--- a/src/testlib/qplaintestlogger_p.h
+++ b/src/testlib/qplaintestlogger_p.h
@@ -68,17 +68,17 @@ public:
void leaveTestFunction() override;
void addIncident(IncidentTypes type, const char *description,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &result) override;
void addMessage(QtMsgType, const QMessageLogContext &,
const QString &) override;
void addMessage(MessageTypes type, const QString &message,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
private:
- void printMessage(const char *type, const char *msg, const char *file = 0, int line = 0);
+ void printMessage(const char *type, const char *msg, const char *file = nullptr, int line = 0);
void outputMessage(const char *str);
void printBenchmarkResult(const QBenchmarkResult &result);
};
diff --git a/src/testlib/qsignaldumper.cpp b/src/testlib/qsignaldumper.cpp
index 8305c5d424..d0b6d0dd3f 100644
--- a/src/testlib/qsignaldumper.cpp
+++ b/src/testlib/qsignaldumper.cpp
@@ -87,7 +87,7 @@ static void qSignalDumperCallback(QObject *caller, int signal_index, void **argv
str += objname.toLocal8Bit();
if (!objname.isEmpty())
str += ' ';
- str += QByteArray::number(quintptr(caller), 16);
+ str += QByteArray::number(quintptr(caller), 16).rightJustified(8, '0');
str += ") ";
str += member.name();
@@ -105,7 +105,7 @@ static void qSignalDumperCallback(QObject *caller, int signal_index, void **argv
str += '@';
quintptr addr = quintptr(*reinterpret_cast<void **>(argv[i + 1]));
- str.append(QByteArray::number(addr, 16));
+ str.append(QByteArray::number(addr, 16).rightJustified(8, '0'));
} else if (typeId != QMetaType::UnknownType) {
Q_ASSERT(typeId != QMetaType::Void); // void parameter => metaobject is corrupt
str.append(arg)
@@ -144,7 +144,7 @@ static void qSignalDumperCallbackSlot(QObject *caller, int method_index, void **
str += objname.toLocal8Bit();
if (!objname.isEmpty())
str += ' ';
- str += QByteArray::number(quintptr(caller), 16);
+ str += QByteArray::number(quintptr(caller), 16).rightJustified(8, '0');
str += ") ";
str += member.methodSignature();
@@ -170,13 +170,12 @@ void QSignalDumper::startDump()
{
static QSignalSpyCallbackSet set = { QTest::qSignalDumperCallback,
QTest::qSignalDumperCallbackSlot, QTest::qSignalDumperCallbackEndSignal, 0 };
- qt_register_signal_spy_callbacks(set);
+ qt_register_signal_spy_callbacks(&set);
}
void QSignalDumper::endDump()
{
- static QSignalSpyCallbackSet nset = { 0, 0, 0 ,0 };
- qt_register_signal_spy_callbacks(nset);
+ qt_register_signal_spy_callbacks(nullptr);
}
void QSignalDumper::ignoreClass(const QByteArray &klass)
diff --git a/src/testlib/qsignalspy.h b/src/testlib/qsignalspy.h
index 218a26ec5c..0285080662 100644
--- a/src/testlib/qsignalspy.h
+++ b/src/testlib/qsignalspy.h
@@ -122,7 +122,7 @@ public:
}
if (!QMetaObject::connect(obj, sigIndex, this, memberOffset,
- Qt::DirectConnection, 0)) {
+ Qt::DirectConnection, nullptr)) {
qWarning("QSignalSpy: QMetaObject::connect returned false. Unable to connect.");
return;
}
diff --git a/src/testlib/qsignalspy.qdoc b/src/testlib/qsignalspy.qdoc
index 77affc9a4b..3352307d69 100644
--- a/src/testlib/qsignalspy.qdoc
+++ b/src/testlib/qsignalspy.qdoc
@@ -63,7 +63,7 @@
Constructs a new QSignalSpy that listens for emissions of the \a signal
from the QObject \a object. If QSignalSpy is not able to listen for a
- valid signal (for example, because \a object is null or \a signal does
+ valid signal (for example, because \a object is \nullptr or \a signal does
not denote a valid signal of \a object), an explanatory warning message
will be output using qWarning() and subsequent calls to \c isValid() will
return false.
@@ -77,7 +77,7 @@
Constructs a new QSignalSpy that listens for emissions of the \a signal
from the QObject \a object. If QSignalSpy is not able to listen for a
- valid signal (for example, because \a object is null or \a signal does
+ valid signal (for example, because \a object is \nullptr or \a signal does
not denote a valid signal of \a object), an explanatory warning message
will be output using qWarning() and subsequent calls to \c isValid() will
return false.
diff --git a/src/testlib/qtaptestlogger.cpp b/src/testlib/qtaptestlogger.cpp
index 37ab89ac91..540b36e273 100644
--- a/src/testlib/qtaptestlogger.cpp
+++ b/src/testlib/qtaptestlogger.cpp
@@ -43,7 +43,9 @@
#include "qtestresult_p.h"
#include "qtestassert.h"
-#include <QtCore/qregularexpression.h>
+#if QT_CONFIG(regularexpression)
+# include <QtCore/qregularexpression.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -121,13 +123,15 @@ void QTapTestLogger::addIncident(IncidentTypes type, const char *description,
return;
}
- bool ok = type == Pass || type == XPass || type == BlacklistedPass;
+ bool ok = type == Pass || type == XPass || type == BlacklistedPass || type == BlacklistedXPass;
QTestCharBuffer directive;
- if (type == XFail || type == XPass || type == BlacklistedFail || type == BlacklistedPass)
+ if (type == XFail || type == XPass || type == BlacklistedFail || type == BlacklistedPass
+ || type == BlacklistedXFail || type == BlacklistedXPass) {
// We treat expected or blacklisted failures/passes as TODO-failures/passes,
// which should be treated as soft issues by consumers. Not all do though :/
QTest::qt_asprintf(&directive, " # TODO %s", description);
+ }
int testNumber = QTestLog::totalCount();
if (type == XFail) {
@@ -146,6 +150,7 @@ void QTapTestLogger::addIncident(IncidentTypes type, const char *description,
outputString(YAML_INDENT "---\n");
if (type != XFail) {
+#if QT_CONFIG(regularexpression)
// This is fragile, but unfortunately testlib doesn't plumb
// the expected and actual values to the loggers (yet).
static QRegularExpression verifyRegex(
@@ -206,6 +211,12 @@ void QTapTestLogger::addIncident(IncidentTypes type, const char *description,
YAML_INDENT "# %s\n", description);
outputString(unparsableDescription.data());
}
+#else
+ QTestCharBuffer unparsableDescription;
+ QTest::qt_asprintf(&unparsableDescription,
+ YAML_INDENT "# %s\n", description);
+ outputString(unparsableDescription.data());
+#endif
}
if (file) {
diff --git a/src/testlib/qtaptestlogger_p.h b/src/testlib/qtaptestlogger_p.h
index b51343e4fe..967c724b51 100644
--- a/src/testlib/qtaptestlogger_p.h
+++ b/src/testlib/qtaptestlogger_p.h
@@ -70,9 +70,9 @@ public:
void enterTestData(QTestData *data) override;
void addIncident(IncidentTypes type, const char *description,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
void addMessage(MessageTypes type, const QString &message,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &) override {};
private:
diff --git a/src/testlib/qteamcitylogger.cpp b/src/testlib/qteamcitylogger.cpp
index 9cfbe92b7d..88c83d1269 100644
--- a/src/testlib/qteamcitylogger.cpp
+++ b/src/testlib/qteamcitylogger.cpp
@@ -66,6 +66,10 @@ namespace QTest {
return "BPASS";
case QAbstractTestLogger::BlacklistedFail:
return "BFAIL";
+ case QAbstractTestLogger::BlacklistedXPass:
+ return "BXPASS";
+ case QAbstractTestLogger::BlacklistedXFail:
+ return "BXFAIL";
}
return "??????";
}
@@ -247,7 +251,7 @@ QString QTeamCityLogger::tcEscapedString(const QString &str) const
}
}
- return qMove(formattedString).simplified();
+ return std::move(formattedString).simplified();
}
QString QTeamCityLogger::escapedTestFuncName() const
diff --git a/src/testlib/qteamcitylogger_p.h b/src/testlib/qteamcitylogger_p.h
index 80f2454724..dd7c0cdcf0 100644
--- a/src/testlib/qteamcitylogger_p.h
+++ b/src/testlib/qteamcitylogger_p.h
@@ -70,11 +70,11 @@ public:
void leaveTestFunction() override;
void addIncident(IncidentTypes type, const char *description,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &result) override;
void addMessage(MessageTypes type, const QString &message,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
private:
QString currTestFuncName;
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index 82078ad7a8..89abc616d9 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -49,7 +49,9 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qstring.h>
#include <QtCore/qstringlist.h>
+#include <QtCore/qcborcommon.h>
#include <QtCore/qdatetime.h>
+#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qobject.h>
#include <QtCore/qvariant.h>
#include <QtCore/qurl.h>
@@ -110,6 +112,12 @@ template<> inline char *toString(const QDateTime &dateTime)
}
#endif // datestring
+template<> inline char *toString(const QCborError &c)
+{
+ // use the Q_ENUM formatting
+ return toString(c.c);
+}
+
template<> inline char *toString(const QChar &c)
{
const ushort uc = c.unicode();
@@ -121,6 +129,13 @@ template<> inline char *toString(const QChar &c)
return qstrdup(qPrintable(QString::fromLatin1("QChar: '%1' (0x%2)").arg(c).arg(QString::number(static_cast<int>(c.unicode()), 16))));
}
+template<> inline char *toString(const QModelIndex &idx)
+{
+ char msg[128];
+ qsnprintf(msg, sizeof(msg), "QModelIndex(%d,%d,%p,%p)", idx.row(), idx.column(), idx.internalPointer(), idx.model());
+ return qstrdup(msg);
+}
+
template<> inline char *toString(const QPoint &p)
{
char msg[128] = {'\0'};
@@ -359,9 +374,30 @@ QT_END_NAMESPACE
# define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__);
#endif
+// Hooks for coverage-testing of QTestLib itself:
+#if QT_CONFIG(testlib_selfcover) && defined(__COVERAGESCANNER__)
+struct QtCoverageScanner
+{
+ QtCoverageScanner(const char *name)
+ {
+ __coveragescanner_clear();
+ __coveragescanner_testname(name);
+ }
+ ~QtCoverageScanner()
+ {
+ __coveragescanner_save();
+ __coveragescanner_testname("");
+ }
+};
+#define TESTLIB_SELFCOVERAGE_START(name) QtCoverageScanner _qtCoverageScanner(name);
+#else
+#define TESTLIB_SELFCOVERAGE_START(name)
+#endif
+
#define QTEST_APPLESS_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
+ TESTLIB_SELFCOVERAGE_START(TestObject) \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv); \
@@ -388,48 +424,49 @@ int main(int argc, char *argv[]) \
# define QTEST_DISABLE_KEYPAD_NAVIGATION
#endif
-#define QTEST_MAIN(TestObject) \
-int main(int argc, char *argv[]) \
-{ \
+#define QTEST_MAIN_IMPL(TestObject) \
+ TESTLIB_SELFCOVERAGE_START(#TestObject) \
QApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
QTEST_DISABLE_KEYPAD_NAVIGATION \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
- return QTest::qExec(&tc, argc, argv); \
-}
+ return QTest::qExec(&tc, argc, argv);
#elif defined(QT_GUI_LIB)
#include <QtTest/qtest_gui.h>
-#define QTEST_MAIN(TestObject) \
-int main(int argc, char *argv[]) \
-{ \
+#define QTEST_MAIN_IMPL(TestObject) \
+ TESTLIB_SELFCOVERAGE_START(#TestObject) \
QGuiApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
- return QTest::qExec(&tc, argc, argv); \
-}
+ return QTest::qExec(&tc, argc, argv);
#else
-#define QTEST_MAIN(TestObject) \
-int main(int argc, char *argv[]) \
-{ \
+#define QTEST_MAIN_IMPL(TestObject) \
+ TESTLIB_SELFCOVERAGE_START(#TestObject) \
QCoreApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
- return QTest::qExec(&tc, argc, argv); \
-}
+ return QTest::qExec(&tc, argc, argv);
#endif // QT_GUI_LIB
+#define QTEST_MAIN(TestObject) \
+int main(int argc, char *argv[]) \
+{ \
+ QTEST_MAIN_IMPL(TestObject) \
+}
+
#define QTEST_GUILESS_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
+ TESTLIB_SELFCOVERAGE_START(#TestObject) \
QCoreApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
TestObject tc; \
diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp
index 84a99c10f3..886f1f75b9 100644
--- a/src/testlib/qtestblacklist.cpp
+++ b/src/testlib/qtestblacklist.cpp
@@ -104,6 +104,7 @@ static QSet<QByteArray> keywords()
#endif
#ifdef Q_OS_OSX
<< "osx"
+ << "macos"
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
<< "windows"
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index ea147f1b0f..db44b3860a 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -52,6 +52,7 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qfloat16.h>
#include <QtCore/qlibraryinfo.h>
#include <QtCore/private/qtools_p.h>
#include <QtCore/qdiriterator.h>
@@ -77,6 +78,10 @@
#include <QtTest/private/qtestutil_macos_p.h>
#endif
+#if defined(Q_OS_DARWIN)
+#include <QtTest/private/qappletestlogger_p.h>
+#endif
+
#include <cmath>
#include <numeric>
#include <algorithm>
@@ -245,7 +250,7 @@ static void stackTrace()
static bool installCoverageTool(const char * appname, const char * testname)
{
-#ifdef __COVERAGESCANNER__
+#if defined(__COVERAGESCANNER__) && !QT_CONFIG(testlib_selfcover)
if (!qEnvironmentVariableIsEmpty("QT_TESTCOCOON_ACTIVE"))
return false;
// Set environment variable QT_TESTCOCOON_ACTIVE to prevent an eventual subtest from
@@ -282,74 +287,75 @@ namespace QTestPrivate
namespace QTest
{
- class WatchDog;
+class WatchDog;
- static QObject *currentTestObject = 0;
- static QString mainSourcePath;
+static QObject *currentTestObject = 0;
+static QString mainSourcePath;
#if defined(Q_OS_MACOS)
- bool macNeedsActivate = false;
- IOPMAssertionID powerID;
+bool macNeedsActivate = false;
+IOPMAssertionID powerID;
#endif
- class TestMethods {
- Q_DISABLE_COPY(TestMethods)
- public:
- typedef std::vector<QMetaMethod> MetaMethods;
+class TestMethods {
+public:
+ Q_DISABLE_COPY_MOVE(TestMethods)
- explicit TestMethods(const QObject *o, const MetaMethods &m = MetaMethods());
+ typedef std::vector<QMetaMethod> MetaMethods;
- void invokeTests(QObject *testObject) const;
+ explicit TestMethods(const QObject *o, const MetaMethods &m = MetaMethods());
- static QMetaMethod findMethod(const QObject *obj, const char *signature);
+ void invokeTests(QObject *testObject) const;
- private:
- bool invokeTest(int index, const char *data, WatchDog *watchDog) const;
- void invokeTestOnData(int index) const;
+ static QMetaMethod findMethod(const QObject *obj, const char *signature);
- QMetaMethod m_initTestCaseMethod; // might not exist, check isValid().
- QMetaMethod m_initTestCaseDataMethod;
- QMetaMethod m_cleanupTestCaseMethod;
- QMetaMethod m_initMethod;
- QMetaMethod m_cleanupMethod;
+private:
+ bool invokeTest(int index, const char *data, WatchDog *watchDog) const;
+ void invokeTestOnData(int index) const;
- MetaMethods m_methods;
- };
+ QMetaMethod m_initTestCaseMethod; // might not exist, check isValid().
+ QMetaMethod m_initTestCaseDataMethod;
+ QMetaMethod m_cleanupTestCaseMethod;
+ QMetaMethod m_initMethod;
+ QMetaMethod m_cleanupMethod;
- TestMethods::TestMethods(const QObject *o, const MetaMethods &m)
- : m_initTestCaseMethod(TestMethods::findMethod(o, "initTestCase()"))
- , m_initTestCaseDataMethod(TestMethods::findMethod(o, "initTestCase_data()"))
- , m_cleanupTestCaseMethod(TestMethods::findMethod(o, "cleanupTestCase()"))
- , m_initMethod(TestMethods::findMethod(o, "init()"))
- , m_cleanupMethod(TestMethods::findMethod(o, "cleanup()"))
- , m_methods(m)
- {
- if (m.empty()) {
- const QMetaObject *metaObject = o->metaObject();
- const int count = metaObject->methodCount();
- m_methods.reserve(count);
- for (int i = 0; i < count; ++i) {
- const QMetaMethod me = metaObject->method(i);
- if (isValidSlot(me))
- m_methods.push_back(me);
- }
+ MetaMethods m_methods;
+};
+
+TestMethods::TestMethods(const QObject *o, const MetaMethods &m)
+ : m_initTestCaseMethod(TestMethods::findMethod(o, "initTestCase()"))
+ , m_initTestCaseDataMethod(TestMethods::findMethod(o, "initTestCase_data()"))
+ , m_cleanupTestCaseMethod(TestMethods::findMethod(o, "cleanupTestCase()"))
+ , m_initMethod(TestMethods::findMethod(o, "init()"))
+ , m_cleanupMethod(TestMethods::findMethod(o, "cleanup()"))
+ , m_methods(m)
+{
+ if (m.empty()) {
+ const QMetaObject *metaObject = o->metaObject();
+ const int count = metaObject->methodCount();
+ m_methods.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ const QMetaMethod me = metaObject->method(i);
+ if (isValidSlot(me))
+ m_methods.push_back(me);
}
}
+}
- QMetaMethod TestMethods::findMethod(const QObject *obj, const char *signature)
- {
- const QMetaObject *metaObject = obj->metaObject();
- const int funcIndex = metaObject->indexOfMethod(signature);
- return funcIndex >= 0 ? metaObject->method(funcIndex) : QMetaMethod();
- }
+QMetaMethod TestMethods::findMethod(const QObject *obj, const char *signature)
+{
+ const QMetaObject *metaObject = obj->metaObject();
+ const int funcIndex = metaObject->indexOfMethod(signature);
+ return funcIndex >= 0 ? metaObject->method(funcIndex) : QMetaMethod();
+}
- static int keyDelay = -1;
- static int mouseDelay = -1;
- static int eventDelay = -1;
+static int keyDelay = -1;
+static int mouseDelay = -1;
+static int eventDelay = -1;
#if QT_CONFIG(thread)
- static int timeout = -1;
+static int timeout = -1;
#endif
- static bool noCrashHandler = false;
+static bool noCrashHandler = false;
/*! \internal
Invoke a method of the object without generating warning if the method does not exist
@@ -496,7 +502,7 @@ static void qPrintDataTags(FILE *stream)
}
}
-static int qToInt(char *str)
+static int qToInt(const char *str)
{
char *pEnd;
int l = (int)strtol(str, &pEnd, 10);
@@ -507,9 +513,9 @@ static int qToInt(char *str)
return l;
}
-Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
+Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool qml)
{
- QTestLog::LogMode logFormat = QTestLog::Plain;
+ int logFormat = -1; // Not set
const char *logFilename = 0;
QTest::testFunctions.clear();
@@ -677,7 +683,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
fprintf(stderr, "only one logger can log to stdout\n");
exit(1);
}
- QTestLog::addLogger(logFormat, filename);
+ QTestLog::addLogger(QTestLog::LogMode(logFormat), filename);
}
delete [] filename;
delete [] format;
@@ -811,9 +817,9 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
// we load the QML files. So just store the data for now.
int colon = -1;
int offset;
- for (offset = 0; *(argv[i]+offset); ++offset) {
- if (*(argv[i]+offset) == ':') {
- if (*(argv[i]+offset+1) == ':') {
+ for (offset = 0; argv[i][offset]; ++offset) {
+ if (argv[i][offset] == ':') {
+ if (argv[i][offset + 1] == ':') {
// "::" is used as a test name separator.
// e.g. "ClickTests::test_click:row1".
++offset;
@@ -839,10 +845,30 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
QTestLog::setInstalledTestCoverage(installedTestCoverage);
// If no loggers were created by the long version of the -o command-line
- // option, create a logger using whatever filename and format were
- // set using the old-style command-line options.
- if (QTestLog::loggerCount() == 0)
- QTestLog::addLogger(logFormat, logFilename);
+ // option, but a logger was requested via the old-style option, add it.
+ const bool explicitLoggerRequested = logFormat != -1;
+ if (QTestLog::loggerCount() == 0 && explicitLoggerRequested)
+ QTestLog::addLogger(QTestLog::LogMode(logFormat), logFilename);
+
+ bool addFallbackLogger = !explicitLoggerRequested;
+
+#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
+ // Any explicitly requested loggers will be added by now, so we can check if they use stdout
+ const bool safeToAddAppleLogger = !AppleUnifiedLogger::willMirrorToStderr() || !QTestLog::loggerUsingStdout();
+ if (safeToAddAppleLogger && QAppleTestLogger::debugLoggingEnabled()) {
+ QTestLog::addLogger(QTestLog::Apple, nullptr);
+ if (AppleUnifiedLogger::willMirrorToStderr() && !logFilename)
+ addFallbackLogger = false; // Prevent plain test logger fallback below
+ }
+#endif
+
+ if (addFallbackLogger)
+ QTestLog::addLogger(QTestLog::Plain, logFilename);
+}
+
+// Temporary, backwards compatibility, until qtdeclarative's use of it is converted
+Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) {
+ qtest_qParseArgs(argc, const_cast<const char *const *>(argv), qml);
}
QBenchmarkResult qMedian(const QVector<QBenchmarkResult> &container)
@@ -1069,7 +1095,7 @@ bool TestMethods::invokeTest(int index, const char *data, WatchDog *watchDog) co
const int globalDataCount = gTable->dataCount();
int curGlobalDataIndex = 0;
- /* For each test function that has a *_data() table/function, do: */
+ /* For each entry in the global data table, do: */
do {
if (!gTable->isEmpty())
QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex));
@@ -1077,50 +1103,50 @@ bool TestMethods::invokeTest(int index, const char *data, WatchDog *watchDog) co
if (curGlobalDataIndex == 0) {
qsnprintf(member, 512, "%s_data()", name.constData());
invokeMethod(QTest::currentTestObject, member);
+ if (QTestResult::skipCurrentTest())
+ break;
}
bool foundFunction = false;
- if (!QTestResult::skipCurrentTest()) {
- int curDataIndex = 0;
- const int dataCount = table.dataCount();
-
- // Data tag requested but none available?
- if (data && !dataCount) {
- // Let empty data tag through.
- if (!*data)
- data = 0;
- else {
- fprintf(stderr, "Unknown testdata for function %s(): '%s'\n", name.constData(), data);
- fprintf(stderr, "Function has no testdata.\n");
- return false;
- }
+ int curDataIndex = 0;
+ const int dataCount = table.dataCount();
+
+ // Data tag requested but none available?
+ if (data && !dataCount) {
+ // Let empty data tag through.
+ if (!*data)
+ data = 0;
+ else {
+ fprintf(stderr, "Unknown testdata for function %s(): '%s'\n", name.constData(), data);
+ fprintf(stderr, "Function has no testdata.\n");
+ return false;
}
+ }
- /* For each entry in the data table, do: */
- do {
- QTestResult::setSkipCurrentTest(false);
- QTestResult::setBlacklistCurrentTest(false);
- if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
- foundFunction = true;
+ /* For each entry in this test's data table, do: */
+ do {
+ QTestResult::setSkipCurrentTest(false);
+ QTestResult::setBlacklistCurrentTest(false);
+ if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
+ foundFunction = true;
- QTestPrivate::checkBlackLists(name.constData(), dataCount ? table.testData(curDataIndex)->dataTag() : 0);
+ QTestPrivate::checkBlackLists(name.constData(), dataCount ? table.testData(curDataIndex)->dataTag() : 0);
- QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
- : table.testData(curDataIndex));
+ QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
+ : table.testData(curDataIndex));
- QTestPrivate::qtestMouseButtons = Qt::NoButton;
- if (watchDog)
- watchDog->beginTest();
- invokeTestOnData(index);
- if (watchDog)
- watchDog->testFinished();
+ QTestPrivate::qtestMouseButtons = Qt::NoButton;
+ if (watchDog)
+ watchDog->beginTest();
+ invokeTestOnData(index);
+ if (watchDog)
+ watchDog->testFinished();
- if (data)
- break;
- }
- ++curDataIndex;
- } while (curDataIndex < dataCount);
- }
+ if (data)
+ break;
+ }
+ ++curDataIndex;
+ } while (curDataIndex < dataCount);
if (data && !foundFunction) {
fprintf(stderr, "Unknown testdata for function %s: '%s()'\n", name.constData(), data);
@@ -1195,7 +1221,9 @@ char *formatString(const char *prefix, const char *suffix, size_t numArguments,
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.
+ the returned string as an ellipsis at the end. The caller has
+ ownership of the returned pointer and must ensure it is later passed
+ to operator delete[].
\a length is the length of the string \a ba.
*/
@@ -1597,7 +1625,7 @@ FatalSignalHandler::~FatalSignalHandler()
// Helper class for resolving symbol names by dynamically loading "dbghelp.dll".
class DebugSymbolResolver
{
- Q_DISABLE_COPY(DebugSymbolResolver)
+ Q_DISABLE_COPY_MOVE(DebugSymbolResolver)
public:
struct Symbol {
Symbol() : name(nullptr), address(0) {}
@@ -2120,7 +2148,7 @@ QSharedPointer<QTemporaryDir> QTest::qExtractTestData(const QString &dirName)
}
}
- result = qMove(tempDir);
+ result = std::move(tempDir);
return result;
}
@@ -2162,13 +2190,12 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co
if (found.isEmpty()) {
const char *testObjectName = QTestResult::currentTestObjectName();
if (testObjectName) {
- QString testsPath = QLibraryInfo::location(QLibraryInfo::TestsPath);
- QString candidate = QString::fromLatin1("%1/%2/%3")
+ const QString testsPath = QLibraryInfo::location(QLibraryInfo::TestsPath);
+ const QString candidate = QString::fromLatin1("%1/%2/%3")
.arg(testsPath, QFile::decodeName(testObjectName).toLower(), base);
if (QFileInfo::exists(candidate)) {
found = candidate;
- }
- else if (QTestLog::verboseLevel() >= 2) {
+ } else if (QTestLog::verboseLevel() >= 2) {
QTestLog::info(qPrintable(
QString::fromLatin1("testdata %1 not found in tests install path [%2]; "
"checking next location")
@@ -2190,11 +2217,10 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co
}
const QString canonicalPath = srcdir.canonicalFilePath();
- QString candidate = QString::fromLatin1("%1/%2").arg(canonicalPath, base);
+ const QString candidate = QString::fromLatin1("%1/%2").arg(canonicalPath, base);
if (!canonicalPath.isEmpty() && QFileInfo::exists(candidate)) {
found = candidate;
- }
- else if (QTestLog::verboseLevel() >= 2) {
+ } else if (QTestLog::verboseLevel() >= 2) {
QTestLog::info(qPrintable(
QString::fromLatin1("testdata %1 not found relative to source path [%2]")
.arg(base, QDir::toNativeSeparators(candidate))),
@@ -2204,31 +2230,48 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co
// 4. Try resources
if (found.isEmpty()) {
- QString candidate = QString::fromLatin1(":/%1").arg(base);
- if (QFileInfo::exists(candidate))
+ const QString candidate = QString::fromLatin1(":/%1").arg(base);
+ if (QFileInfo::exists(candidate)) {
found = candidate;
+ } else if (QTestLog::verboseLevel() >= 2) {
+ QTestLog::info(qPrintable(
+ QString::fromLatin1("testdata %1 not found in resources [%2]")
+ .arg(base, QDir::toNativeSeparators(candidate))),
+ file, line);
+ }
}
// 5. Try current directory
if (found.isEmpty()) {
const QString candidate = QDir::currentPath() + QLatin1Char('/') + base;
- if (QFileInfo::exists(candidate))
+ if (QFileInfo::exists(candidate)) {
found = candidate;
+ } else if (QTestLog::verboseLevel() >= 2) {
+ QTestLog::info(qPrintable(
+ QString::fromLatin1("testdata %1 not found in current directory [%2]")
+ .arg(base, QDir::toNativeSeparators(candidate))),
+ file, line);
+ }
}
// 6. Try main source directory
if (found.isEmpty()) {
- QString candidate = QTest::mainSourcePath % QLatin1Char('/') % base;
- if (QFileInfo::exists(candidate))
+ const QString candidate = QTest::mainSourcePath % QLatin1Char('/') % base;
+ if (QFileInfo::exists(candidate)) {
found = candidate;
+ } else if (QTestLog::verboseLevel() >= 2) {
+ QTestLog::info(qPrintable(
+ QString::fromLatin1("testdata %1 not found in main source directory [%2]")
+ .arg(base, QDir::toNativeSeparators(candidate))),
+ file, line);
+ }
}
if (found.isEmpty()) {
QTest::qWarn(qPrintable(
QString::fromLatin1("testdata %1 could not be located!").arg(base)),
file, line);
- }
- else if (QTestLog::verboseLevel() >= 1) {
+ } else if (QTestLog::verboseLevel() >= 1) {
QTestLog::info(qPrintable(
QString::fromLatin1("testdata %1 was located at %2").arg(base, QDir::toNativeSeparators(found))),
file, line);
@@ -2302,7 +2345,7 @@ void QTest::addColumnInternal(int id, const char *name)
*/
QTestData &QTest::newRow(const char *dataTag)
{
- QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag can not be null");
+ QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag cannot be null");
QTestTable *tbl = QTestTable::currentTestTable();
QTEST_ASSERT_X(tbl, "QTest::newRow()", "Cannot add testdata outside of a _data slot.");
QTEST_ASSERT_X(tbl->elementCount(), "QTest::newRow()", "Must add columns before attempting to add rows.");
@@ -2417,7 +2460,7 @@ bool QTest::currentTestFailed()
Sleeps for \a ms milliseconds, blocking execution of the
test. qSleep() will not do any event processing and leave your test
unresponsive. Network communication might time out while
- sleeping. Use \l qWait() to do non-blocking sleeping.
+ sleeping. Use \l {QTest::qWait()} to do non-blocking sleeping.
\a ms must be greater than 0.
@@ -2428,7 +2471,7 @@ bool QTest::currentTestFailed()
Example:
\snippet code/src_qtestlib_qtestcase.cpp 23
- \sa qWait()
+ \sa {QTest::qWait()}
*/
void QTest::qSleep(int ms)
{
@@ -2476,13 +2519,38 @@ bool QTest::compare_helper(bool success, const char *failureMsg,
return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line);
}
+template <typename T>
+static bool floatingCompare(const T &t1, const T &t2)
+{
+ switch (qFpClassify(t1))
+ {
+ case FP_INFINITE:
+ return (t1 < 0) == (t2 < 0) && qFpClassify(t2) == FP_INFINITE;
+ case FP_NAN:
+ return qFpClassify(t2) == FP_NAN;
+ default:
+ return qFuzzyCompare(t1, t2);
+ }
+}
+
+/*! \fn bool QTest::qCompare(const qfloat16 &t1, const qfloat16 &t2, const char *actual, const char *expected, const char *file, int line)
+ \internal
+ */
+bool QTest::qCompare(qfloat16 const &t1, qfloat16 const &t2, const char *actual, const char *expected,
+ const char *file, int line)
+{
+ return compare_helper(qFuzzyCompare(t1, t2), "Compared qfloat16s are not the same (fuzzy compare)",
+ toString(t1), toString(t2), actual, expected, file, line);
+}
+
/*! \fn bool QTest::qCompare(const float &t1, const float &t2, const char *actual, const char *expected, const char *file, int line)
\internal
*/
bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected,
const char *file, int line)
{
- return compare_helper(qFuzzyCompare(t1, t2), "Compared floats are not the same (fuzzy compare)",
+ return compare_helper(floatingCompare(t1, t2),
+ "Compared floats are not the same (fuzzy compare)",
toString(t1), toString(t2), actual, expected, file, line);
}
@@ -2492,16 +2560,8 @@ bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const
bool QTest::qCompare(double const &t1, double const &t2, const char *actual, const char *expected,
const char *file, int line)
{
- bool equal = false;
- int cl1 = std::fpclassify(t1);
- int cl2 = std::fpclassify(t2);
- if (cl1 == FP_INFINITE)
- equal = ((t1 < 0) == (t2 < 0)) && cl2 == FP_INFINITE;
- else if (cl1 == FP_NAN)
- equal = (cl2 == FP_NAN);
- else
- equal = qFuzzyCompare(t1, t2);
- return compare_helper(equal, "Compared doubles are not the same (fuzzy compare)",
+ return compare_helper(floatingCompare(t1, t2),
+ "Compared doubles are not the same (fuzzy compare)",
toString(t1), toString(t2), actual, expected, file, line);
}
@@ -2514,7 +2574,7 @@ bool QTest::qCompare(double const &t1, double const &t2, const char *actual, con
*/
#define TO_STRING_IMPL(TYPE, FORMAT) \
-template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE >(const TYPE &t) \
+template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE>(const TYPE &t) \
{ \
char *msg = new char[128]; \
qsnprintf(msg, 128, #FORMAT, t); \
@@ -2537,8 +2597,64 @@ TO_STRING_IMPL(quint64, %llu)
TO_STRING_IMPL(bool, %d)
TO_STRING_IMPL(signed char, %hhd)
TO_STRING_IMPL(unsigned char, %hhu)
-TO_STRING_IMPL(float, %g)
-TO_STRING_IMPL(double, %lg)
+
+/*!
+ \internal
+
+ Be consistent about leading 0 in exponent.
+
+ POSIX specifies that %e (hence %g when using it) uses at least two digits in
+ the exponent, requiring a leading 0 on single-digit exponents; (at least)
+ MinGW includes a leading zero also on an already-two-digit exponent,
+ e.g. 9e-040, which differs from more usual platforms. So massage that away.
+ */
+static void massageExponent(char *text)
+{
+ char *p = strchr(text, 'e');
+ if (!p)
+ return;
+ const char *const end = p + strlen(p); // *end is '\0'
+ p += (p[1] == '-' || p[1] == '+') ? 2 : 1;
+ if (p[0] != '0' || end - 2 <= p)
+ return;
+ // We have a leading 0 on an exponent of at least two more digits
+ const char *n = p + 1;
+ while (end - 2 > n && n[0] == '0')
+ ++n;
+ memmove(p, n, end + 1 - n);
+}
+
+// Be consistent about display of infinities and NaNs (snprintf()'s varies,
+// notably on MinGW, despite POSIX documenting "[-]inf" or "[-]infinity" for %f,
+// %e and %g, uppercasing for their capital versions; similar for "nan"):
+#define TO_STRING_FLOAT(TYPE, FORMAT) \
+template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE>(const TYPE &t) \
+{ \
+ char *msg = new char[128]; \
+ switch (qFpClassify(t)) { \
+ case FP_INFINITE: \
+ qstrncpy(msg, (t < 0 ? "-inf" : "inf"), 128); \
+ break; \
+ case FP_NAN: \
+ qstrncpy(msg, "nan", 128); \
+ break; \
+ default: \
+ qsnprintf(msg, 128, #FORMAT, double(t)); \
+ massageExponent(msg); \
+ break; \
+ } \
+ return msg; \
+}
+
+TO_STRING_FLOAT(float, %g)
+TO_STRING_FLOAT(double, %.12g)
+
+template <> Q_TESTLIB_EXPORT char *QTest::toString<qfloat16>(const qfloat16 &t)
+{
+ char *msg = new char[16];
+ qsnprintf(msg, 16, "%.3g", static_cast<float>(t));
+ return msg;
+}
template <> Q_TESTLIB_EXPORT char *QTest::toString<char>(const char &t)
{
diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h
index f6891dc941..794283ff78 100644
--- a/src/testlib/qtestcase.h
+++ b/src/testlib/qtestcase.h
@@ -57,6 +57,7 @@
QT_BEGIN_NAMESPACE
+class qfloat16;
class QRegularExpression;
#define QVERIFY(statement) \
@@ -67,17 +68,17 @@ do {\
#define QFAIL(message) \
do {\
- QTest::qFail(message, __FILE__, __LINE__);\
+ QTest::qFail(static_cast<const char *>(message), __FILE__, __LINE__);\
return;\
} while (false)
#define QVERIFY2(statement, description) \
do {\
if (statement) {\
- if (!QTest::qVerify(true, #statement, (description), __FILE__, __LINE__))\
+ if (!QTest::qVerify(true, #statement, static_cast<const char *>(description), __FILE__, __LINE__))\
return;\
} else {\
- if (!QTest::qVerify(false, #statement, (description), __FILE__, __LINE__))\
+ if (!QTest::qVerify(false, #statement, static_cast<const char *>(description), __FILE__, __LINE__))\
return;\
}\
} while (false)
@@ -150,7 +151,7 @@ do {\
// Ideally we'd use qWaitFor instead of QTRY_LOOP_IMPL, but due
// to a compiler bug on MSVC < 2017 we can't (see QTBUG-59096)
#define QTRY_IMPL(expr, timeout)\
- const int qt_test_step = 50; \
+ const int qt_test_step = timeout < 350 ? timeout / 7 + 1 : 50; \
const int qt_test_timeoutValue = timeout; \
QTRY_LOOP_IMPL((expr), qt_test_timeoutValue, qt_test_step); \
QTRY_TIMEOUT_DEBUG_IMPL((expr), qt_test_timeoutValue, qt_test_step)\
@@ -184,23 +185,15 @@ do { \
#define QSKIP_INTERNAL(statement) \
do {\
- QTest::qSkip(statement, __FILE__, __LINE__);\
+ QTest::qSkip(static_cast<const char *>(statement), __FILE__, __LINE__);\
return;\
} while (false)
-#ifdef Q_COMPILER_VARIADIC_MACROS
-
#define QSKIP(statement, ...) QSKIP_INTERNAL(statement)
-#else
-
-#define QSKIP(statement) QSKIP_INTERNAL(statement)
-
-#endif
-
#define QEXPECT_FAIL(dataIndex, comment, mode)\
do {\
- if (!QTest::qExpectFail(dataIndex, comment, QTest::mode, __FILE__, __LINE__))\
+ if (!QTest::qExpectFail(dataIndex, static_cast<const char *>(comment), QTest::mode, __FILE__, __LINE__))\
return;\
} while (false)
@@ -217,7 +210,7 @@ do {\
} while (false)
#define QWARN(msg)\
- QTest::qWarn(msg, __FILE__, __LINE__)
+ QTest::qWarn(static_cast<const char *>(msg), __FILE__, __LINE__)
#ifdef QT_TESTCASE_BUILDDIR
# define QFINDTESTDATA(basepath)\
@@ -361,6 +354,9 @@ namespace QTest
}
#endif
+ Q_TESTLIB_EXPORT bool qCompare(qfloat16 const &t1, qfloat16 const &t2,
+ const char *actual, const char *expected, const char *file, int line);
+
Q_TESTLIB_EXPORT bool qCompare(float const &t1, float const &t2,
const char *actual, const char *expected, const char *file, int line);
@@ -405,6 +401,7 @@ namespace QTest
QTEST_COMPARE_DECL(float)
QTEST_COMPARE_DECL(double)
+ QTEST_COMPARE_DECL(qfloat16)
QTEST_COMPARE_DECL(char)
QTEST_COMPARE_DECL(signed char)
QTEST_COMPARE_DECL(unsigned char)
diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc
index ad9776f7ec..2af016304d 100644
--- a/src/testlib/qtestcase.qdoc
+++ b/src/testlib/qtestcase.qdoc
@@ -959,7 +959,7 @@
\overload
\since 5.8
- Returns a string containing \c{nullptr}.
+ Returns a string containing \nullptr.
*/
/*!
@@ -995,6 +995,22 @@
*/
/*!
+ \fn char *QTest::toString(const QCborError &c)
+ \overload
+ \since 5.12
+
+ Returns a textual representation of the given CBOR error \a c.
+*/
+
+/*!
+ \fn template <class... Types> char *QTest::toString(const std::tuple<Types...> &tuple)
+ \overload
+ \since 5.12
+
+ Returns a textual representation of the given \a tuple.
+*/
+
+/*!
\fn char *QTest::toString(const QTime &time)
\overload
@@ -1113,6 +1129,12 @@
*/
/*!
+ \fn template <typename Tuple, int... I> char *QTest::toString(const Tuple &tuple, QtPrivate::IndexesList<I...> )
+ \internal
+ \since 5.12
+*/
+
+/*!
\fn QTouchDevice *QTest::createTouchDevice(QTouchDevice::DeviceType devType = QTouchDevice::TouchScreen)
\since 5.8
diff --git a/src/testlib/qtestcoreelement_p.h b/src/testlib/qtestcoreelement_p.h
index e79efdd87f..84406fed85 100644
--- a/src/testlib/qtestcoreelement_p.h
+++ b/src/testlib/qtestcoreelement_p.h
@@ -80,7 +80,7 @@ class QTestCoreElement: public QTestCoreList<ElementType>
template<class ElementType>
QTestCoreElement<ElementType>::QTestCoreElement(int t)
- :listOfAttributes(0), type(QTest::LogElementType(t))
+ :listOfAttributes(nullptr), type(QTest::LogElementType(t))
{
}
@@ -114,7 +114,7 @@ const char *QTestCoreElement<ElementType>::attributeValue(QTest::AttributeIndex
if (attrb)
return attrb->value();
- return 0;
+ return nullptr;
}
template <class ElementType>
@@ -124,7 +124,7 @@ const char *QTestCoreElement<ElementType>::attributeName(QTest::AttributeIndex i
if (attrb)
return attrb->name();
- return 0;
+ return nullptr;
}
template <class ElementType>
@@ -145,7 +145,7 @@ const char *QTestCoreElement<ElementType>::elementName() const
if (type != QTest::LET_Undefined)
return xmlElementNames[type];
- return 0;
+ return nullptr;
}
template <class ElementType>
@@ -165,7 +165,7 @@ const QTestElementAttribute *QTestCoreElement<ElementType>::attribute(QTest::Att
iterator = iterator->nextElement();
}
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/testlib/qtestcorelist_p.h b/src/testlib/qtestcorelist_p.h
index 5943695876..daeb293644 100644
--- a/src/testlib/qtestcorelist_p.h
+++ b/src/testlib/qtestcorelist_p.h
@@ -66,9 +66,6 @@ class QTestCoreList
void addToList(T **list);
T *nextElement();
T *previousElement();
- int count(T *list);
- int count();
-
private:
T *next;
T *prev;
@@ -76,8 +73,8 @@ class QTestCoreList
template <class T>
QTestCoreList<T>::QTestCoreList()
- : next(0)
- , prev(0)
+ : next(nullptr)
+ , prev(nullptr)
{
}
@@ -85,12 +82,12 @@ template <class T>
QTestCoreList<T>::~QTestCoreList()
{
if (prev) {
- prev->next = 0;
+ prev->next = nullptr;
}
delete prev;
if (next) {
- next->prev = 0;
+ next->prev = nullptr;
}
delete next;
}
@@ -121,20 +118,6 @@ 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
#endif
diff --git a/src/testlib/qtestevent.qdoc b/src/testlib/qtestevent.qdoc
index f0d3bff162..af84f2ac2b 100644
--- a/src/testlib/qtestevent.qdoc
+++ b/src/testlib/qtestevent.qdoc
@@ -133,7 +133,7 @@
Adds a \a msecs milliseconds delay.
- \sa QTest::qWait()
+ \sa {QTest::qWait()}
*/
/*! \fn void QTestEventList::simulate(QWidget *w)
diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h
index 63501ffb1e..e8a7e0d5f5 100644
--- a/src/testlib/qtestkeyboard.h
+++ b/src/testlib/qtestkeyboard.h
@@ -166,6 +166,7 @@ namespace QTest
Q_DECL_UNUSED inline static void keyPress(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
{ keyEvent(Press, window, key, modifier, delay); }
+#if QT_CONFIG(shortcut)
Q_DECL_UNUSED inline static void keySequence(QWindow *window, const QKeySequence &keySequence)
{
for (int i = 0; i < keySequence.count(); ++i) {
@@ -174,6 +175,7 @@ namespace QTest
keyClick(window, key, modifiers);
}
}
+#endif
#ifdef QT_WIDGETS_LIB
static void simulateEvent(QWidget *widget, bool press, int code,
@@ -305,6 +307,7 @@ namespace QTest
inline static void keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
{ keyEvent(Click, widget, key, modifier, delay); }
+#if QT_CONFIG(shortcut)
inline static void keySequence(QWidget *widget, const QKeySequence &keySequence)
{
for (int i = 0; i < keySequence.count(); ++i) {
@@ -313,6 +316,7 @@ namespace QTest
keyClick(widget, key, modifiers);
}
}
+#endif
#endif // QT_WIDGETS_LIB
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 1268730cc6..faef3912c4 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -60,6 +60,7 @@
#include <QtCore/qbytearray.h>
#include <QtCore/QElapsedTimer>
#include <QtCore/QVariant>
+#include <QtCore/qvector.h>
#if QT_CONFIG(regularexpression)
#include <QtCore/QRegularExpression>
#endif
@@ -73,6 +74,10 @@ QT_BEGIN_NAMESPACE
static void saveCoverageTool(const char * appname, bool testfailed, bool installedTestCoverage)
{
#ifdef __COVERAGESCANNER__
+# if QT_CONFIG(testlib_selfcover)
+ __coveragescanner_teststate(QTestLog::failCount() > 0 ? "FAILED" :
+ QTestLog::passCount() > 0 ? "PASSED" : "SKIPPED");
+# else
if (!installedTestCoverage)
return;
// install again to make sure the filename is correct.
@@ -83,6 +88,7 @@ static void saveCoverageTool(const char * appname, bool testfailed, bool install
__coveragescanner_testname("");
__coveragescanner_clear();
unsetenv("QT_TESTCOCOON_ACTIVE");
+# endif // testlib_selfcover
#else
Q_UNUSED(appname);
Q_UNUSED(testfailed);
@@ -93,6 +99,8 @@ static void saveCoverageTool(const char * appname, bool testfailed, bool install
static QElapsedTimer elapsedFunctionTime;
static QElapsedTimer elapsedTotalTime;
+#define FOREACH_TEST_LOGGER for (QAbstractTestLogger *logger : QTest::loggers)
+
namespace QTest {
int fails = 0;
@@ -160,109 +168,7 @@ namespace QTest {
static IgnoreResultList *ignoreResultList = 0;
- struct LoggerList
- {
- QAbstractTestLogger *logger;
- LoggerList *next;
- };
-
- class TestLoggers
- {
- public:
- static void addLogger(QAbstractTestLogger *logger)
- {
- LoggerList *l = new LoggerList;
- l->logger = logger;
- l->next = loggers;
- loggers = l;
- }
-
- static void destroyLoggers()
- {
- while (loggers) {
- LoggerList *l = loggers;
- loggers = loggers->next;
- delete l->logger;
- delete l;
- }
- }
-
-#define FOREACH_LOGGER(operation) \
- LoggerList *l = loggers; \
- while (l) { \
- QAbstractTestLogger *logger = l->logger; \
- Q_UNUSED(logger); \
- operation; \
- l = l->next; \
- }
-
- static void startLogging()
- {
- FOREACH_LOGGER(logger->startLogging());
- }
-
- static void stopLogging()
- {
- FOREACH_LOGGER(logger->stopLogging());
- }
-
- static void enterTestFunction(const char *function)
- {
- FOREACH_LOGGER(logger->enterTestFunction(function));
- }
-
- static void leaveTestFunction()
- {
- FOREACH_LOGGER(logger->leaveTestFunction());
- }
-
- static void enterTestData(QTestData *data)
- {
- FOREACH_LOGGER(logger->enterTestData(data));
- }
-
- static void addIncident(QAbstractTestLogger::IncidentTypes type, const char *description,
- const char *file = 0, int line = 0)
- {
- FOREACH_LOGGER(logger->addIncident(type, description, file, line));
- }
-
- static void addBenchmarkResult(const QBenchmarkResult &result)
- {
- FOREACH_LOGGER(logger->addBenchmarkResult(result));
- }
-
- static void addMessage(QtMsgType type, const QMessageLogContext &context,
- const QString &message)
- {
- FOREACH_LOGGER(logger->addMessage(type, context, message));
- }
-
- static void addMessage(QAbstractTestLogger::MessageTypes type, const QString &message,
- const char *file = 0, int line = 0)
- {
- FOREACH_LOGGER(logger->addMessage(type, message, file, line));
- }
-
- static void outputString(const char *msg)
- {
- FOREACH_LOGGER(logger->outputString(msg));
- }
-
- static int loggerCount()
- {
- int count = 0;
- FOREACH_LOGGER(++count);
- return count;
- }
-
- private:
- static LoggerList *loggers;
- };
-
-#undef FOREACH_LOGGER
-
- LoggerList *TestLoggers::loggers = 0;
+ static QVector<QAbstractTestLogger*> loggers;
static bool loggerUsingStdout = false;
static int verbosity = 0;
@@ -301,10 +207,10 @@ namespace QTest {
{
static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings);
- if (QTest::TestLoggers::loggerCount() == 0) {
+ if (QTestLog::loggerCount() == 0) {
// if this goes wrong, something is seriously broken.
qInstallMessageHandler(oldMessageHandler);
- QTEST_ASSERT(QTest::TestLoggers::loggerCount() != 0);
+ QTEST_ASSERT(QTestLog::loggerCount() != 0);
}
if (handleIgnoredMessage(type, message)) {
@@ -317,13 +223,16 @@ namespace QTest {
return;
if (!counter.deref()) {
- QTest::TestLoggers::addMessage(QAbstractTestLogger::QSystem,
+ FOREACH_TEST_LOGGER {
+ logger->addMessage(QAbstractTestLogger::QSystem,
QStringLiteral("Maximum amount of warnings exceeded. Use -maxwarnings to override."));
+ }
return;
}
}
- QTest::TestLoggers::addMessage(type, context, message);
+ FOREACH_TEST_LOGGER
+ logger->addMessage(type, context, message);
if (type == QtFatalMsg) {
/* Right now, we're inside the custom message handler and we're
@@ -346,13 +255,16 @@ void QTestLog::enterTestFunction(const char* function)
QTEST_ASSERT(function);
- QTest::TestLoggers::enterTestFunction(function);
+ FOREACH_TEST_LOGGER
+ logger->enterTestFunction(function);
}
void QTestLog::enterTestData(QTestData *data)
{
QTEST_ASSERT(data);
- QTest::TestLoggers::enterTestData(data);
+
+ FOREACH_TEST_LOGGER
+ logger->enterTestData(data);
}
int QTestLog::unhandledIgnoreMessages()
@@ -371,7 +283,8 @@ void QTestLog::leaveTestFunction()
if (printAvailableTags)
return;
- QTest::TestLoggers::leaveTestFunction();
+ FOREACH_TEST_LOGGER
+ logger->leaveTestFunction();
}
void QTestLog::printUnhandledIgnoreMessages()
@@ -386,7 +299,8 @@ void QTestLog::printUnhandledIgnoreMessages()
message = QStringLiteral("Did not receive any message matching: \"") + list->pattern.toRegularExpression().pattern() + QLatin1Char('"');
#endif
}
- QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, message);
+ FOREACH_TEST_LOGGER
+ logger->addMessage(QAbstractTestLogger::Info, message);
list = list->next;
}
@@ -406,7 +320,8 @@ void QTestLog::addPass(const char *msg)
++QTest::passes;
- QTest::TestLoggers::addIncident(QAbstractTestLogger::Pass, msg);
+ FOREACH_TEST_LOGGER
+ logger->addIncident(QAbstractTestLogger::Pass, msg);
}
void QTestLog::addFail(const char *msg, const char *file, int line)
@@ -415,7 +330,8 @@ void QTestLog::addFail(const char *msg, const char *file, int line)
++QTest::fails;
- QTest::TestLoggers::addIncident(QAbstractTestLogger::Fail, msg, file, line);
+ FOREACH_TEST_LOGGER
+ logger->addIncident(QAbstractTestLogger::Fail, msg, file, line);
}
void QTestLog::addXFail(const char *msg, const char *file, int line)
@@ -423,7 +339,8 @@ void QTestLog::addXFail(const char *msg, const char *file, int line)
QTEST_ASSERT(msg);
QTEST_ASSERT(file);
- QTest::TestLoggers::addIncident(QAbstractTestLogger::XFail, msg, file, line);
+ FOREACH_TEST_LOGGER
+ logger->addIncident(QAbstractTestLogger::XFail, msg, file, line);
}
void QTestLog::addXPass(const char *msg, const char *file, int line)
@@ -433,7 +350,8 @@ void QTestLog::addXPass(const char *msg, const char *file, int line)
++QTest::fails;
- QTest::TestLoggers::addIncident(QAbstractTestLogger::XPass, msg, file, line);
+ FOREACH_TEST_LOGGER
+ logger->addIncident(QAbstractTestLogger::XPass, msg, file, line);
}
void QTestLog::addBPass(const char *msg)
@@ -442,7 +360,8 @@ void QTestLog::addBPass(const char *msg)
++QTest::blacklists;
- QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedPass, msg);
+ FOREACH_TEST_LOGGER
+ logger->addIncident(QAbstractTestLogger::BlacklistedPass, msg);
}
void QTestLog::addBFail(const char *msg, const char *file, int line)
@@ -452,7 +371,30 @@ void QTestLog::addBFail(const char *msg, const char *file, int line)
++QTest::blacklists;
- QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedFail, msg, file, line);
+ FOREACH_TEST_LOGGER
+ logger->addIncident(QAbstractTestLogger::BlacklistedFail, msg, file, line);
+}
+
+void QTestLog::addBXPass(const char *msg, const char *file, int line)
+{
+ QTEST_ASSERT(msg);
+ QTEST_ASSERT(file);
+
+ ++QTest::blacklists;
+
+ FOREACH_TEST_LOGGER
+ logger->addIncident(QAbstractTestLogger::BlacklistedXPass, msg, file, line);
+}
+
+void QTestLog::addBXFail(const char *msg, const char *file, int line)
+{
+ QTEST_ASSERT(msg);
+ QTEST_ASSERT(file);
+
+ ++QTest::blacklists;
+
+ FOREACH_TEST_LOGGER
+ logger->addIncident(QAbstractTestLogger::BlacklistedXFail, msg, file, line);
}
void QTestLog::addSkip(const char *msg, const char *file, int line)
@@ -462,27 +404,33 @@ void QTestLog::addSkip(const char *msg, const char *file, int line)
++QTest::skips;
- QTest::TestLoggers::addMessage(QAbstractTestLogger::Skip, QString::fromUtf8(msg), file, line);
+ FOREACH_TEST_LOGGER
+ logger->addMessage(QAbstractTestLogger::Skip, QString::fromUtf8(msg), file, line);
}
void QTestLog::addBenchmarkResult(const QBenchmarkResult &result)
{
- QTest::TestLoggers::addBenchmarkResult(result);
+ FOREACH_TEST_LOGGER
+ logger->addBenchmarkResult(result);
}
void QTestLog::startLogging()
{
elapsedTotalTime.start();
elapsedFunctionTime.start();
- QTest::TestLoggers::startLogging();
+ FOREACH_TEST_LOGGER
+ logger->startLogging();
QTest::oldMessageHandler = qInstallMessageHandler(QTest::messageHandler);
}
void QTestLog::stopLogging()
{
qInstallMessageHandler(QTest::oldMessageHandler);
- QTest::TestLoggers::stopLogging();
- QTest::TestLoggers::destroyLoggers();
+ FOREACH_TEST_LOGGER {
+ logger->stopLogging();
+ delete logger;
+ }
+ QTest::loggers.clear();
QTest::loggerUsingStdout = false;
saveCoverageTool(QTestResult::currentAppName(), failCount() != 0, QTestLog::installedTestCoverage());
}
@@ -517,6 +465,11 @@ void QTestLog::addLogger(LogMode mode, const char *filename)
case QTestLog::TAP:
logger = new QTapTestLogger(filename);
break;
+#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
+ case QTestLog::Apple:
+ logger = new QAppleTestLogger;
+ break;
+#endif
#if defined(HAVE_XCTEST)
case QTestLog::XCTest:
logger = new QXcodeTestLogger;
@@ -524,21 +477,13 @@ void QTestLog::addLogger(LogMode mode, const char *filename)
#endif
}
-#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
- // Logger that also feeds messages to AUL. It needs to wrap the existing
- // logger, as it needs to be able to short circuit the existing logger
- // in case AUL prints to stderr.
- if (QAppleTestLogger::debugLoggingEnabled())
- logger = new QAppleTestLogger(logger);
-#endif
-
QTEST_ASSERT(logger);
- QTest::TestLoggers::addLogger(logger);
+ QTest::loggers.append(logger);
}
int QTestLog::loggerCount()
{
- return QTest::TestLoggers::loggerCount();
+ return QTest::loggers.size();
}
bool QTestLog::loggerUsingStdout()
@@ -550,15 +495,16 @@ void QTestLog::warn(const char *msg, const char *file, int line)
{
QTEST_ASSERT(msg);
- if (QTest::TestLoggers::loggerCount() > 0)
- QTest::TestLoggers::addMessage(QAbstractTestLogger::Warn, QString::fromUtf8(msg), file, line);
+ FOREACH_TEST_LOGGER
+ logger->addMessage(QAbstractTestLogger::Warn, QString::fromUtf8(msg), file, line);
}
void QTestLog::info(const char *msg, const char *file, int line)
{
QTEST_ASSERT(msg);
- QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, QString::fromUtf8(msg), file, line);
+ FOREACH_TEST_LOGGER
+ logger->addMessage(QAbstractTestLogger::Info, QString::fromUtf8(msg), file, line);
}
void QTestLog::setVerboseLevel(int level)
diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h
index 600c078ce2..e63e89a78e 100644
--- a/src/testlib/qtestlog_p.h
+++ b/src/testlib/qtestlog_p.h
@@ -53,6 +53,10 @@
#include <QtTest/qttestglobal.h>
+#if defined(Q_OS_DARWIN)
+#include <QtCore/private/qcore_mac_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QBenchmarkResult;
@@ -63,9 +67,12 @@ class Q_TESTLIB_EXPORT QTestLog
{
public:
enum LogMode {
- Plain = 0, XML, LightXML, XunitXML, CSV, TeamCity, TAP,
+ Plain = 0, XML, LightXML, XunitXML, CSV, TeamCity, TAP
+#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
+ , Apple
+#endif
#if defined(HAVE_XCTEST)
- XCTest
+ , XCTest
#endif
};
@@ -80,6 +87,8 @@ public:
static void addXPass(const char *msg, const char *file, int line);
static void addBPass(const char *msg);
static void addBFail(const char *msg, const char *file, int line);
+ static void addBXPass(const char *msg, const char *file, int line);
+ static void addBXFail(const char *msg, const char *file, int line);
static void addSkip(const char *msg, const char *file, int line);
static void addBenchmarkResult(const QBenchmarkResult &result);
diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp
index 88e3407c90..a7a4807e06 100644
--- a/src/testlib/qtestresult.cpp
+++ b/src/testlib/qtestresult.cpp
@@ -218,17 +218,24 @@ static bool checkStatement(bool statement, const char *msg, const char *file, in
{
if (statement) {
if (QTest::expectFailMode) {
- QTestLog::addXPass(msg, file, line);
+ if (QTest::blacklistCurrentTest)
+ QTestLog::addBXPass(msg, file, line);
+ else
+ QTestLog::addXPass(msg, file, line);
+
+ QTest::failed = true;
bool doContinue = (QTest::expectFailMode == QTest::Continue);
clearExpectFail();
- QTest::failed = true;
return doContinue;
}
return true;
}
if (QTest::expectFailMode) {
- QTestLog::addXFail(QTest::expectFailComment, file, line);
+ if (QTest::blacklistCurrentTest)
+ QTestLog::addBXFail(QTest::expectFailComment, file, line);
+ else
+ QTestLog::addXFail(QTest::expectFailComment, file, line);
bool doContinue = (QTest::expectFailMode == QTest::Continue);
clearExpectFail();
return doContinue;
diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp
index 72cb53bca7..c47042c3a0 100644
--- a/src/testlib/qxmltestlogger.cpp
+++ b/src/testlib/qxmltestlogger.cpp
@@ -91,6 +91,10 @@ namespace QTest {
return "bpass";
case QAbstractTestLogger::BlacklistedFail:
return "bfail";
+ case QAbstractTestLogger::BlacklistedXPass:
+ return "bxpass";
+ case QAbstractTestLogger::BlacklistedXFail:
+ return "bxfail";
}
return "??????";
}
@@ -136,8 +140,9 @@ void QXmlTestLogger::startLogging()
void QXmlTestLogger::stopLogging()
{
QTestCharBuffer buf;
- QTest::qt_asprintf(&buf,
- "<Duration msecs=\"%f\"/>\n", QTestLog::msecsTotalTime());
+
+ QTest::qt_asprintf(&buf, "<Duration msecs=\"%s\"/>\n",
+ QString::number(QTestLog::msecsTotalTime()).toUtf8().constData());
outputString(buf.constData());
if (xmlmode == QXmlTestLogger::Complete) {
outputString("</TestCase>\n");
@@ -159,9 +164,9 @@ void QXmlTestLogger::leaveTestFunction()
{
QTestCharBuffer buf;
QTest::qt_asprintf(&buf,
- " <Duration msecs=\"%f\"/>\n"
+ " <Duration msecs=\"%s\"/>\n"
"</TestFunction>\n",
- QTestLog::msecsFunctionTime());
+ QString::number(QTestLog::msecsFunctionTime()).toUtf8().constData());
outputString(buf.constData());
}
diff --git a/src/testlib/qxmltestlogger_p.h b/src/testlib/qxmltestlogger_p.h
index b85742f939..04ed57d587 100644
--- a/src/testlib/qxmltestlogger_p.h
+++ b/src/testlib/qxmltestlogger_p.h
@@ -71,11 +71,11 @@ public:
void leaveTestFunction() override;
void addIncident(IncidentTypes type, const char *description,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &result) override;
void addMessage(MessageTypes type, const QString &message,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
static int xmlCdata(QTestCharBuffer *dest, char const* src);
static int xmlQuote(QTestCharBuffer *dest, char const* src);
diff --git a/src/testlib/qxunittestlogger.cpp b/src/testlib/qxunittestlogger.cpp
index ec33c29ae5..336edb5994 100644
--- a/src/testlib/qxunittestlogger.cpp
+++ b/src/testlib/qxunittestlogger.cpp
@@ -180,6 +180,13 @@ void QXunitTestLogger::addIncident(IncidentTypes type, const char *description,
++failureCounter;
typeBuf = "bfail";
break;
+ case QAbstractTestLogger::BlacklistedXPass:
+ typeBuf = "bxpass";
+ break;
+ case QAbstractTestLogger::BlacklistedXFail:
+ ++failureCounter;
+ typeBuf = "bxfail";
+ break;
default:
typeBuf = "??????";
break;
@@ -212,11 +219,11 @@ void QXunitTestLogger::addIncident(IncidentTypes type, const char *description,
if (!strcmp(oldResult, "pass")) {
overwrite = true;
}
- else if (!strcmp(oldResult, "bpass")) {
+ else if (!strcmp(oldResult, "bpass") || !strcmp(oldResult, "bxfail")) {
overwrite = (type == QAbstractTestLogger::XPass || type == QAbstractTestLogger::Fail) || (type == QAbstractTestLogger::XFail)
- || (type == QAbstractTestLogger::BlacklistedFail);
+ || (type == QAbstractTestLogger::BlacklistedFail) || (type == QAbstractTestLogger::BlacklistedXPass);
}
- else if (!strcmp(oldResult, "bfail")) {
+ else if (!strcmp(oldResult, "bfail") || !strcmp(oldResult, "bxpass")) {
overwrite = (type == QAbstractTestLogger::XPass || type == QAbstractTestLogger::Fail) || (type == QAbstractTestLogger::XFail);
}
else if (!strcmp(oldResult, "xfail")) {
diff --git a/src/testlib/qxunittestlogger_p.h b/src/testlib/qxunittestlogger_p.h
index 8fb01fbe61..48f07ddcf2 100644
--- a/src/testlib/qxunittestlogger_p.h
+++ b/src/testlib/qxunittestlogger_p.h
@@ -71,12 +71,12 @@ class QXunitTestLogger : public QAbstractTestLogger
void leaveTestFunction() override;
void addIncident(IncidentTypes type, const char *description,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &result) override;
void addTag(QTestElement* element);
void addMessage(MessageTypes type, const QString &message,
- const char *file = 0, int line = 0) override;
+ const char *file = nullptr, int line = 0) override;
private:
QTestElement *listOfTestcases;
diff --git a/src/testlib/selfcover.pri b/src/testlib/selfcover.pri
new file mode 100644
index 0000000000..7de50ba6e6
--- /dev/null
+++ b/src/testlib/selfcover.pri
@@ -0,0 +1,28 @@
+# Configuration for testlib and its tests, to instrument with
+# FrogLogic's Squish CoCo (cf. testcocoon.prf, which handles similar
+# for general code; but testlib needs special handling).
+
+# Only for use when feature testlib_selfcover is enabled:
+!qtConfig(testlib_selfcover): return()
+
+# This enables verification that testlib itself is adequately tested,
+# as a grounds for trusting that testing with it is useful.
+# Exclude all non-testlib source from coverage instrumentation:
+COVERAGE_OPTIONS = --cs-exclude-file-abs-wildcard=$$QT_SOURCE_TREE/*
+COVERAGE_OPTIONS += --cs-include-file-abs-wildcard=*/src/testlib/*
+COVERAGE_OPTIONS += --cs-mcc # enable Multiple Condition Coverage
+COVERAGE_OPTIONS += --cs-mcdc # enable Multiple Condition / Decision Coverage
+# (recommended for ISO 26262 ASIL A, B and C -- highly recommended for ASIL D)
+# https://doc.froglogic.com/squish-coco/4.1/codecoverage.html#sec%3Amcdc
+
+QMAKE_CFLAGS += $$COVERAGE_OPTIONS
+QMAKE_CXXFLAGS += $$COVERAGE_OPTIONS
+QMAKE_LFLAGS += $$COVERAGE_OPTIONS
+
+# FIXME: relies on QMAKE_* being just the command-names, with no path prefix
+QMAKE_CC = cs$$QMAKE_CC
+QMAKE_CXX = cs$$QMAKE_CXX
+QMAKE_LINK = cs$$QMAKE_LINK
+QMAKE_LINK_SHLIB = cs$$QMAKE_LINK_SHLIB
+QMAKE_AR = cs$$QMAKE_AR
+QMAKE_LIB = cs$$QMAKE_LIB
diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro
index 46b61dac07..f52a913a08 100644
--- a/src/testlib/testlib.pro
+++ b/src/testlib/testlib.pro
@@ -12,6 +12,7 @@ unix:!embedded:QMAKE_PKGCONFIG_DESCRIPTION = Qt \
QMAKE_DOCS = $$PWD/doc/qttestlib.qdocconf
HEADERS = \
+ qabstracttestlogger_p.h \
qbenchmark.h \
qbenchmark_p.h \
qbenchmarkmeasurement_p.h \
@@ -21,10 +22,16 @@ HEADERS = \
qbenchmarkperfevents_p.h \
qbenchmarkmetric.h \
qbenchmarkmetric_p.h \
+ qcsvbenchmarklogger_p.h \
+ qplaintestlogger_p.h \
+ qsignaldumper_p.h \
qsignalspy.h \
+ qteamcitylogger_p.h \
qtestaccessible.h \
qtestassert.h \
qtestcase.h \
+ qtestcoreelement_p.h \
+ qtestcorelist_p.h \
qtestdata.h \
qtestevent.h \
qtesteventloop.h \
@@ -32,15 +39,23 @@ HEADERS = \
qtest_network.h \
qtest_widgets.h \
qtest.h \
+ qtestelement_p.h \
+ qtestelementattribute_p.h \
qtestkeyboard.h \
+ qtestlog_p.h \
qtestmouse.h \
+ qtestresult_p.h \
qtestspontaneevent.h \
qtestsystem.h \
+ qtesttable_p.h \
qtesttouch.h \
qtestblacklist_p.h \
qtesthelpers_p.h \
qttestglobal.h \
- qtaptestlogger_p.h
+ qtestxunitstreamer_p.h \
+ qtaptestlogger_p.h \
+ qxmltestlogger_p.h \
+ qxunittestlogger_p.h
SOURCES = \
qtestcase.cpp \
@@ -131,4 +146,5 @@ mac {
!qtHaveModule(network): HEADERSCLEAN_EXCLUDE += qtest_network.h
+include(selfcover.pri)
load(qt_module)