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)
72
73
74
75
77void QTestResult::reset()
79 QTest::currentTestData =
nullptr;
80 QTest::currentGlobalTestData =
nullptr;
81 QTest::currentTestFunc =
nullptr;
82 QTest::currentTestObjectName =
nullptr;
85 QTest::expectFailComment =
nullptr;
86 QTest::expectFailMode = 0;
87 QTest::blacklistCurrentTest =
false;
89 QTestLog::resetCounters();
92void QTestResult::setBlacklistCurrentTest(
bool b)
94 QTest::blacklistCurrentTest = b;
97bool QTestResult::currentTestFailed()
99 return QTest::hasFailed();
102QTestData *QTestResult::currentGlobalTestData()
104 return QTest::currentGlobalTestData;
107QTestData *QTestResult::currentTestData()
109 return QTest::currentTestData;
112void QTestResult::setCurrentGlobalTestData(QTestData *data)
114 QTest::currentGlobalTestData = data;
117void QTestResult::setCurrentTestData(QTestData *data)
119 QTest::currentTestData = data;
120 QTest::resetFailed();
122 QTestLog::enterTestData(data);
125void QTestResult::setCurrentTestFunction(
const char *func)
127 QTest::currentTestFunc = func;
128 QTest::resetFailed();
130 QTestLog::enterTestFunction(func);
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156void QTestResult::finishedCurrentTestData()
158 if (QTest::expectFailMode)
159 addFailure(
"QEXPECT_FAIL was called without any subsequent verification statements");
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179void QTestResult::finishedCurrentTestDataCleanup()
181 if (!QTest::hasFailed() && QTestLog::unhandledIgnoreMessages()) {
182 QTestLog::printUnhandledIgnoreMessages();
183 addFailure(
"Not all expected messages were received");
187 if (!QTest::hasFailed() && !QTest::skipCurrentTest) {
188 if (QTest::blacklistCurrentTest)
189 QTestLog::addBPass(
"");
191 QTestLog::addPass(
"");
194 QTestLog::clearCurrentTestState();
195 QTest::resetFailed();
199
200
201
202
203
204
205
206void QTestResult::finishedCurrentTestFunction()
208 QTestLog::clearCurrentTestState();
209 QTestLog::leaveTestFunction();
211 QTest::currentTestFunc =
nullptr;
212 QTest::resetFailed();
215const char *QTestResult::currentTestFunction()
217 return QTest::currentTestFunc;
220const char *QTestResult::currentDataTag()
222 return QTest::currentTestData ? QTest::currentTestData->dataTag() :
nullptr;
225const char *QTestResult::currentGlobalDataTag()
227 return QTest::currentGlobalTestData ? QTest::currentGlobalTestData->dataTag() :
nullptr;
232 if (!dataIndex || dataIndex[0] ==
'\0')
234 if (!QTest::currentTestData)
236 if (strcmp(dataIndex, QTest::currentTestData->dataTag()) == 0)
241bool QTestResult::expectFail(
const char *dataIndex,
const char *comment,
242 QTest::TestFailMode mode,
const char *file,
int line)
244 QTEST_ASSERT(comment);
245 QTEST_ASSERT(mode > 0);
247 if (!isExpectFailData(dataIndex)) {
252 if (QTest::expectFailMode) {
254 addFailure(
"Already expecting a fail", file, line);
258 QTest::expectFailMode = mode;
259 QTest::expectFailComment = comment;
263static bool checkStatement(
bool statement,
const char *msg,
const char *file,
int line)
267 if (QTest::blacklistCurrentTest)
268 QTestLog::addBXPass(msg, file, line);
270 QTestLog::addXPass(msg, file, line);
274 bool doContinue = (QTest::expectFailMode == QTest::Continue);
282 if (QTest::blacklistCurrentTest)
283 QTestLog::addBXFail(QTest::expectFailComment, file, line);
285 QTestLog::addXFail(QTest::expectFailComment, file, line);
286 bool doContinue = (QTest::expectFailMode == QTest::Continue);
291 QTestResult::addFailure(msg, file, line);
295void QTestResult::fail(
const char *msg,
const char *file,
int line)
297 checkStatement(
false, msg, file, line);
306bool QTestResult::verify(
bool statement,
const char *statementStr,
307 const char *description,
const char *file,
int line)
309 QTEST_ASSERT(statementStr);
311 Q_DECL_UNINITIALIZED
char msg[maxMsgLen];
314 if (QTestLog::verboseLevel() >= 2) {
315 std::snprintf(msg, maxMsgLen,
"QVERIFY(%s)", statementStr);
316 QTestLog::info(msg, file, line);
319 if (statement == !!QTest::expectFailMode) {
320 std::snprintf(msg, maxMsgLen,
321 statement ?
"'%s' returned TRUE unexpectedly. (%s)" :
"'%s' returned FALSE. (%s)",
322 statementStr, description ? description :
"");
325 return checkStatement(statement, msg, file, line);
331 case QTest::ComparisonOperation::CustomCompare:
333 case QTest::ComparisonOperation::ThreeWayCompare:
335 case QTest::ComparisonOperation::Equal:
336 case QTest::ComparisonOperation::NotEqual:
337 case QTest::ComparisonOperation::LessThan:
338 case QTest::ComparisonOperation::LessThanOrEqual:
339 case QTest::ComparisonOperation::GreaterThan:
340 case QTest::ComparisonOperation::GreaterThanOrEqual:
343 Q_UNREACHABLE_RETURN(
"");
349 case QTest::ComparisonOperation::CustomCompare:
351 case QTest::ComparisonOperation::ThreeWayCompare:
353 case QTest::ComparisonOperation::Equal:
354 case QTest::ComparisonOperation::NotEqual:
355 case QTest::ComparisonOperation::LessThan:
356 case QTest::ComparisonOperation::LessThanOrEqual:
357 case QTest::ComparisonOperation::GreaterThan:
358 case QTest::ComparisonOperation::GreaterThanOrEqual:
361 Q_UNREACHABLE_RETURN(
"");
366 std::mbstate_t state = {};
369 auto r = std::mbsrtowcs(
nullptr, &s, INT_MAX, &state);
372 return q26::saturate_cast<
int>(r);
378 const char *failureMsg,
379 const char *val1,
const char *val2,
380 const char *actual,
const char *expected,
381 QTest::ComparisonOperation op)
385 const int written = std::snprintf(msg, maxMsgLen,
"%s\n", failureMsg);
387 maxMsgLen -= written;
389 const auto protect = [](
const char *s) {
return s ? s :
"<null>"; };
392 std::snprintf(msg, maxMsgLen,
" %s(%s)%*s %s\n %s(%s)%*s %s",
393 leftArgNameForOp(op), actual, qMax(len1, len2) - len1 + 1,
":",
395 rightArgNameForOp(op), expected, qMax(len1, len2) - len2 + 1,
":",
399 std::snprintf(msg, maxMsgLen,
" %s: %s\n %s: %s",
400 leftArgNameForOp(op), actual, rightArgNameForOp(op), expected);
406 const char *actual,
const char *expected,
407 const char *actualExpr,
const char *expectedExpr)
409 formatFailMessage(msg, maxMsgLen,
"Comparison failed!",
410 actual, expected, actualExpr, expectedExpr,
411 QTest::ComparisonOperation::CustomCompare);
416template <
class Actual,
class Expected>
419 const char *failureMsg,
420 const Actual &val1,
const Expected &val2,
421 const char *actual,
const char *expected,
422 QTest::ComparisonOperation op)
424 const char *val1S = QTest::toString(val1);
425 const char *val2S = QTest::toString(val2);
427 formatFailMessage(msg, maxMsgLen, failureMsg, val1S, val2S, actual, expected, op);
433template <
class Actual,
class Expected>
435 const Actual &val1,
const Expected &val2,
436 const char *actual,
const char *expected,
437 const char *file,
int line,
438 bool hasValues =
true)
440 Q_DECL_UNINITIALIZED
char msg[maxMsgLen];
443 QTEST_ASSERT(expected);
444 QTEST_ASSERT(actual);
446 if (QTestLog::verboseLevel() >= 2) {
447 std::snprintf(msg, maxMsgLen,
"QCOMPARE(%s, %s)", actual, expected);
448 QTestLog::info(msg, file, line);
452 failureMsg =
"Compared values are not the same";
456 std::snprintf(msg, maxMsgLen,
457 "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected);
459 return checkStatement(success, msg, file, line);
464 std::snprintf(msg, maxMsgLen,
"%s", failureMsg);
465 return checkStatement(success, msg, file, line);
468 formatFailMessage(msg, maxMsgLen, failureMsg, val1, val2, actual, expected,
469 QTest::ComparisonOperation::CustomCompare);
471 return checkStatement(success, msg, file, line);
478 const char *actual,
const char *expected,
479 const char *file,
int line)
481 const size_t maxMsgLen = 1024;
482 Q_DECL_UNINITIALIZED
char msg[maxMsgLen];
485 QTEST_ASSERT(expected);
486 QTEST_ASSERT(actual);
488 QTEST_ASSERT(success || failureMsg);
490 if (QTestLog::verboseLevel() >= 2) {
491 std::snprintf(msg, maxMsgLen,
"QCOMPARE(%s, %s)", actual, expected);
492 QTestLog::info(msg, file, line);
497 std::snprintf(msg, maxMsgLen,
"QCOMPARE(%s, %s) returned TRUE unexpectedly.",
500 return checkStatement(success, msg, file, line);
506bool QTestResult::compare(
bool success,
const char *failureMsg,
507 char *val1,
char *val2,
508 const char *actual,
const char *expected,
509 const char *file,
int line)
511 const bool result = compareHelper(success, failureMsg,
512 val1 !=
nullptr ? val1 :
"<null>",
513 val2 !=
nullptr ? val2 :
"<null>",
514 actual, expected, file, line,
515 val1 !=
nullptr && val2 !=
nullptr);
524bool QTestResult::compare(
bool success,
const char *failureMsg,
525 double val1,
double val2,
526 const char *actual,
const char *expected,
527 const char *file,
int line)
529 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
532bool QTestResult::compare(
bool success,
const char *failureMsg,
533 float val1,
float val2,
534 const char *actual,
const char *expected,
535 const char *file,
int line)
537 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
540bool QTestResult::compare(
bool success,
const char *failureMsg,
542 const char *actual,
const char *expected,
543 const char *file,
int line)
545 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
548#if QT_POINTER_SIZE == 8
549bool QTestResult::compare(
bool success,
const char *failureMsg,
550 qsizetype val1, qsizetype val2,
551 const char *actual,
const char *expected,
552 const char *file,
int line)
554 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
558bool QTestResult::compare(
bool success,
const char *failureMsg,
559 unsigned val1,
unsigned val2,
560 const char *actual,
const char *expected,
561 const char *file,
int line)
563 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
566bool QTestResult::compare(
bool success,
const char *failureMsg,
567 QStringView val1, QStringView val2,
568 const char *actual,
const char *expected,
569 const char *file,
int line)
571 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
574bool QTestResult::compare(
bool success,
const char *failureMsg,
575 QStringView val1,
const QLatin1StringView &val2,
576 const char *actual,
const char *expected,
577 const char *file,
int line)
579 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
582bool QTestResult::compare(
bool success,
const char *failureMsg,
583 const QLatin1StringView & val1, QStringView val2,
584 const char *actual,
const char *expected,
585 const char *file,
int line)
587 return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line);
592bool QTestResult::compare(
bool success,
const char *failureMsg,
593 const char *actual,
const char *expeceted,
594 const char *file,
int line)
596 return compareHelper(success, failureMsg, actual, expeceted, file, line);
599void QTestResult::addFailure(
const char *message,
const char *file,
int line)
602 if (qApp && QThread::currentThread() == qApp->thread())
603 QTestEventLoop::instance().exitLoop();
605 if (QTest::blacklistCurrentTest)
606 QTestLog::addBFail(message, file, line);
608 QTestLog::addFail(message, file, line);
609 QTest::setFailed(
true);
612void QTestResult::addSkip(
const char *message,
const char *file,
int line)
616 QTestLog::addSkip(message, file, line);
619void QTestResult::setCurrentTestObject(
const char *name)
621 QTest::currentTestObjectName = name;
624const char *QTestResult::currentTestObjectName()
626 return QTest::currentTestObjectName ? QTest::currentTestObjectName :
"";
629void QTestResult::setSkipCurrentTest(
bool value)
631 QTest::skipCurrentTest = value;
634bool QTestResult::skipCurrentTest()
636 return QTest::skipCurrentTest;
639void QTestResult::setCurrentAppName(
const char *appName)
641 ::currentAppName = appName;
644const char *QTestResult::currentAppName()
646 return ::currentAppName;
651 using namespace QTest;
653 case ComparisonOperation::CustomCompare:
655 case ComparisonOperation::Equal:
656 return "QCOMPARE_EQ";
657 case ComparisonOperation::NotEqual:
658 return "QCOMPARE_NE";
659 case ComparisonOperation::LessThan:
660 return "QCOMPARE_LT";
661 case ComparisonOperation::LessThanOrEqual:
662 return "QCOMPARE_LE";
663 case ComparisonOperation::GreaterThan:
664 return "QCOMPARE_GT";
665 case ComparisonOperation::GreaterThanOrEqual:
666 return "QCOMPARE_GE";
667 case ComparisonOperation::ThreeWayCompare:
668 return "QCOMPARE_3WAY";
670 Q_UNREACHABLE_RETURN(
"");
675 using namespace QTest;
677 case ComparisonOperation::CustomCompare:
678 return "Compared values are not the same";
679 case ComparisonOperation::ThreeWayCompare:
680 return "The result of operator<=>() is not what was expected";
681 case ComparisonOperation::Equal:
682 return "The computed value is expected to be equal to the baseline, but is not";
683 case ComparisonOperation::NotEqual:
684 return "The computed value is expected to be different from the baseline, but is not";
685 case ComparisonOperation::LessThan:
686 return "The computed value is expected to be less than the baseline, but is not";
687 case ComparisonOperation::LessThanOrEqual:
688 return "The computed value is expected to be less than or equal to the baseline, but is not";
689 case ComparisonOperation::GreaterThan:
690 return "The computed value is expected to be greater than the baseline, but is not";
691 case ComparisonOperation::GreaterThanOrEqual:
692 return "The computed value is expected to be greater than or equal to the baseline, but is not";
694 Q_UNREACHABLE_RETURN(
"");
697bool QTestResult::reportResult(
bool success,
const void *lhs,
const void *rhs,
698 const char *(*lhsFormatter)(
const void*),
699 const char *(*rhsFormatter)(
const void*),
700 const char *lhsExpr,
const char *rhsExpr,
701 QTest::ComparisonOperation op,
const char *file,
int line,
702 const char *failureMessage)
704 Q_DECL_UNINITIALIZED
char msg[maxMsgLen];
707 QTEST_ASSERT(lhsExpr);
708 QTEST_ASSERT(rhsExpr);
710 if (QTestLog::verboseLevel() >= 2) {
711 std::snprintf(msg, maxMsgLen,
"%s(%s, %s)", macroNameForOp(op), lhsExpr, rhsExpr);
712 QTestLog::info(msg, file, line);
716 if (QTest::expectFailMode) {
717 std::snprintf(msg, maxMsgLen,
"%s(%s, %s) returned TRUE unexpectedly.",
718 macroNameForOp(op), lhsExpr, rhsExpr);
720 return checkStatement(success, msg, file, line);
723 const std::unique_ptr<
const char[]> lhsPtr{ lhsFormatter(lhs) };
724 const std::unique_ptr<
const char[]> rhsPtr{ rhsFormatter(rhs) };
727 failureMessage = failureMessageForOp(op);
729 formatFailMessage(msg, maxMsgLen, failureMessage, lhsPtr.get(), rhsPtr.get(),
730 lhsExpr, rhsExpr, op);
732 return checkStatement(success, msg, file, line);
735bool QTestResult::report3WayResult(
bool success,
736 const char *failureMessage,
737 const void *lhs,
const void *rhs,
738 const char *(*lhsFormatter)(
const void*),
739 const char *(*rhsFormatter)(
const void*),
740 const char *lhsExpression,
const char *rhsExpression,
741 const char *(*actualOrderFormatter)(
const void *),
742 const char *(*expectedOrderFormatter)(
const void *),
743 const void *actualOrder,
const void *expectedOrder,
744 const char *expectedExpression,
745 const char *file,
int line)
750 QTEST_ASSERT(lhsExpression);
751 QTEST_ASSERT(rhsExpression);
752 QTEST_ASSERT(expectedExpression);
753 const char *macroName = macroNameForOp(QTest::ComparisonOperation::ThreeWayCompare);
754 const std::string actualExpression = std::string(lhsExpression) +
" <=> " + rhsExpression;
756 if (QTestLog::verboseLevel() >= 2) {
757 std::snprintf(msg, maxMsgLen,
"%s(%s, %s, %s)",
758 macroName, lhsExpression, rhsExpression, expectedExpression);
759 QTestLog::info(msg, file, line);
763 if (QTest::expectFailMode) {
764 std::snprintf(msg, maxMsgLen,
"%s(%s, %s, %s) returned TRUE unexpectedly.",
765 macroName, lhsExpression, rhsExpression, expectedExpression);
767 return checkStatement(success, msg, file, line);
769 const std::unique_ptr<
const char[]> lhsStr{lhsFormatter(lhs)};
770 const std::unique_ptr<
const char[]> rhsStr{rhsFormatter(rhs)};
772 const std::unique_ptr<
const char[]> actual{actualOrderFormatter(actualOrder)};
773 const std::unique_ptr<
const char[]> expected{expectedOrderFormatter(expectedOrder)};
776 failureMessage = failureMessageForOp(QTest::ComparisonOperation::ThreeWayCompare);
779 formatFailMessage(msg, maxMsgLen, failureMessage,
780 lhsStr.get(), rhsStr.get(),
781 lhsExpression, rhsExpression,
782 QTest::ComparisonOperation::ThreeWayCompare);
785 formatFailMessage(msg + strlen(msg), maxMsgLen - strlen(msg),
"",
786 actual.get(), expected.get(),
787 actualExpression.c_str(), expectedExpression,
788 QTest::ComparisonOperation::CustomCompare);
790 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()