4#include <QtTest/private/qtestresult_p.h>
5#include <QtCore/qglobal.h>
6#include <QtCore/qstringview.h>
8#include <QtTest/private/qtestlog_p.h>
9#include <QtTest/qtest.h>
10#include <QtTest/qtestdata.h>
11#include <QtTest/qtestcase.h>
12#include <QtTest/qtestassert.h>
13#include <QtTest/qtesteventloop.h>
17#include <QtCore/q26numeric.h>
35 static const bool fatalFailure = []() {
36 static const char *
const environmentVar =
"QTEST_FATAL_FAIL";
37 if (!qEnvironmentVariableIsSet(environmentVar))
41 const int fatal = qEnvironmentVariableIntValue(environmentVar, &ok);
45 if (failed && fatalFailure)
71void QTestResult::reset()
73 QTest::currentTestData =
nullptr;
74 QTest::currentGlobalTestData =
nullptr;
75 QTest::currentTestFunc =
nullptr;
76 QTest::currentTestObjectName =
nullptr;
79 QTest::expectFailComment =
nullptr;
80 QTest::expectFailMode = 0;
81 QTest::blacklistCurrentTest =
false;
83 QTestLog::resetCounters();
86void QTestResult::setBlacklistCurrentTest(
bool b)
88 QTest::blacklistCurrentTest = b;
91bool QTestResult::currentTestFailed()
93 return QTest::hasFailed();
96QTestData *QTestResult::currentGlobalTestData()
98 return QTest::currentGlobalTestData;
101QTestData *QTestResult::currentTestData()
103 return QTest::currentTestData;
106void QTestResult::setCurrentGlobalTestData(QTestData *data)
108 QTest::currentGlobalTestData = data;
111void QTestResult::setCurrentTestData(QTestData *data)
113 QTest::currentTestData = data;
114 QTest::resetFailed();
116 QTestLog::enterTestData(data);
119void QTestResult::setCurrentTestFunction(
const char *func)
121 QTest::currentTestFunc = func;
122 QTest::resetFailed();
124 QTestLog::enterTestFunction(func);
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150void QTestResult::finishedCurrentTestData()
152 if (QTest::expectFailMode)
153 addFailure(
"QEXPECT_FAIL was called without any subsequent verification statements");
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173void QTestResult::finishedCurrentTestDataCleanup()
175 if (!QTest::hasFailed() && QTestLog::unhandledIgnoreMessages()) {
176 QTestLog::printUnhandledIgnoreMessages();
177 addFailure(
"Not all expected messages were received");
181 if (!QTest::hasFailed() && !QTest::skipCurrentTest) {
182 if (QTest::blacklistCurrentTest)
183 QTestLog::addBPass(
"");
185 QTestLog::addPass(
"");
188 QTestLog::clearCurrentTestState();
189 QTest::resetFailed();
193
194
195
196
197
198
199
200void QTestResult::finishedCurrentTestFunction()
202 QTestLog::clearCurrentTestState();
203 QTestLog::leaveTestFunction();
205 QTest::currentTestFunc =
nullptr;
206 QTest::resetFailed();
209const char *QTestResult::currentTestFunction()
211 return QTest::currentTestFunc;
214const char *QTestResult::currentDataTag()
216 return QTest::currentTestData ? QTest::currentTestData->dataTag() :
nullptr;
219const char *QTestResult::currentGlobalDataTag()
221 return QTest::currentGlobalTestData ? QTest::currentGlobalTestData->dataTag() :
nullptr;
226 if (!dataIndex || dataIndex[0] ==
'\0')
228 if (!QTest::currentTestData)
230 if (strcmp(dataIndex, QTest::currentTestData->dataTag()) == 0)
235bool QTestResult::expectFail(
const char *dataIndex,
const char *comment,
236 QTest::TestFailMode mode,
const char *file,
int line)
238 QTEST_ASSERT(comment);
239 QTEST_ASSERT(mode > 0);
241 if (!isExpectFailData(dataIndex)) {
246 if (QTest::expectFailMode) {
248 addFailure(
"Already expecting a fail", file, line);
252 QTest::expectFailMode = mode;
253 QTest::expectFailComment = comment;
257static bool checkStatement(
bool statement,
const char *msg,
const char *file,
int line)
261 if (QTest::blacklistCurrentTest)
262 QTestLog::addBXPass(msg, file, line);
264 QTestLog::addXPass(msg, file, line);
268 bool doContinue = (QTest::expectFailMode == QTest::Continue);
276 if (QTest::blacklistCurrentTest)
277 QTestLog::addBXFail(QTest::expectFailComment, file, line);
279 QTestLog::addXFail(QTest::expectFailComment, file, line);
280 bool doContinue = (QTest::expectFailMode == QTest::Continue);
285 QTestResult::addFailure(msg, file, line);
289void QTestResult::fail(
const char *msg,
const char *file,
int line)
291 checkStatement(
false, msg, file, line);
300bool QTestResult::verify(
bool statement,
const char *statementStr,
301 const char *description,
const char *file,
int line)
303 QTEST_ASSERT(statementStr);
305 Q_DECL_UNINITIALIZED
char msg[maxMsgLen];
308 if (QTestLog::verboseLevel() >= 2) {
309 std::snprintf(msg, maxMsgLen,
"QVERIFY(%s)", statementStr);
310 QTestLog::info(msg, file, line);
313 if (statement == !!QTest::expectFailMode) {
314 std::snprintf(msg, maxMsgLen,
315 statement ?
"'%s' returned TRUE unexpectedly. (%s)" :
"'%s' returned FALSE. (%s)",
316 statementStr, description ? description :
"");
319 return checkStatement(statement, msg, file, line);
325 case QTest::ComparisonOperation::CustomCompare:
327 case QTest::ComparisonOperation::ThreeWayCompare:
329 case QTest::ComparisonOperation::Equal:
330 case QTest::ComparisonOperation::NotEqual:
331 case QTest::ComparisonOperation::LessThan:
332 case QTest::ComparisonOperation::LessThanOrEqual:
333 case QTest::ComparisonOperation::GreaterThan:
334 case QTest::ComparisonOperation::GreaterThanOrEqual:
337 Q_UNREACHABLE_RETURN(
"");
343 case QTest::ComparisonOperation::CustomCompare:
345 case QTest::ComparisonOperation::ThreeWayCompare:
347 case QTest::ComparisonOperation::Equal:
348 case QTest::ComparisonOperation::NotEqual:
349 case QTest::ComparisonOperation::LessThan:
350 case QTest::ComparisonOperation::LessThanOrEqual:
351 case QTest::ComparisonOperation::GreaterThan:
352 case QTest::ComparisonOperation::GreaterThanOrEqual:
355 Q_UNREACHABLE_RETURN(
"");
360 std::mbstate_t state = {};
363 auto r = std::mbsrtowcs(
nullptr, &s, INT_MAX, &state);
366 return q26::saturate_cast<
int>(r);
372 const char *failureMsg,
373 const char *val1,
const char *val2,
374 const char *actual,
const char *expected,
375 QTest::ComparisonOperation op)
379 const int written = std::snprintf(msg, maxMsgLen,
"%s\n", failureMsg);
381 maxMsgLen -= written;
383 const auto protect = [](
const char *s) {
return s ? s :
"<null>"; };
386 std::snprintf(msg, maxMsgLen,
" %s(%s)%*s %s\n %s(%s)%*s %s",
387 leftArgNameForOp(op), actual, qMax(len1, len2) - len1 + 1,
":",
389 rightArgNameForOp(op), expected, qMax(len1, len2) - len2 + 1,
":",
393 std::snprintf(msg, maxMsgLen,
" %s: %s\n %s: %s",
394 leftArgNameForOp(op), actual, rightArgNameForOp(op), expected);
400 const char *actual,
const char *expected,
401 const char *actualExpr,
const char *expectedExpr)
403 formatFailMessage(msg, maxMsgLen,
"Comparison failed!",
404 actual, expected, actualExpr, expectedExpr,
405 QTest::ComparisonOperation::CustomCompare);
410template <
class Actual,
class Expected>
413 const char *failureMsg,
414 const Actual &val1,
const Expected &val2,
415 const char *actual,
const char *expected,
416 QTest::ComparisonOperation op)
418 const char *val1S = QTest::toString(val1);
419 const char *val2S = QTest::toString(val2);
421 formatFailMessage(msg, maxMsgLen, failureMsg, val1S, val2S, actual, expected, op);
427template <
class Actual,
class Expected>
429 const Actual &val1,
const Expected &val2,
430 const char *actual,
const char *expected,
431 const char *file,
int line,
432 bool hasValues =
true)
434 Q_DECL_UNINITIALIZED
char msg[maxMsgLen];
437 QTEST_ASSERT(expected);
438 QTEST_ASSERT(actual);
440 if (QTestLog::verboseLevel() >= 2) {
441 std::snprintf(msg, maxMsgLen,
"QCOMPARE(%s, %s)", actual, expected);
442 QTestLog::info(msg, file, line);
446 failureMsg =
"Compared values are not the same";
450 std::snprintf(msg, maxMsgLen,
451 "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected);
453 return checkStatement(success, msg, file, line);
458 std::snprintf(msg, maxMsgLen,
"%s", failureMsg);
459 return checkStatement(success, msg, file, line);
462 formatFailMessage(msg, maxMsgLen, failureMsg, val1, val2, actual, expected,
463 QTest::ComparisonOperation::CustomCompare);
465 return checkStatement(success, msg, file, line);
472 const char *actual,
const char *expected,
473 const char *file,
int line)
475 const size_t maxMsgLen = 1024;
476 Q_DECL_UNINITIALIZED
char msg[maxMsgLen];
479 QTEST_ASSERT(expected);
480 QTEST_ASSERT(actual);
482 QTEST_ASSERT(success || failureMsg);
484 if (QTestLog::verboseLevel() >= 2) {
485 std::snprintf(msg, maxMsgLen,
"QCOMPARE(%s, %s)", actual, expected);
486 QTestLog::info(msg, file, line);
491 std::snprintf(msg, maxMsgLen,
"QCOMPARE(%s, %s) returned TRUE unexpectedly.",
494 return checkStatement(success, msg, file, line);
500bool QTestResult::compare(
bool success,
const char *failureMsg,
501 char *val1,
char *val2,
502 const char *actual,
const char *expected,
503 const char *file,
int line)
505 const bool result = compareHelper(success, failureMsg,
506 val1 !=
nullptr ? val1 :
"<null>",
507 val2 !=
nullptr ? val2 :
"<null>",
508 actual, expected, file, line,
509 val1 !=
nullptr && val2 !=
nullptr);
518bool QTestResult::compare(
bool success,
const char *failureMsg,
519 double val1,
double val2,
520 const char *actual,
const char *expected,
521 const char *file,
int line)
523 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
526bool QTestResult::compare(
bool success,
const char *failureMsg,
527 float val1,
float val2,
528 const char *actual,
const char *expected,
529 const char *file,
int line)
531 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
534bool QTestResult::compare(
bool success,
const char *failureMsg,
536 const char *actual,
const char *expected,
537 const char *file,
int line)
539 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
542#if QT_POINTER_SIZE == 8
543bool QTestResult::compare(
bool success,
const char *failureMsg,
544 qsizetype val1, qsizetype val2,
545 const char *actual,
const char *expected,
546 const char *file,
int line)
548 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
552bool QTestResult::compare(
bool success,
const char *failureMsg,
553 unsigned val1,
unsigned val2,
554 const char *actual,
const char *expected,
555 const char *file,
int line)
557 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
560bool QTestResult::compare(
bool success,
const char *failureMsg,
561 QStringView val1, QStringView val2,
562 const char *actual,
const char *expected,
563 const char *file,
int line)
565 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
568bool QTestResult::compare(
bool success,
const char *failureMsg,
569 QStringView val1,
const QLatin1StringView &val2,
570 const char *actual,
const char *expected,
571 const char *file,
int line)
573 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
576bool QTestResult::compare(
bool success,
const char *failureMsg,
577 const QLatin1StringView & val1, QStringView val2,
578 const char *actual,
const char *expected,
579 const char *file,
int line)
581 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
586bool QTestResult::compare(
bool success,
const char *failureMsg,
587 const char *actual,
const char *expeceted,
588 const char *file,
int line)
590 return compareHelper(success, failureMsg, actual, expeceted, file, line);
593void QTestResult::addFailure(
const char *message,
const char *file,
int line)
596 if (qApp && QThread::currentThread() == qApp->thread())
597 QTestEventLoop::instance().exitLoop();
599 if (QTest::blacklistCurrentTest)
600 QTestLog::addBFail(message, file, line);
602 QTestLog::addFail(message, file, line);
603 QTest::setFailed(
true);
606void QTestResult::addSkip(
const char *message,
const char *file,
int line)
610 QTestLog::addSkip(message, file, line);
613void QTestResult::setCurrentTestObject(
const char *name)
615 QTest::currentTestObjectName = name;
618const char *QTestResult::currentTestObjectName()
620 return QTest::currentTestObjectName ? QTest::currentTestObjectName :
"";
623void QTestResult::setSkipCurrentTest(
bool value)
625 QTest::skipCurrentTest = value;
628bool QTestResult::skipCurrentTest()
630 return QTest::skipCurrentTest;
633void QTestResult::setCurrentAppName(
const char *appName)
635 ::currentAppName = appName;
638const char *QTestResult::currentAppName()
640 return ::currentAppName;
645 using namespace QTest;
647 case ComparisonOperation::CustomCompare:
649 case ComparisonOperation::Equal:
650 return "QCOMPARE_EQ";
651 case ComparisonOperation::NotEqual:
652 return "QCOMPARE_NE";
653 case ComparisonOperation::LessThan:
654 return "QCOMPARE_LT";
655 case ComparisonOperation::LessThanOrEqual:
656 return "QCOMPARE_LE";
657 case ComparisonOperation::GreaterThan:
658 return "QCOMPARE_GT";
659 case ComparisonOperation::GreaterThanOrEqual:
660 return "QCOMPARE_GE";
661 case ComparisonOperation::ThreeWayCompare:
662 return "QCOMPARE_3WAY";
664 Q_UNREACHABLE_RETURN(
"");
669 using namespace QTest;
671 case ComparisonOperation::CustomCompare:
672 return "Compared values are not the same";
673 case ComparisonOperation::ThreeWayCompare:
674 return "The result of operator<=>() is not what was expected";
675 case ComparisonOperation::Equal:
676 return "The computed value is expected to be equal to the baseline, but is not";
677 case ComparisonOperation::NotEqual:
678 return "The computed value is expected to be different from the baseline, but is not";
679 case ComparisonOperation::LessThan:
680 return "The computed value is expected to be less than the baseline, but is not";
681 case ComparisonOperation::LessThanOrEqual:
682 return "The computed value is expected to be less than or equal to the baseline, but is not";
683 case ComparisonOperation::GreaterThan:
684 return "The computed value is expected to be greater than the baseline, but is not";
685 case ComparisonOperation::GreaterThanOrEqual:
686 return "The computed value is expected to be greater than or equal to the baseline, but is not";
688 Q_UNREACHABLE_RETURN(
"");
691bool QTestResult::reportResult(
bool success,
const void *lhs,
const void *rhs,
692 const char *(*lhsFormatter)(
const void*),
693 const char *(*rhsFormatter)(
const void*),
694 const char *lhsExpr,
const char *rhsExpr,
695 QTest::ComparisonOperation op,
const char *file,
int line,
696 const char *failureMessage)
698 Q_DECL_UNINITIALIZED
char msg[maxMsgLen];
701 QTEST_ASSERT(lhsExpr);
702 QTEST_ASSERT(rhsExpr);
704 if (QTestLog::verboseLevel() >= 2) {
705 std::snprintf(msg, maxMsgLen,
"%s(%s, %s)", macroNameForOp(op), lhsExpr, rhsExpr);
706 QTestLog::info(msg, file, line);
710 if (QTest::expectFailMode) {
711 std::snprintf(msg, maxMsgLen,
"%s(%s, %s) returned TRUE unexpectedly.",
712 macroNameForOp(op), lhsExpr, rhsExpr);
714 return checkStatement(success, msg, file, line);
717 const std::unique_ptr<
const char[]> lhsPtr{ lhsFormatter(lhs) };
718 const std::unique_ptr<
const char[]> rhsPtr{ rhsFormatter(rhs) };
721 failureMessage = failureMessageForOp(op);
723 formatFailMessage(msg, maxMsgLen, failureMessage, lhsPtr.get(), rhsPtr.get(),
724 lhsExpr, rhsExpr, op);
726 return checkStatement(success, msg, file, line);
729bool QTestResult::report3WayResult(
bool success,
730 const char *failureMessage,
731 const void *lhs,
const void *rhs,
732 const char *(*lhsFormatter)(
const void*),
733 const char *(*rhsFormatter)(
const void*),
734 const char *lhsExpression,
const char *rhsExpression,
735 const char *(*actualOrderFormatter)(
const void *),
736 const char *(*expectedOrderFormatter)(
const void *),
737 const void *actualOrder,
const void *expectedOrder,
738 const char *expectedExpression,
739 const char *file,
int line)
744 QTEST_ASSERT(lhsExpression);
745 QTEST_ASSERT(rhsExpression);
746 QTEST_ASSERT(expectedExpression);
747 const char *macroName = macroNameForOp(QTest::ComparisonOperation::ThreeWayCompare);
748 const std::string actualExpression = std::string(lhsExpression) +
" <=> " + rhsExpression;
750 if (QTestLog::verboseLevel() >= 2) {
751 std::snprintf(msg, maxMsgLen,
"%s(%s, %s, %s)",
752 macroName, lhsExpression, rhsExpression, expectedExpression);
753 QTestLog::info(msg, file, line);
757 if (QTest::expectFailMode) {
758 std::snprintf(msg, maxMsgLen,
"%s(%s, %s, %s) returned TRUE unexpectedly.",
759 macroName, lhsExpression, rhsExpression, expectedExpression);
761 return checkStatement(success, msg, file, line);
763 const std::unique_ptr<
const char[]> lhsStr{lhsFormatter(lhs)};
764 const std::unique_ptr<
const char[]> rhsStr{rhsFormatter(rhs)};
766 const std::unique_ptr<
const char[]> actual{actualOrderFormatter(actualOrder)};
767 const std::unique_ptr<
const char[]> expected{expectedOrderFormatter(expectedOrder)};
770 failureMessage = failureMessageForOp(QTest::ComparisonOperation::ThreeWayCompare);
773 formatFailMessage(msg, maxMsgLen, failureMessage,
774 lhsStr.get(), rhsStr.get(),
775 lhsExpression, rhsExpression,
776 QTest::ComparisonOperation::ThreeWayCompare);
779 formatFailMessage(msg + strlen(msg), maxMsgLen - strlen(msg),
"",
780 actual.get(), expected.get(),
781 actualExpression.c_str(), expectedExpression,
782 QTest::ComparisonOperation::CustomCompare);
784 return checkStatement(success, msg, file, line);
Q_TESTLIB_EXPORT Q_DECL_COLD_FUNCTION const char * formatPropertyTestHelperFailure(char *msg, size_t maxMsgLen, const char *actual, const char *expected, const char *actualExpr, const char *expectedExpr)
static void resetFailed()
static const char * expectFailComment
static bool skipCurrentTest
static bool blacklistCurrentTest
static const char * currentTestFunc
static void setFailed(bool failed)
static const char * currentTestObjectName
static QTestData * currentTestData
static QTestData * currentGlobalTestData
static int expectFailMode
static Q_DECL_COLD_FUNCTION void formatFailMessage(char *msg, size_t maxMsgLen, const char *failureMsg, const Actual &val1, const Expected &val2, const char *actual, const char *expected, QTest::ComparisonOperation op)
static Q_DECL_COLD_FUNCTION void formatFailMessage(char *msg, size_t maxMsgLen, const char *failureMsg, const char *val1, const char *val2, const char *actual, const char *expected, QTest::ComparisonOperation op)
static bool checkStatement(bool statement, const char *msg, const char *file, int line)
static bool isExpectFailData(const char *dataIndex)
static const char * rightArgNameForOp(QTest::ComparisonOperation op)
static constexpr size_t maxMsgLen
static const char * failureMessageForOp(QTest::ComparisonOperation op)
static int approx_wide_len(const char *s)
static bool compareHelper(bool success, const char *failureMsg, const char *actual, const char *expected, const char *file, int line)
static const char * currentAppName
static bool compareHelper(bool success, const char *failureMsg, const Actual &val1, const Expected &val2, const char *actual, const char *expected, const char *file, int line, bool hasValues=true)
static const char * macroNameForOp(QTest::ComparisonOperation op)
static const char * leftArgNameForOp(QTest::ComparisonOperation op)
static void clearExpectFail()