Testlib: teach TAP test logger to support new QCOMPARE_* operators
The TAP test logger will now correctly print comparison types such as QCOMPARE_NE or QCOMPARE_LT, and also provide a proper expected/wanted value (by adding proper arithmetical operators in front of the value). Sample output: type: QCOMPARE_GE message: Left value is expected to be greater than or equal to right value, but is not wanted: >= 1 (rhs) found: 0 (lhs) expected: >= 1 (rhs) actual: 0 (lhs) at: tst_ExtendedCompare::compareUnregistereEnum() (tst_extendedcompare.cpp:232) file: tst_extendedcompare.cpp line: 232 As a drive-by: make some variables const. Task-number: QTBUG-98873 Change-Id: Idb54eaabcb937b42d3fc844f30041aab82d73f69 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
3dcf1779be
commit
9327d1aaf7
@ -281,25 +281,53 @@ void QTapTestLogger::addIncident(IncidentTypes type, const char *description,
|
||||
const char *indent = isExpectedFail ? YAML_INDENT YAML_INDENT YAML_INDENT : YAML_INDENT;
|
||||
if (!ok) {
|
||||
#if QT_CONFIG(regularexpression)
|
||||
enum class OperationType {
|
||||
Unknown,
|
||||
Compare, /* Plain old QCOMPARE */
|
||||
Verify, /* QVERIFY */
|
||||
CompareOp, /* QCOMPARE_OP */
|
||||
};
|
||||
|
||||
// This is fragile, but unfortunately testlib doesn't plumb
|
||||
// the expected and actual values to the loggers (yet).
|
||||
static QRegularExpression verifyRegex(u"^'(?<actualexpression>.*)' returned "
|
||||
"(?<actual>\\w+).+\\((?<message>.*)\\)$"_s);
|
||||
static const QRegularExpression verifyRegex(
|
||||
u"^'(?<actualexpression>.*)' returned "
|
||||
"(?<actual>\\w+).+\\((?<message>.*)\\)$"_s);
|
||||
|
||||
static QRegularExpression compareRegex(
|
||||
static const QRegularExpression compareRegex(
|
||||
u"^(?<message>.*)\n"
|
||||
"\\s*Actual\\s+\\((?<actualexpression>.*)\\)\\s*: (?<actual>.*)\n"
|
||||
"\\s*Expected\\s+\\((?<expectedexpresssion>.*)\\)\\s*: "
|
||||
"(?<expected>.*)$"_s);
|
||||
|
||||
QString descriptionString = QString::fromUtf8(description);
|
||||
QRegularExpressionMatch match = verifyRegex.match(descriptionString);
|
||||
const bool isVerify = match.hasMatch();
|
||||
if (!isVerify)
|
||||
match = compareRegex.match(descriptionString);
|
||||
static const QRegularExpression compareOpRegex(
|
||||
u"^(?<message>.*)\n"
|
||||
"\\s*Left\\s+\\((?<actualexpression>.*)\\)\\s*: (?<actual>.*)\n"
|
||||
"\\s*Right\\s+\\((?<expectedexpresssion>.*)\\)\\s*: "
|
||||
"(?<expected>.*)$"_s);
|
||||
|
||||
if (match.hasMatch()) {
|
||||
const QString descriptionString = QString::fromUtf8(description);
|
||||
QRegularExpressionMatch match = verifyRegex.match(descriptionString);
|
||||
|
||||
OperationType opType = OperationType::Unknown;
|
||||
if (match.hasMatch())
|
||||
opType = OperationType::Verify;
|
||||
|
||||
if (opType == OperationType::Unknown) {
|
||||
match = compareRegex.match(descriptionString);
|
||||
if (match.hasMatch())
|
||||
opType = OperationType::Compare;
|
||||
}
|
||||
|
||||
if (opType == OperationType::Unknown) {
|
||||
match = compareOpRegex.match(descriptionString);
|
||||
if (match.hasMatch())
|
||||
opType = OperationType::CompareOp;
|
||||
}
|
||||
|
||||
if (opType != OperationType::Unknown) {
|
||||
QString message = match.captured(u"message");
|
||||
QLatin1StringView comparisonType;
|
||||
QString expected;
|
||||
QString actual;
|
||||
const auto parenthesize = [&match](QLatin1StringView key) -> QString {
|
||||
@ -307,16 +335,45 @@ void QTapTestLogger::addIncident(IncidentTypes type, const char *description,
|
||||
};
|
||||
const QString actualExpression = parenthesize("actualexpression"_L1);
|
||||
|
||||
if (isVerify) {
|
||||
if (opType == OperationType::Verify) {
|
||||
comparisonType = "QVERIFY"_L1;
|
||||
actual = match.captured(u"actual").toLower() % actualExpression;
|
||||
expected = (actual.startsWith("true "_L1) ? "false"_L1 : "true"_L1)
|
||||
% actualExpression;
|
||||
if (message.isEmpty())
|
||||
message = u"Verification failed"_s;
|
||||
} else {
|
||||
} else if (opType == OperationType::Compare) {
|
||||
comparisonType = "QCOMPARE"_L1;
|
||||
expected = match.captured(u"expected")
|
||||
% parenthesize("expectedexpresssion"_L1);
|
||||
actual = match.captured(u"actual") % actualExpression;
|
||||
} else {
|
||||
struct ComparisonInfo {
|
||||
const char *comparisonType;
|
||||
const char *comparisonStringOp;
|
||||
};
|
||||
// get a proper comparison type based on the error message
|
||||
const auto info = [](const QString &err) -> ComparisonInfo {
|
||||
if (err.contains("different"_L1))
|
||||
return { "QCOMPARE_NE", "!= " };
|
||||
else if (err.contains("less than or equal to"_L1))
|
||||
return { "QCOMPARE_LE", "<= " };
|
||||
else if (err.contains("greater than or equal to"_L1))
|
||||
return { "QCOMPARE_GE", ">= " };
|
||||
else if (err.contains("less than"_L1))
|
||||
return { "QCOMPARE_LT", "< " };
|
||||
else if (err.contains("greater than"_L1))
|
||||
return { "QCOMPARE_GT", "> " };
|
||||
else if (err.contains("to be equal to"_L1))
|
||||
return { "QCOMPARE_EQ", "== " };
|
||||
else
|
||||
return { "Unknown", "" };
|
||||
}(message);
|
||||
comparisonType = QLatin1StringView(info.comparisonType);
|
||||
expected = QLatin1StringView(info.comparisonStringOp)
|
||||
% match.captured(u"expected")
|
||||
% parenthesize("expectedexpresssion"_L1);
|
||||
actual = match.captured(u"actual") % actualExpression;
|
||||
}
|
||||
|
||||
QTestCharBuffer diagnosticsYamlish;
|
||||
@ -329,7 +386,7 @@ void QTapTestLogger::addIncident(IncidentTypes type, const char *description,
|
||||
"%sfound: %s\n"
|
||||
"%sexpected: %s\n"
|
||||
"%sactual: %s\n",
|
||||
indent, isVerify ? "QVERIFY" : "QCOMPARE",
|
||||
indent, comparisonType.latin1(),
|
||||
indent, qPrintable(message),
|
||||
indent, qPrintable(expected), indent, qPrintable(actual),
|
||||
indent, qPrintable(expected), indent, qPrintable(actual)
|
||||
|
Loading…
x
Reference in New Issue
Block a user