QTest: DRY test function invocation

Wrap the QMetaMethod::invoke() calls in a helper function in
preparation of filtering execeptions as part of QTBUG-66320. Rename
the existing helper function to make the old documentation comment
redundant.

Pick this back to LTS branch in order to avoid needless code
divergence going forward.

Pick-to: 6.6 6.5
Change-Id: I34ae24bf23ea21d7063016257908f925fc087298
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 5e237f1af21af363a395aef09f93115c5882b443)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2024-01-26 10:58:51 +01:00 committed by Qt Cherry-pick Bot
parent 28a88b5986
commit 346b5931a7

View File

@ -543,17 +543,17 @@ static int repetitions = 1;
static bool repeatForever = false; static bool repeatForever = false;
static bool skipBlacklisted = false; static bool skipBlacklisted = false;
/*! \internal static bool invokeTestMethodIfValid(QMetaMethod m, QObject *obj = QTest::currentTestObject)
Invoke a method of the object without generating warning if the method does not exist {
*/ return m.isValid() && m.invoke(obj, Qt::DirectConnection);
static void invokeMethod(QObject *obj, const char *methodName) }
static void invokeTestMethodIfExists(const char *methodName, QObject *obj = QTest::currentTestObject)
{ {
const QMetaObject *metaObject = obj->metaObject(); const QMetaObject *metaObject = obj->metaObject();
int funcIndex = metaObject->indexOfMethod(methodName); int funcIndex = metaObject->indexOfMethod(methodName);
if (funcIndex >= 0) { // doesn't generate a warning if it doesn't exist:
QMetaMethod method = metaObject->method(funcIndex); invokeTestMethodIfValid(metaObject->method(funcIndex), obj);
method.invoke(obj, Qt::DirectConnection);
}
} }
int defaultEventDelay() int defaultEventDelay()
@ -637,7 +637,7 @@ static void qPrintDataTags(FILE *stream)
// Get global data tags: // Get global data tags:
QTestTable::globalTestTable(); QTestTable::globalTestTable();
invokeMethod(QTest::currentTestObject, "initTestCase_data()"); invokeTestMethodIfExists("initTestCase_data()");
const QTestTable *gTable = QTestTable::globalTestTable(); const QTestTable *gTable = QTestTable::globalTestTable();
const QMetaObject *currTestMetaObj = QTest::currentTestObject->metaObject(); const QMetaObject *currTestMetaObj = QTest::currentTestObject->metaObject();
@ -656,7 +656,7 @@ static void qPrintDataTags(FILE *stream)
QByteArray member; QByteArray member;
member.resize(qstrlen(slot) + qstrlen("_data()") + 1); member.resize(qstrlen(slot) + qstrlen("_data()") + 1);
qsnprintf(member.data(), member.size(), "%s_data()", slot); qsnprintf(member.data(), member.size(), "%s_data()", slot);
invokeMethod(QTest::currentTestObject, member.constData()); invokeTestMethodIfExists(member.constData());
const int dataCount = table.dataCount(); const int dataCount = table.dataCount();
localTags.reserve(dataCount); localTags.reserve(dataCount);
for (int j = 0; j < dataCount; ++j) for (int j = 0; j < dataCount; ++j)
@ -1150,8 +1150,7 @@ void TestMethods::invokeTestOnData(int index) const
bool invokeOk; bool invokeOk;
do { do {
QTest::inTestFunction = true; QTest::inTestFunction = true;
if (m_initMethod.isValid()) invokeTestMethodIfValid(m_initMethod);
m_initMethod.invoke(QTest::currentTestObject, Qt::DirectConnection);
const bool initQuit = const bool initQuit =
QTestResult::skipCurrentTest() || QTestResult::currentTestFailed(); QTestResult::skipCurrentTest() || QTestResult::currentTestFailed();
@ -1163,7 +1162,7 @@ void TestMethods::invokeTestOnData(int index) const
QBenchmarkGlobalData::current->context.tag = QLatin1StringView( QBenchmarkGlobalData::current->context.tag = QLatin1StringView(
QTestResult::currentDataTag() ? QTestResult::currentDataTag() : ""); QTestResult::currentDataTag() ? QTestResult::currentDataTag() : "");
invokeOk = m_methods[index].invoke(QTest::currentTestObject, Qt::DirectConnection); invokeOk = invokeTestMethodIfValid(m_methods[index]);
if (!invokeOk) if (!invokeOk)
QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__); QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);
@ -1176,8 +1175,7 @@ void TestMethods::invokeTestOnData(int index) const
QTestResult::finishedCurrentTestData(); QTestResult::finishedCurrentTestData();
if (!initQuit) { if (!initQuit) {
if (m_cleanupMethod.isValid()) invokeTestMethodIfValid(m_cleanupMethod);
m_cleanupMethod.invoke(QTest::currentTestObject, Qt::DirectConnection);
// Process any deleteLater(), used by event-loop-based apps. // Process any deleteLater(), used by event-loop-based apps.
// Fixes memleak reports. // Fixes memleak reports.
@ -1430,7 +1428,7 @@ bool TestMethods::invokeTest(int index, QLatin1StringView tag, WatchDog *watchDo
if (curGlobalDataIndex == 0) { if (curGlobalDataIndex == 0) {
qsnprintf(member, 512, "%s_data()", name.constData()); qsnprintf(member, 512, "%s_data()", name.constData());
invokeMethod(QTest::currentTestObject, member); invokeTestMethodIfExists(member);
if (QTestResult::skipCurrentTest()) if (QTestResult::skipCurrentTest())
break; break;
} }
@ -1776,8 +1774,7 @@ void TestMethods::invokeTests(QObject *testObject) const
const QMetaObject *metaObject = testObject->metaObject(); const QMetaObject *metaObject = testObject->metaObject();
QTEST_ASSERT(metaObject); QTEST_ASSERT(metaObject);
QTestResult::setCurrentTestFunction("initTestCase"); QTestResult::setCurrentTestFunction("initTestCase");
if (m_initTestCaseDataMethod.isValid()) invokeTestMethodIfValid(m_initTestCaseDataMethod, testObject);
m_initTestCaseDataMethod.invoke(testObject, Qt::DirectConnection);
QScopedPointer<WatchDog> watchDog; QScopedPointer<WatchDog> watchDog;
if (!alreadyDebugging() if (!alreadyDebugging()
@ -1791,8 +1788,7 @@ void TestMethods::invokeTests(QObject *testObject) const
QSignalDumper::startDump(); QSignalDumper::startDump();
if (!QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()) { if (!QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()) {
if (m_initTestCaseMethod.isValid()) invokeTestMethodIfValid(m_initTestCaseMethod, testObject);
m_initTestCaseMethod.invoke(testObject, Qt::DirectConnection);
// finishedCurrentTestDataCleanup() resets QTestResult::currentTestFailed(), so use a local copy. // finishedCurrentTestDataCleanup() resets QTestResult::currentTestFailed(), so use a local copy.
const bool previousFailed = QTestResult::currentTestFailed(); const bool previousFailed = QTestResult::currentTestFailed();
@ -1816,8 +1812,7 @@ void TestMethods::invokeTests(QObject *testObject) const
QTestResult::setSkipCurrentTest(false); QTestResult::setSkipCurrentTest(false);
QTestResult::setBlacklistCurrentTest(false); QTestResult::setBlacklistCurrentTest(false);
QTestResult::setCurrentTestFunction("cleanupTestCase"); QTestResult::setCurrentTestFunction("cleanupTestCase");
if (m_cleanupTestCaseMethod.isValid()) invokeTestMethodIfValid(m_cleanupTestCaseMethod, testObject);
m_cleanupTestCaseMethod.invoke(testObject, Qt::DirectConnection);
QTestResult::finishedCurrentTestData(); QTestResult::finishedCurrentTestData();
// Restore skip state as it affects decision on whether we passed: // Restore skip state as it affects decision on whether we passed:
QTestResult::setSkipCurrentTest(wasSkipped || QTestResult::skipCurrentTest()); QTestResult::setSkipCurrentTest(wasSkipped || QTestResult::skipCurrentTest());