Introduce basic test setup for models

This test setup utilizes the "mocked" configuration so far only used for
manual testing. This allows adding unit tests for models without having to
run Syncthing itself. The test is pretty basic itself at this point.
This commit is contained in:
Martchus 2024-04-26 23:04:47 +02:00
parent eb4c1ac761
commit ecece11df3
4 changed files with 116 additions and 0 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 ()

View File

@ -0,0 +1,59 @@
#include "../syncthingdirectorymodel.h"
#include <syncthingconnector/syncthingconnection.h>
#include <QtTest/QtTest>
#include <QEventLoop>
#include <QTimer>
#include <qtutilities/misc/compat.h>
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"