From f38073206831d950185e432f9ed840535489a9ad Mon Sep 17 00:00:00 2001 From: Martchus Date: Sun, 21 Oct 2018 21:07:43 +0200 Subject: [PATCH] Don't use std::function for handlers in testcode Just use the lambdas directly and make if(handler) check only if possible. --- connector/CMakeLists.txt | 2 +- connector/tests/connectiontests.cpp | 53 ++++++++++++++--------------- testhelper/CMakeLists.txt | 2 +- testhelper/helper.h | 24 ++++++++++++- 4 files changed, 50 insertions(+), 31 deletions(-) diff --git a/connector/CMakeLists.txt b/connector/CMakeLists.txt index e2930d7..9676d8e 100644 --- a/connector/CMakeLists.txt +++ b/connector/CMakeLists.txt @@ -46,7 +46,7 @@ set(TS_FILES ) # find c++utilities -find_package(c++utilities 4.15.0 REQUIRED) +find_package(c++utilities 4.16.0 REQUIRED) use_cpp_utilities() set(META_PUBLIC_SHARED_LIB_DEPENDS c++utilities) set(META_PUBLIC_STATIC_LIB_DEPENDS c++utilities_static) diff --git a/connector/tests/connectiontests.cpp b/connector/tests/connectiontests.cpp index 05ae1c0..dbb61ac 100644 --- a/connector/tests/connectiontests.cpp +++ b/connector/tests/connectiontests.cpp @@ -89,8 +89,8 @@ private: static void (SyncthingConnection::*defaultReconnect())(void); static void (SyncthingConnection::*defaultDisconnect())(void); - template TemporaryConnection handleNewDevices(Handler handler); - template TemporaryConnection handleNewDirs(Handler handler); + template TemporaryConnection handleNewDevices(const Handler &handler); + template TemporaryConnection handleNewDirs(const Handler &handler); WaitForConnected connectedSignal() const; void waitForConnected(int timeout = 5000); void waitForAllDirsAndDevsReady(bool initialConfig = false); @@ -230,7 +230,7 @@ void ConnectionTests::waitForAllDirsAndDevsReady(const bool initialConfig) { bool allDirsReady, allDevsReady; bool isConnected = m_connection.isConnected(); - const function checkAllDirsReady([this, &allDirsReady, &initialConfig] { + const auto checkAllDirsReady([this, &allDirsReady, &initialConfig] { bool oneDirPaused = false; for (const SyncthingDir &dir : m_connection.dirInfo()) { if (dir.status == SyncthingDirStatus::Unknown) { @@ -241,7 +241,7 @@ void ConnectionTests::waitForAllDirsAndDevsReady(const bool initialConfig) } allDirsReady = !initialConfig || oneDirPaused; }); - const function checkAllDevsReady([this, &allDevsReady, &initialConfig] { + const auto checkAllDevsReady([this, &allDevsReady, &initialConfig] { bool oneDevPaused = false; for (const SyncthingDev &dev : m_connection.devInfo()) { if (dev.status == SyncthingDevStatus::Unknown) { @@ -252,7 +252,7 @@ void ConnectionTests::waitForAllDirsAndDevsReady(const bool initialConfig) } allDevsReady = !initialConfig || oneDevPaused; }); - const function checkStatus([this, &isConnected](SyncthingStatus) { isConnected = m_connection.isConnected(); }); + auto checkStatus([this, &isConnected](SyncthingStatus) { isConnected = m_connection.isConnected(); }); checkAllDirsReady(); checkAllDevsReady(); if (allDirsReady && allDevsReady) { @@ -270,7 +270,7 @@ void ConnectionTests::waitForAllDirsAndDevsReady(const bool initialConfig) /*! * \brief Helps handling newDevices() signal when waiting for device change. */ -template TemporaryConnection ConnectionTests::handleNewDevices(Handler handler) +template TemporaryConnection ConnectionTests::handleNewDevices(const Handler &handler) { return QObject::connect(&m_connection, &SyncthingConnection::newDevices, [&handler](const std::vector &devs) { for (const SyncthingDev &dev : devs) { @@ -282,7 +282,7 @@ template TemporaryConnection ConnectionTests::handleNewDevice /*! * \brief Helps handling newDirs() signal when waiting for directory change. */ -template TemporaryConnection ConnectionTests::handleNewDirs(Handler handler) +template TemporaryConnection ConnectionTests::handleNewDirs(const Handler &handler) { return QObject::connect(&m_connection, &SyncthingConnection::newDirs, [&handler](const std::vector &dirs) { for (const SyncthingDir &dir : dirs) { @@ -335,7 +335,7 @@ void ConnectionTests::testErrorCases() bool authErrorStatus = false, authErrorConfig = false; bool apiKeyErrorStatus = false, apiKeyErrorConfig = false; bool allErrorsEmitted = false; - const function errorHandler = [&](const QString &errorMessage) { + const auto errorHandler = [&](const QString &errorMessage) { if ((errorMessage == QStringLiteral("Unable to request Syncthing status: Connection refused")) || (errorMessage == QStringLiteral("Unable to request Syncthing config: Connection refused"))) { // Syncthing not ready yet, wait 100 ms till next connection attempt @@ -400,10 +400,9 @@ void ConnectionTests::testSendingError() bool newNotificationEmitted = false; const DateTime sentTime(DateTime::now()); const QString sentMessage(QStringLiteral("test notification")); - const function newNotificationHandler - = [&](ChronoUtilities::DateTime receivedTime, const QString &receivedMessage) { - newNotificationEmitted |= receivedTime == sentTime && receivedMessage == sentMessage; - }; + const auto newNotificationHandler = [&](ChronoUtilities::DateTime receivedTime, const QString &receivedMessage) { + newNotificationEmitted |= receivedTime == sentTime && receivedMessage == sentMessage; + }; waitForSignals([this, sentTime, &sentMessage] { m_connection.emitNotification(sentTime, sentMessage); }, 500, connectionSignal(&SyncthingConnection::newNotification, newNotificationHandler, &newNotificationEmitted)); } @@ -494,18 +493,17 @@ void ConnectionTests::testResumingAllDevices() { cerr << "\n - Resuming all devices ..." << endl; bool devResumed = false; - const function devResumedHandler = [&devResumed](const SyncthingDev &dev, int) { + const auto devResumedHandler = [&devResumed](const SyncthingDev &dev, int) { if (dev.name == QStringLiteral("Test dev 2") && !dev.paused) { devResumed = true; } }; - const function)> newDevsHandler = [&devResumedHandler](const std::vector &devs) { + const auto newDevsHandler = [&devResumedHandler](const std::vector &devs) { for (const auto &dev : devs) { devResumedHandler(dev, 0); } }; - const function devResumedTriggeredHandler - = [this](const QStringList &devIds) { CPPUNIT_ASSERT_EQUAL(m_connection.deviceIds(), devIds); }; + const auto devResumedTriggeredHandler = [this](const QStringList &devIds) { CPPUNIT_ASSERT_EQUAL(m_connection.deviceIds(), devIds); }; const auto newDevsConnection = handleNewDevices(devResumedHandler); waitForConnected(); waitForConnection(&SyncthingConnection::resumeAllDevs, 7500, connectedSignal(), @@ -525,18 +523,17 @@ void ConnectionTests::testResumingDirectory() { cerr << "\n - Resuming all dirs ..." << endl; bool dirResumed = false; - const function dirResumedHandler = [&dirResumed](const SyncthingDir &dir, int) { + const auto dirResumedHandler = [&dirResumed](const SyncthingDir &dir, int) { if (dir.id == QStringLiteral("test2") && !dir.paused) { dirResumed = true; } }; - const function)> newDirsHandler = [&dirResumedHandler](const std::vector &dirs) { + const auto newDirsHandler = [&dirResumedHandler](const std::vector &dirs) { for (const auto &dir : dirs) { dirResumedHandler(dir, 0); } }; - const function dirResumedTriggeredHandler - = [this](const QStringList &devIds) { CPPUNIT_ASSERT_EQUAL(m_connection.directoryIds(), devIds); }; + const auto dirResumedTriggeredHandler = [this](const QStringList &devIds) { CPPUNIT_ASSERT_EQUAL(m_connection.directoryIds(), devIds); }; const auto newDirsConnection = handleNewDirs(dirResumedHandler); waitForConnected(); waitForConnection(&SyncthingConnection::resumeAllDirs, 7500, connectedSignal(), @@ -552,13 +549,13 @@ void ConnectionTests::testPausingDirectory() { cerr << "\n - Pause dir 1 ..." << endl; bool dirPaused = false; - const function dirPausedHandler = [&dirPaused](const SyncthingDir &dir, int) { + const auto dirPausedHandler = [&dirPaused](const SyncthingDir &dir, int) { if (dir.id == QStringLiteral("test1") && dir.paused) { dirPaused = true; } }; const QStringList ids({ QStringLiteral("test1") }); - const function dirPausedTriggeredHandler = [&ids](const QStringList &devIds) { CPPUNIT_ASSERT_EQUAL(ids, devIds); }; + const auto dirPausedTriggeredHandler = [&ids](const QStringList &devIds) { CPPUNIT_ASSERT_EQUAL(ids, devIds); }; const auto newDirsConnection = handleNewDirs(dirPausedHandler); waitForConnected(); waitForSignals(bind(&SyncthingConnection::pauseDirectories, &m_connection, ids), 7500, connectedSignal(), @@ -574,7 +571,7 @@ void ConnectionTests::testRequestingLog() cerr << "\n - Requesting log ..." << endl; waitForConnected(); - const function &)> handleLogAvailable = [&](const vector &logEntries) { + const auto handleLogAvailable = [](const vector &logEntries) { CPPUNIT_ASSERT(!logEntries.empty()); CPPUNIT_ASSERT(!logEntries[0].when.isEmpty()); CPPUNIT_ASSERT(!logEntries[0].message.isEmpty()); @@ -588,7 +585,7 @@ void ConnectionTests::testRequestingQrCode() cerr << "\n - Requesting QR-Code for own device ID ..." << endl; waitForConnected(); - const function handleQrCodeAvailable = [&](const QString &qrText, const QByteArray &data) { + const auto handleQrCodeAvailable = [](const QString &qrText, const QByteArray &data) { CPPUNIT_ASSERT_EQUAL(QStringLiteral("some text"), qrText); CPPUNIT_ASSERT(!data.isEmpty()); }; @@ -613,7 +610,7 @@ void ConnectionTests::testConnectingWithSettings() settings.password = m_connection.password(); bool isConnected; - const function checkStatus([this, &isConnected](SyncthingStatus) { isConnected = m_connection.isConnected(); }); + const auto checkStatus([this, &isConnected](SyncthingStatus) { isConnected = m_connection.isConnected(); }); waitForSignals( bind(static_cast(&SyncthingConnection::connect), &m_connection, ref(settings)), 5000, connectionSignal(&SyncthingConnection::statusChanged, checkStatus, &isConnected)); @@ -625,7 +622,7 @@ void ConnectionTests::testRequestingRescan() waitForConnected(); bool rescanTriggered = false; - function rescanTriggeredHandler = [&rescanTriggered](const QString &dir) { + const auto rescanTriggeredHandler = [&rescanTriggered](const QString &dir) { CPPUNIT_ASSERT_EQUAL(QStringLiteral("test2"), dir); rescanTriggered = true; }; @@ -633,7 +630,7 @@ void ConnectionTests::testRequestingRescan() connectionSignal(&SyncthingConnection::rescanTriggered, rescanTriggeredHandler, &rescanTriggered)); bool errorOccured = false; - function errorHandler = [&errorOccured](const QString &message) { + const auto errorHandler = [&errorOccured](const QString &message) { errorOccured |= message.startsWith(QStringLiteral("Unable to request rescan: Error transferring")) && message.endsWith(QStringLiteral("/rest/db/scan?folder=non-existing-dir&sub=sub/path - server replied: Internal Server Error")); }; @@ -661,7 +658,7 @@ void ConnectionTests::testDealingWithArbitraryConfig() // expect the change via newConfig() signal bool hasNewConfig = false; - function handleNewConfig([&hasNewConfig](const QJsonObject &newConfig) { + const auto handleNewConfig([&hasNewConfig](const QJsonObject &newConfig) { const auto newIntervall(newConfig.value(QLatin1String("options")).toObject().value(QLatin1String("relayReconnectIntervalM")).toInt()); if (newIntervall == 75) { hasNewConfig = true; diff --git a/testhelper/CMakeLists.txt b/testhelper/CMakeLists.txt index 9f31681..f42ccc1 100644 --- a/testhelper/CMakeLists.txt +++ b/testhelper/CMakeLists.txt @@ -30,7 +30,7 @@ set(TS_FILES ) # find c++utilities -find_package(c++utilities 4.0.0 REQUIRED) +find_package(c++utilities 4.16.0 REQUIRED) use_cpp_utilities() set(META_PUBLIC_SHARED_LIB_DEPENDS c++utilities) set(META_PUBLIC_STATIC_LIB_DEPENDS c++utilities_static) diff --git a/testhelper/helper.h b/testhelper/helper.h index 538b704..2c90ab5 100644 --- a/testhelper/helper.h +++ b/testhelper/helper.h @@ -95,6 +95,28 @@ private: QMetaObject::Connection m_connection; }; +/*! + * \brief Returns whether the \a object is actually callable. + * + * This is supposed to be the case if \a object evaluates to true in boolean context (eg. std::function) or + * if there's no conversion to bool (eg. lambda). + */ +template > * = nullptr> inline bool isActuallyCallable(const T &object) +{ + return object ? true : false; +} + +/*! + * \brief Returns whether the \a object is actually callable. + * + * This is supposed to be the case if \a object evaluates to true in boolean context (eg. std::function) or + * if there's no conversion to bool (eg. lambda). + */ +template > * = nullptr> inline bool isActuallyCallable(const T &) +{ + return true; +} + /*! * \brief The SignalInfo class represents a connection of a signal with a handler. * @@ -130,7 +152,7 @@ public: , m_signalEmitted(false) { // register handler if specified - if (handler) { + if (isActuallyCallable(handler)) { m_handlerConnection = QObject::connect(sender, signal, sender, handler, Qt::DirectConnection); #ifndef SYNCTHINGTESTHELPER_FOR_CLI if (!m_handlerConnection) {