diff --git a/syncthingconnector/CMakeLists.txt b/syncthingconnector/CMakeLists.txt index d74dcb1..fe9bd88 100644 --- a/syncthingconnector/CMakeLists.txt +++ b/syncthingconnector/CMakeLists.txt @@ -150,5 +150,39 @@ if (META_MAIN_TEST_NAME) set_tests_properties("${META_MAIN_TEST_NAME}" PROPERTIES RESOURCE_LOCK "syncthingtestinstance") endif () +# add additional library with mocked SyncthingConnector class so models can be tested without running Syncthing itself +if (EXCLUDE_TESTS_FROM_ALL) + set(TESTS_EXCLUSION EXCLUDE_FROM_ALL) +else () + unset(TESTS_EXCLUSION) +endif () +add_library( + ${META_TARGET_NAME}_mocked + ${TESTS_EXCLUSION} + OBJECT + syncthingconnection.h + syncthingconnection.cpp + syncthingconnection_requests.cpp + syncthingconnectionmockhelpers.h + syncthingconnectionmockhelpers.cpp) +target_link_libraries( + ${META_TARGET_NAME}_mocked + PUBLIC ${META_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" + PRIVATE "${PRIVATE_LIBRARIES}") +target_include_directories( + ${META_TARGET_NAME}_mocked + PUBLIC ${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE} ${TARGET_GENERATED_INCLUDE_DIRECTORY} ${PUBLIC_INCLUDE_DIRS} + PRIVATE ${PRIVATE_INCLUDE_DIRS}) +target_compile_definitions( + ${META_TARGET_NAME}_mocked + PUBLIC ${META_PUBLIC_COMPILE_DEFINITIONS} ${META_PROJECT_VARNAME_UPPER}_MOCKED + ${META_PROJECT_VARNAME_UPPER}_CONNECTION_MOCKED SyncthingConnection=SyncthingConnectionMocked + PRIVATE "${META_PRIVATE_COMPILE_DEFINITIONS}") +target_compile_options( + ${META_TARGET_NAME}_mocked + PUBLIC "${META_PUBLIC_COMPILE_OPTIONS}" + PRIVATE "${META_PRIVATE_COMPILE_OPTIONS}") +set_target_properties(${META_TARGET_NAME}_mocked PROPERTIES CXX_STANDARD "${META_CXX_STANDARD}") + include(Doxygen) include(ConfigHeader) diff --git a/syncthingconnector/syncthingconnection.cpp b/syncthingconnector/syncthingconnection.cpp index 701132e..c7c3c76 100644 --- a/syncthingconnector/syncthingconnection.cpp +++ b/syncthingconnector/syncthingconnection.cpp @@ -39,6 +39,7 @@ using namespace CppUtilities::EscapeCodes; namespace Data { +#ifndef LIB_SYNCTHING_CONNECTOR_MOCKED /*! * \brief Returns the QNetworkAccessManager instance used by SyncthingConnection instances. */ @@ -47,6 +48,7 @@ QNetworkAccessManager &networkAccessManager() static auto networkAccessManager = new QNetworkAccessManager; return *networkAccessManager; } +#endif /*! * \class SyncthingConnection diff --git a/syncthingmodel/CMakeLists.txt b/syncthingmodel/CMakeLists.txt index 1076233..b966bac 100644 --- a/syncthingmodel/CMakeLists.txt +++ b/syncthingmodel/CMakeLists.txt @@ -7,6 +7,7 @@ set(META_APP_NAME "Data models of Syncthing Tray") set(META_APP_DESCRIPTION "Data models of Syncthing Tray") set(META_PROJECT_VARNAME_UPPER LIB_SYNCTHING_MODEL) set(META_PUBLIC_QT_MODULES Gui Widgets) +set(META_SRCDIR_REFS "${CMAKE_CURRENT_SOURCE_DIR}/../syncthingconnector") # add project files set(HEADER_FILES @@ -37,6 +38,9 @@ set(RES_FILES resources/${META_PROJECT_NAME}icons.qrc) set(TS_FILES translations/${META_PROJECT_NAME}_zh_CN.ts translations/${META_PROJECT_NAME}_cs_CZ.ts translations/${META_PROJECT_NAME}_de_DE.ts translations/${META_PROJECT_NAME}_en_US.ts) +set(QT_TESTS models) +set(QT_TEST_SRC_FILES_models syncthingicons.cpp syncthingmodel.cpp syncthingdirectorymodel.cpp) + # find c++utilities find_package(${PACKAGE_NAMESPACE_PREFIX}c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.0.0 REQUIRED) use_cpp_utilities() @@ -63,3 +67,20 @@ include(WindowsResources) include(LibraryTarget) include(Doxygen) include(ConfigHeader) + +# configure test target +include(TestUtilities) +list(APPEND QT_TEST_LIBRARIES ${LIB_SYNCTHING_CONNECTOR_LIB}_mocked ${CPP_UTILITIES_LIB}) +use_qt_module(LIBRARIES_VARIABLE "QT_TEST_LIBRARIES" PREFIX "${QT_PACKAGE_PREFIX}" MODULE "Test") +foreach (TEST ${QT_TESTS}) + configure_test_target( + TEST_NAME + "${TEST}_tests" + SRC_FILES + ${QT_TEST_SRC_FILES_${TEST}} + "tests/${TEST}.cpp" + LIBRARIES + "${QT_TEST_LIBRARIES}" + FULL_TEST_NAME_OUT_VAR + FULL_TEST_NAME_${TEST}) +endforeach () diff --git a/syncthingmodel/tests/models.cpp b/syncthingmodel/tests/models.cpp new file mode 100644 index 0000000..faa9958 --- /dev/null +++ b/syncthingmodel/tests/models.cpp @@ -0,0 +1,59 @@ +#include "../syncthingdirectorymodel.h" + +#include + +#include + +#include +#include + +#include + +class ModelTests : public QObject { + Q_OBJECT + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + + void testDirectoryModel(); + +private: + QTimer m_timeout; + QEventLoop m_loop; + Data::SyncthingConnection m_connection; +}; + +void ModelTests::initTestCase() +{ + // setup timeout + m_timeout.setSingleShot(true); + m_timeout.setInterval(5000); + m_timeout.start(); + connect(&m_timeout, &QTimer::timeout, this, [this] { + m_loop.quit(); + QFAIL("Timeout exceeded when loading mocked config/status for test"); + }); + + // request config and status and wait until available + connect(&m_connection, &Data::SyncthingConnection::newConfigApplied, &m_loop, &QEventLoop::quit); + m_connection.requestConfigAndStatus(); + m_loop.exec(); + m_timeout.stop(); +} + +void ModelTests::cleanupTestCase() +{ +} + +void ModelTests::testDirectoryModel() +{ + auto model = Data::SyncthingDirectoryModel(m_connection); + QCOMPARE(model.rowCount(QModelIndex()), 3); + QCOMPARE(model.index(0, 0).data(), QStringLiteral("A folder")); + QCOMPARE(model.index(1, 0).data(), QStringLiteral("Yet another folder")); + QCOMPARE(model.index(2, 0).data(), QStringLiteral("A folder which is not shared")); +} + +QTEST_MAIN(ModelTests) +#include "models.moc"