From 0bcaf185cc75ba4dcdf9a8e3b8e6087a36f67ec6 Mon Sep 17 00:00:00 2001 From: wangyixue Date: Fri, 21 Jul 2023 16:12:01 +0800 Subject: [PATCH] tests: add some unit tests Add some unit tests. Mostly for platformthemeplugin. Log: add some unit tests --- .reuse/dep5 | 2 +- .../qdeepinfiledialoghelper.cpp | 2 + tests/CMakeLists.txt | 54 ++++ .../filedialogmanagerservice.cpp | 81 ++++++ .../platformtheme/filedialogmanagerservice.h | 58 ++++ tests/platformtheme/filedialogservice.cpp | 198 +++++++++++++ tests/platformtheme/filedialogservice.h | 275 ++++++++++++++++++ tests/platformtheme/qt-theme.ini | 9 + tests/platformtheme/test-files.qrc | 5 + tests/platformtheme/ut_dthemesettings.cpp | 89 ++++++ .../ut_qdeepinfiledialoghelper.cpp | 165 +++++++++++ tests/platformtheme/ut_qdeepintheme.cpp | 90 ++++++ tests/test-recoverage-qmake.sh | 31 -- tests/ut_pluginloading.cpp | 84 ++++++ 14 files changed, 1111 insertions(+), 32 deletions(-) create mode 100644 tests/platformtheme/filedialogmanagerservice.cpp create mode 100644 tests/platformtheme/filedialogmanagerservice.h create mode 100644 tests/platformtheme/filedialogservice.cpp create mode 100644 tests/platformtheme/filedialogservice.h create mode 100644 tests/platformtheme/qt-theme.ini create mode 100644 tests/platformtheme/test-files.qrc create mode 100644 tests/platformtheme/ut_dthemesettings.cpp create mode 100644 tests/platformtheme/ut_qdeepinfiledialoghelper.cpp create mode 100644 tests/platformtheme/ut_qdeepintheme.cpp delete mode 100755 tests/test-recoverage-qmake.sh create mode 100644 tests/ut_pluginloading.cpp diff --git a/.reuse/dep5 b/.reuse/dep5 index dd4ee640..c413ce8d 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -31,7 +31,7 @@ License: CC0-1.0 # png svg dci Files: platformthemeplugin/icons/* styleplugins/chameleon/*.svg styles/images/*.png tests/*/icons/*/*.svg tests/*/*.svg tests/*/icons/*/*.dci - tests/imageformats/dci/*.dci + tests/imageformats/dci/*.dci tests/platformtheme/qt-theme.ini Copyright: None License: CC0-1.0 diff --git a/platformthemeplugin/qdeepinfiledialoghelper.cpp b/platformthemeplugin/qdeepinfiledialoghelper.cpp index 33590c17..2964bd79 100644 --- a/platformthemeplugin/qdeepinfiledialoghelper.cpp +++ b/platformthemeplugin/qdeepinfiledialoghelper.cpp @@ -31,7 +31,9 @@ DGUI_USE_NAMESPACE QT_BEGIN_NAMESPACE +#ifndef DIALOG_SERVICE #define DIALOG_SERVICE "com.deepin.filemanager.filedialog" +#endif Q_LOGGING_CATEGORY(fileDialogHelper, "dtk.qpa.fileDialogHelper"); QList stringList2UrlList(const QStringList &list) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 87d3c6e9..2d031ff1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,6 +2,31 @@ # # SPDX-License-Identifier: LGPL-3.0-or-later +if(QT_VERSION_MAJOR EQUAL 5) + find_package(Qt5X11Extras REQUIRED) + list(APPEND QT_LIBS Qt5::X11Extras) + if(QT_VERSION_MINOR GREATER_EQUAL 8) # Qt5.8 + find_package(Qt5ThemeSupport REQUIRED) + list(APPEND THEME_LIBS Qt5::ThemeSupportPrivate) + else() + list(APPEND THEME_LIBS Qt5::PlatformSupportPrivate) # TODO to be verified + endif() + set(3RD_PARTY_SOURCES + ${CMAKE_SOURCE_DIR}/3rdparty/qdbustrayicon.cpp + ${CMAKE_SOURCE_DIR}/3rdparty/qstatusnotifieritemadaptor.cpp + ${CMAKE_SOURCE_DIR}/3rdparty/qdbusmenuconnection.cpp + ) + set(3RD_PARTY_HEADERS + ${CMAKE_SOURCE_DIR}/3rdparty/qdbustrayicon_p.h + ${CMAKE_SOURCE_DIR}/3rdparty/qstatusnotifieritemadaptor_p.h + ${CMAKE_SOURCE_DIR}/3rdparty/qdbusmenuconnection_p.h + ) + qt5_add_dbus_interface(DBUS_INTERFACES ${CMAKE_SOURCE_DIR}/platformthemeplugin/xmls/com.deepin.filemanager.filedialog.xml filedialog_interface) + qt5_add_dbus_interface(DBUS_INTERFACES ${CMAKE_SOURCE_DIR}/platformthemeplugin/xmls/com.deepin.filemanager.filedialogmanager.xml filedialogmanager_interface) +else() + qt6_add_dbus_interface(DBUS_INTERFACES ${CMAKE_SOURCE_DIR}/platformthemeplugin/xmls/com.deepin.filemanager.filedialog.xml filedialog_interface) + qt6_add_dbus_interface(DBUS_INTERFACES ${CMAKE_SOURCE_DIR}/platformthemeplugin/xmls/com.deepin.filemanager.filedialogmanager.xml filedialogmanager_interface) +endif() add_executable(unit-tests ${CMAKE_SOURCE_DIR}/iconengineplugins/svgiconengine/qsvgiconengine.h ${CMAKE_SOURCE_DIR}/imageformatplugins/svg/qsvgiohandler.h @@ -9,11 +34,17 @@ add_executable(unit-tests ${CMAKE_SOURCE_DIR}/styleplugins/chameleon/chameleonstyle.h ${CMAKE_SOURCE_DIR}/styleplugins/chameleon/common.h ${CMAKE_SOURCE_DIR}/styleplugins/chameleon/dstyleanimation.h + ${CMAKE_SOURCE_DIR}/platformthemeplugin/dthemesettings.h + ${CMAKE_SOURCE_DIR}/platformthemeplugin/qdeepintheme.h + ${CMAKE_SOURCE_DIR}/platformthemeplugin/qdeepinfiledialoghelper.h ${CMAKE_SOURCE_DIR}/iconengineplugins/svgiconengine/qsvgiconengine.cpp ${CMAKE_SOURCE_DIR}/imageformatplugins/svg/qsvgiohandler.cpp ${CMAKE_SOURCE_DIR}/imageformatplugins/dci/qdciiohandler.cpp ${CMAKE_SOURCE_DIR}/styleplugins/chameleon/chameleonstyle.cpp ${CMAKE_SOURCE_DIR}/styleplugins/chameleon/dstyleanimation.cpp + ${CMAKE_SOURCE_DIR}/platformthemeplugin/dthemesettings.cpp + ${CMAKE_SOURCE_DIR}/platformthemeplugin/qdeepintheme.cpp + ${CMAKE_SOURCE_DIR}/platformthemeplugin/qdeepinfiledialoghelper.cpp iconengines/svgiconengine/ut_qsvgiconengine.cpp iconengines/svgiconengine/icons.qrc imageformats/dci/ut_qdciiohandler.cpp @@ -21,10 +52,24 @@ add_executable(unit-tests imageformats/svg/ut_qsvgiohandler.cpp styleplugins/chameleon/ut_chameleonstyle.cpp styleplugins/chameleon/icons/theme-icons.qrc + platformtheme/ut_dthemesettings.cpp + platformtheme/ut_qdeepintheme.cpp + platformtheme/ut_qdeepinfiledialoghelper.cpp + platformtheme/test-files.qrc + platformtheme/filedialogservice.h + platformtheme/filedialogservice.cpp + platformtheme/filedialogmanagerservice.h + platformtheme/filedialogmanagerservice.cpp + ut_pluginloading.cpp main.cpp + ${3RD_PARTY_SOURCES} + ${3RD_PARTY_HEADERS} + ${DBUS_INTERFACES} ) find_package(GTest REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Concurrent REQUIRED) +find_package(PkgConfig REQUIRED) +pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11) target_compile_options(unit-tests PRIVATE -g -fno-access-control @@ -46,9 +91,17 @@ target_link_libraries(unit-tests PRIVATE Qt${QT_VERSION_MAJOR}::Concurrent Qt${QT_VERSION_MAJOR}::CorePrivate Qt${QT_VERSION_MAJOR}::GuiPrivate + ${THEME_LIBS} + ${QT_LIBS} Qt${QT_VERSION_MAJOR}::WidgetsPrivate asan gcov + PkgConfig::X11 +) +target_compile_definitions(unit-tests PRIVATE + DIALOG_SERVICE="org.deepin.fakefilemanager.filedialog" + META_FILE_BASE_DIR="${CMAKE_SOURCE_DIR}" + PLUGIN_OUTPUT_BASE_DIR="${PLUGIN_OUTPUT_BASE_DIR}" ) target_include_directories(unit-tests PRIVATE ${CMAKE_SOURCE_DIR}/iconengineplugins/builtinengine @@ -57,6 +110,7 @@ target_include_directories(unit-tests PRIVATE ${CMAKE_SOURCE_DIR}/imageformatplugins/svg ${CMAKE_SOURCE_DIR}/imageformatplugins/dci ${CMAKE_SOURCE_DIR}/styleplugins/chameleon + ${CMAKE_SOURCE_DIR}/platformthemeplugin ) target_compile_definitions(unit-tests PRIVATE -DUT_PLATFORMPLUGIN_PATH="${CMAKE_BINARY_DIR}/plugins" diff --git a/tests/platformtheme/filedialogmanagerservice.cpp b/tests/platformtheme/filedialogmanagerservice.cpp new file mode 100644 index 00000000..392cff10 --- /dev/null +++ b/tests/platformtheme/filedialogmanagerservice.cpp @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#include "filedialogmanagerservice.h" +#include +#include +FileDialogManagerService::FileDialogManagerService(const QString &service, + const QString &path) + : m_service{service}, + m_path{path}, + m_useFileChooserDialog{true}, + m_errorMsg{} +{ + registerAll(); +} + +FileDialogManagerService::~FileDialogManagerService() +{ + unregisterAll(); +} + +bool FileDialogManagerService::registerAll() +{ + QDBusConnection conn = QDBusConnection::sessionBus(); + if (!conn.registerService(m_service)) { + m_errorMsg = QString("Cannot register service %1").arg(m_service); + return false; + } + if (!conn.registerObject(m_path, this, QDBusConnection::ExportAllContents)) { + m_errorMsg = QString("Cannot register object %1").arg(m_path); + return false; + } + return true; +} + +bool FileDialogManagerService::unregisterAll() +{ + QDBusConnection conn = QDBusConnection::sessionBus(); + conn.unregisterObject(m_path); + if (!conn.unregisterService(m_service)) { + m_errorMsg = QString("Cannot unregister service %1").arg(m_service); + return false; + } + return true; +} + +QList FileDialogManagerService::dialogs() +{ + return m_dialogMap.keys(); +} + +QDBusObjectPath FileDialogManagerService::createDialog(const QString key) +{ + QString path{"/com/deepin/filemanager/filedialog/"}; + if (key.isEmpty()) { + path.append(QUuid::createUuid().toRfc4122().toHex()); + } else { + path.append(key); + } + FileDialogService *dialogService = new FileDialogService(path); + m_dialogMap.insert(QDBusObjectPath{path}, dialogService); + return QDBusObjectPath{path}; +} + +void FileDialogManagerService::destroyDialog(const QDBusObjectPath &path) +{ + auto dialog = m_dialogMap.find(path); + dialog.value()->deleteLater(); + m_dialogMap.erase(dialog); +} + +bool FileDialogManagerService::isUseFileChooserDialog() +{ + return m_useFileChooserDialog; +} + +QString FileDialogManagerService::errorString() +{ + return m_errorMsg; +} diff --git a/tests/platformtheme/filedialogmanagerservice.h b/tests/platformtheme/filedialogmanagerservice.h new file mode 100644 index 00000000..6ba20c82 --- /dev/null +++ b/tests/platformtheme/filedialogmanagerservice.h @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#ifndef FILEDIALOGMANAGERSERVICE_H +#define FILEDIALOGMANAGERSERVICE_H +#include +#include +#include "filedialogservice.h" +#include + +class FileDialogManagerService : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.filedialogmanager") + Q_CLASSINFO("D-Bus Introspection", "" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "") + +public: + FileDialogManagerService(const QString &service, const QString &path); + ~FileDialogManagerService(); + +public Q_SLOTS: + Q_SCRIPTABLE QDBusObjectPath createDialog(const QString key); + void destroyDialog(const QDBusObjectPath &path); + QList dialogs(); + QString errorString(); + bool isUseFileChooserDialog(); + +private: + bool registerAll(); + bool unregisterAll(); + QMap m_dialogMap; + QString m_service; + QString m_path; + bool m_useFileChooserDialog; + QString m_errorMsg; +}; + +#endif // FILEDIALOGMANAGERSERVICE_H diff --git a/tests/platformtheme/filedialogservice.cpp b/tests/platformtheme/filedialogservice.cpp new file mode 100644 index 00000000..ab7ad9d9 --- /dev/null +++ b/tests/platformtheme/filedialogservice.cpp @@ -0,0 +1,198 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#include "filedialogservice.h" +#include + +FileDialogService::FileDialogService(const QString &path) + : m_objPath{path} + , m_online{false} + , m_accepted{false} + , m_rejected{false} + , m_visible{false} +{ + QDBusConnection conn = QDBusConnection::sessionBus(); + m_online = conn.registerObject(m_objPath, this, QDBusConnection::ExportAllContents); + connect(this, &QObject::destroyed, this, &FileDialogService::destroyed); +} + +FileDialogService::~FileDialogService() +{ + QDBusConnection conn = QDBusConnection::sessionBus(); + conn.unregisterObject(m_objPath); + m_online = false; +} + +void FileDialogService::accept() +{ + m_accepted = true; + Q_EMIT this->accepted(); +} + +void FileDialogService::activateWindow() +{ +} + +void FileDialogService::addCustomWidget(int type, const QString & data) +{ + Q_UNUSED(type) + Q_UNUSED(data) +} + +void FileDialogService::addDisableUrlScheme(const QString & type) +{ + Q_UNUSED(type) +} + +QMap FileDialogService::allCustomWidgetsValue(int type) +{ + Q_UNUSED(type) + return QMap(); +} + +void FileDialogService::beginAddCustomWidget() +{ +} + +void FileDialogService::endAddCustomWidget() +{ +} + +QDBusVariant FileDialogService::getCustomWidgetValue(int type, const QString & text) +{ + Q_UNUSED(type) + Q_UNUSED(text) + return QDBusVariant(); +} + +void FileDialogService::hide() +{ + m_visible = false; +} + +QString FileDialogService::labelText(int label) +{ + Q_UNUSED(label) + return QString(); +} + +void FileDialogService::makeHeartbeat() +{ +} + +void FileDialogService::open() +{ +} + +int FileDialogService::options() +{ + return 0; +} + +void FileDialogService::reject() +{ + m_rejected = true; + Q_EMIT this->rejected(); +} + +void FileDialogService::selectFile(const QString & filename) +{ + Q_UNUSED(filename) +} + +void FileDialogService::selectNameFilter(const QString & filter) +{ + m_nameFilters.append(filter); +} + +void FileDialogService::selectNameFilterByIndex(int index) +{ + Q_UNUSED(index) +} + +void FileDialogService::selectUrl(const QString & url) +{ + m_selectedFiles.append(url); +} + +QStringList FileDialogService::selectedFiles() +{ + QStringList files; + for (auto fileUrl : m_selectedFiles) { + files.append(fileUrl.toString()); + } + return files; +} + +QString FileDialogService::selectedNameFilter() +{ + return m_nameFilters.join(';'); +} + +int FileDialogService::selectedNameFilterIndex() +{ + return 0; +} + +QStringList FileDialogService::selectedUrls() +{ + QStringList files; + for (auto fileUrl : m_selectedFiles) { + files.append(fileUrl.toString()); + } + return files; +} + +void FileDialogService::setAllowMixedSelection(bool on) +{ + Q_UNUSED(on) +} + +void FileDialogService::setCurrentInputName(const QString & name) +{ + Q_UNUSED(name) +} + +void FileDialogService::setFileMode(int fileMode) +{ + Q_UNUSED(fileMode) +} + +void FileDialogService::setLabelText(int label, const QString & text) +{ + Q_UNUSED(label) + Q_UNUSED(text) +} + +void FileDialogService::setOption(int option, bool on) +{ + Q_UNUSED(option) + Q_UNUSED(on) +} + +void FileDialogService::setOptions(int options) +{ + Q_UNUSED(options) +} + +void FileDialogService::setWindowTitle(const QString & title) +{ + Q_UNUSED(title) +} + +void FileDialogService::show() +{ + m_visible = true; +} + +bool FileDialogService::testOption(int option) +{ + Q_UNUSED(option) + return false; +} + +qulonglong FileDialogService::winId() +{ + return qulonglong(); +} diff --git a/tests/platformtheme/filedialogservice.h b/tests/platformtheme/filedialogservice.h new file mode 100644 index 00000000..c5c04b42 --- /dev/null +++ b/tests/platformtheme/filedialogservice.h @@ -0,0 +1,275 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#ifndef FILEDIALOGSERVICE_H +#define FILEDIALOGSERVICE_H +#include +#include +#include + +class FileDialogService : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.filedialog") + Q_CLASSINFO("D-Bus Introspection", "" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "") + Q_PROPERTY(int acceptMode READ acceptMode WRITE setAcceptMode) + Q_PROPERTY(QString directory READ directory WRITE setDirectory) + Q_PROPERTY(QString directoryUrl READ directoryUrl WRITE setDirectoryUrl) + Q_PROPERTY(int filter READ filter WRITE setFilter) + Q_PROPERTY(int heartbeatInterval READ heartbeatInterval WRITE setHeartbeatInterval) + Q_PROPERTY(bool hideOnAccept READ hideOnAccept WRITE setHideOnAccept) + Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters) + Q_PROPERTY(int viewMode READ viewMode WRITE setViewMode) + Q_PROPERTY(bool windowActive READ windowActive) + Q_PROPERTY(uint windowFlags READ windowFlags WRITE setWindowFlags) + +public: + inline int acceptMode() const + { return m_acceptMode; } + inline void setAcceptMode(int value) + { m_acceptMode = value; } + + inline QString directory() const + { return directoryUrl(); } + inline void setDirectory(const QString &value) + { + setDirectoryUrl(value); + Q_EMIT this->directoryChanged(); + } + + inline QString directoryUrl() const + { return m_directoryUrl; } + inline void setDirectoryUrl(const QString &value) + { + m_directoryUrl = value; + Q_EMIT this->directoryUrlChanged(); + } + + inline int filter() const + { return m_filter; } + inline void setFilter(int value) + { + m_filter = value; + } + + inline int heartbeatInterval() const + { return m_heartbeatInterval; } + inline void setHeartbeatInterval(int value) + { m_heartbeatInterval = value; } + + inline bool hideOnAccept() const + { return m_hideOnAccept; } + inline void setHideOnAccept(bool value) + { + m_hideOnAccept = value; + } + + inline QStringList nameFilters() const + { return m_nameFilters; } + inline void setNameFilters(const QStringList &value) + { m_nameFilters = value; } + + inline int viewMode() const + { return m_viewMode; } + inline void setViewMode(int value) + { m_viewMode = value; } + + inline bool windowActive() const + { return m_windowActive; } + + inline uint windowFlags() const + { return m_windowFlags; } + inline void setWindowFlags(uint value) + { m_windowFlags = value; } + +public Q_SLOTS: + void accept(); + void activateWindow(); + void addCustomWidget(int type, const QString &data); + void addDisableUrlScheme(const QString &type); + QMap allCustomWidgetsValue(int type); + void beginAddCustomWidget(); + void endAddCustomWidget(); + QDBusVariant getCustomWidgetValue(int type, const QString &text); + void hide(); + QString labelText(int label); + void makeHeartbeat(); + void open(); + int options(); + void reject(); + void selectFile(const QString &filename); + void selectNameFilter(const QString &filter); + void selectNameFilterByIndex(int index); + void selectUrl(const QString &url); + QStringList selectedFiles(); + QString selectedNameFilter(); + int selectedNameFilterIndex(); + QStringList selectedUrls(); + void setAllowMixedSelection(bool on); + void setCurrentInputName(const QString &name); + void setFileMode(int fileMode); + void setLabelText(int label, const QString &text); + void setOption(int option, bool on); + void setOptions(int options); + void setWindowTitle(const QString &title); + void show(); + bool testOption(int option); + qulonglong winId(); + +Q_SIGNALS: // SIGNALS + void accepted(); + void currentUrlChanged(); + void destroyed(); + void directoryChanged(); + void directoryUrlChanged(); + void finished(int result); + void rejected(); + void selectedNameFilterChanged(); + void selectionFilesChanged(); + void windowActiveChanged(); + +public: + FileDialogService(const QString &path); + ~FileDialogService(); + + QString m_objPath; + bool m_online; + bool m_accepted; + bool m_rejected; + bool m_visible; + QList m_selectedFiles; + + int m_acceptMode; + QString m_directoryUrl; + int m_filter; + int m_heartbeatInterval; + bool m_hideOnAccept; + QStringList m_nameFilters; + int m_viewMode; + bool m_windowActive; + uint m_windowFlags; + + + + + +}; +#endif // FILEDIALOGSERVICE_H diff --git a/tests/platformtheme/qt-theme.ini b/tests/platformtheme/qt-theme.ini new file mode 100644 index 00000000..7444285f --- /dev/null +++ b/tests/platformtheme/qt-theme.ini @@ -0,0 +1,9 @@ +[Theme] +Font=Noto Sans +FontSize=11 +IconThemeName=organic-glass +FallBackIconThemeName=bloom +StyleNames=chameleon +MonoFont=Noto Mono +ScaleLogicalDpi=96, 96 +ScreenScaleFactors=1.25 diff --git a/tests/platformtheme/test-files.qrc b/tests/platformtheme/test-files.qrc new file mode 100644 index 00000000..958b8545 --- /dev/null +++ b/tests/platformtheme/test-files.qrc @@ -0,0 +1,5 @@ + + + qt-theme.ini + + diff --git a/tests/platformtheme/ut_dthemesettings.cpp b/tests/platformtheme/ut_dthemesettings.cpp new file mode 100644 index 00000000..8dddc000 --- /dev/null +++ b/tests/platformtheme/ut_dthemesettings.cpp @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#include +#include +#include +#include +#include +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include +#endif +#include "dthemesettings.h" + +class TestDThemeSettings : public testing::Test +{ +public: + static void SetUpTestSuite() { + userConfigPath = new QTemporaryDir; + userConfigPath->setAutoRemove(true); + QDir path(userConfigPath->path()); + path.mkdir("deepin"); + QFile::copy(":/qt-theme.ini", userConfigPath->filePath("deepin/qt-theme.ini")); + prevEnv = qgetenv("D_QT_THEME_CONFIG_PATH"); + qputenv("D_QT_THEME_CONFIG_PATH", userConfigPath->path().toLocal8Bit()); + themeSettings = new DThemeSettings(false); + } + + static void TearDownTestSuite() { + qputenv("D_Qt_THEME_CONFIG_PATH", prevEnv); + delete themeSettings; + delete userConfigPath; + } + + static DThemeSettings *themeSettings; + static QTemporaryDir *userConfigPath; + static QByteArray prevEnv; +}; + +DThemeSettings *TestDThemeSettings::themeSettings = nullptr; +QTemporaryDir *TestDThemeSettings::userConfigPath = nullptr; +QByteArray TestDThemeSettings::prevEnv = {}; + +// Test user settings load +TEST_F(TestDThemeSettings, makeSettingsUserSpecified) +{ + QSettings *settings = DThemeSettings::makeSettings(); + ASSERT_NE(nullptr, settings); + ASSERT_EQ(settings->status(), QSettings::NoError); + QString name = settings->fileName(); + EXPECT_EQ(name, userConfigPath->filePath("deepin/qt-theme.ini")); + QStringList keys = settings->allKeys(); + EXPECT_TRUE(keys.contains("Font")); + EXPECT_TRUE(keys.contains("FontSize")); + EXPECT_TRUE(keys.contains("IconThemeName")); + EXPECT_TRUE(keys.contains("MonoFont")); + EXPECT_TRUE(keys.contains("ScaleLogicalDpi")); + EXPECT_TRUE(keys.contains("ScreenScaleFactors")); +} + +// Make sure that ini file uses UTF-8 codec +TEST_F(TestDThemeSettings, makeSettingsCodec) +{ + QSettings *settings = DThemeSettings::makeSettings(); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + QTextCodec *iniCodec = settings->iniCodec(); + EXPECT_EQ(codec->name(), iniCodec->name()); +#endif +} + +// Test properties using fake data +TEST_F(TestDThemeSettings, properties) +{ + EXPECT_EQ(themeSettings->isSetIconThemeName(), true); + EXPECT_EQ(themeSettings->iconThemeName(), "organic-glass"); + EXPECT_EQ(themeSettings->isSetFallbackIconThemeName(), true); + EXPECT_EQ(themeSettings->fallbackIconThemeName(), "bloom"); + EXPECT_EQ(themeSettings->isSetStyleNames(), true); + EXPECT_EQ(themeSettings->styleNames(), QStringList{"chameleon"}); + EXPECT_EQ(themeSettings->isSetSystemFont(), true); + EXPECT_EQ(themeSettings->systemFont(), "Noto Sans"); + EXPECT_EQ(themeSettings->isSetSystemFixedFont(), true); + EXPECT_EQ(themeSettings->systemFixedFont(), "Noto Mono"); + EXPECT_EQ(themeSettings->screenScaleFactors(), "1.25"); + DDpi dpi = themeSettings->scaleLogicalDpi(); + EXPECT_DOUBLE_EQ(dpi.first, 96.0); + EXPECT_DOUBLE_EQ(dpi.second, 96.0); +} diff --git a/tests/platformtheme/ut_qdeepinfiledialoghelper.cpp b/tests/platformtheme/ut_qdeepinfiledialoghelper.cpp new file mode 100644 index 00000000..bb8a2049 --- /dev/null +++ b/tests/platformtheme/ut_qdeepinfiledialoghelper.cpp @@ -0,0 +1,165 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#include +#include +#include +#include "filedialogmanagerservice.h" +#include "filedialog_interface.h" +#include "qdeepinfiledialoghelper.h" +#include +#include + +class TestQDeepinFileDialogHelper : public testing::Test +{ +public: + static void SetUpTestSuite() + { + manager = new FileDialogManagerService(DIALOG_SERVICE, "/com/deepin/filemanager/filedialogmanager"); + QDeepinFileDialogHelper::initDBusFileDialogManager(); + } + static void TearDownTestSuite() + { + delete manager; + } + + void SetUp() override + { + helper = new QDeepinFileDialogHelper; + nativedlg = new QFileDialog; + } + + void TearDown() override + { + delete helper; + delete nativedlg; + } + + void ensureDialog() + { + if (filedlg) + return; + if (helper) { + helper->ensureDialog(); + if (helper->filedlgInterface) { + auto dialogPath = helper->filedlgInterface->path(); + filedlg = manager->m_dialogMap[QDBusObjectPath{dialogPath}]; + } + } + } + +private: + QDeepinFileDialogHelper *helper{nullptr}; + FileDialogService *filedlg{nullptr}; + QFileDialog *nativedlg{nullptr}; + static FileDialogManagerService *manager; +}; + +FileDialogManagerService *TestQDeepinFileDialogHelper::manager = nullptr; + +TEST_F(TestQDeepinFileDialogHelper, ensureDialog) +{ + EXPECT_EQ(nullptr, filedlg); + EXPECT_NE(nullptr, helper); + ensureDialog(); + EXPECT_NE(nullptr, filedlg); +} + +TEST_F(TestQDeepinFileDialogHelper, show) +{ + helper->setOptions(QFileDialogOptions::create()); + bool success = helper->show(Qt::Dialog, Qt::ApplicationModal, nativedlg->windowHandle()); + ASSERT_TRUE(success); + EXPECT_TRUE(QGuiApplicationPrivate::self->modalWindowList.contains(helper->auxiliaryWindow)); + EXPECT_EQ(helper->auxiliaryWindow, qApp->modalWindow()); +} + +TEST_F(TestQDeepinFileDialogHelper, exec) +{ + ensureDialog(); + QTimer::singleShot(1, filedlg, &FileDialogService::accept); + helper->exec(); + EXPECT_TRUE(filedlg->m_visible); + // Ensure that auxiliary window is non-modal after exec + ASSERT_NE(nullptr, helper->auxiliaryWindow); + EXPECT_FALSE(QGuiApplicationPrivate::self->modalWindowList.contains(helper->auxiliaryWindow)); +} + +TEST_F(TestQDeepinFileDialogHelper, hide) +{ + ensureDialog(); + QTimer::singleShot(1, helper, &QDeepinFileDialogHelper::hide); + helper->exec(); + EXPECT_FALSE(filedlg->m_visible); + ASSERT_NE(nullptr, helper->auxiliaryWindow); + EXPECT_FALSE(QGuiApplicationPrivate::self->modalWindowList.contains(helper->auxiliaryWindow)); +} + + +TEST_F(TestQDeepinFileDialogHelper, setDirectory) +{ + ensureDialog(); + filedlg->setDirectory("/test"); + helper->setDirectory(QUrl("/dtk")); + EXPECT_EQ("/dtk", filedlg->m_directoryUrl); +} + +TEST_F(TestQDeepinFileDialogHelper, directory) +{ + ensureDialog(); + filedlg->m_directoryUrl = "/test"; + EXPECT_EQ(filedlg->directory(), "/test"); +} + +TEST_F(TestQDeepinFileDialogHelper, selectFile) +{ + ensureDialog(); + filedlg->m_selectedFiles.clear(); + helper->selectFile(QUrl{"/test"}); + ASSERT_EQ(1, filedlg->m_selectedFiles.size()); + EXPECT_EQ(QUrl{"/test"}, filedlg->m_selectedFiles[0]); +} + +TEST_F(TestQDeepinFileDialogHelper, selectedFiles) +{ + ensureDialog(); + filedlg->m_selectedFiles = { + QUrl{"/test1"}, + QUrl{"/test2"}, + QUrl{"/test3"} + };; + auto result = helper->selectedFiles(); + ASSERT_EQ(3, result.size()); + EXPECT_EQ("/test1", result[0].toString()); + EXPECT_EQ("/test2", result[1].toString()); + EXPECT_EQ("/test3", result[2].toString()); +} + +TEST_F(TestQDeepinFileDialogHelper, setFilter) +{ + ensureDialog(); + filedlg->m_filter = 0; + EXPECT_EQ(0, filedlg->filter()); + // TODO Add test for setFilter. Now not sure why options are empty when helper created. +} + +TEST_F(TestQDeepinFileDialogHelper, selectNameFilter) +{ + ensureDialog(); + filedlg->m_nameFilters.clear(); + helper->selectNameFilter("*.cpp"); + EXPECT_EQ(1, filedlg->m_nameFilters.size()); + EXPECT_EQ("*.cpp", filedlg->m_nameFilters[0]); +} + +TEST_F(TestQDeepinFileDialogHelper, selectedNameFilters) +{ + ensureDialog(); + filedlg->m_nameFilters = QStringList{ + "*.cpp", + "*.h" + }; + auto result = helper->selectedNameFilter(); + EXPECT_EQ("*.cpp;*.h", result); +} diff --git a/tests/platformtheme/ut_qdeepintheme.cpp b/tests/platformtheme/ut_qdeepintheme.cpp new file mode 100644 index 00000000..215013a0 --- /dev/null +++ b/tests/platformtheme/ut_qdeepintheme.cpp @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#include +#include "qdeepintheme.h" +#include "filedialogmanagerservice.h" +#ifndef DIALOG_SERVICE +#define DIALOG_SERVICE "org.deepin.fakefilemanager.filedialog" +#endif + +class EnvGuard { +public: + EnvGuard(const char *name, const QByteArray &value) : m_name{name} + { + m_prev = qgetenv(name); + qputenv(name, value); + } + ~EnvGuard() + { + qputenv(qPrintable(m_name), m_prev); + } +private: + QString m_name; + QByteArray m_prev; +}; + +class TestQDeepinTheme : public testing::Test +{ +public: + static void SetUpTestSuite() + { + theme = new QDeepinTheme; + managerService = new FileDialogManagerService(DIALOG_SERVICE, "/com/deepin/filemanager/filedialogmanager"); + } + + static void TearDownTestSuite() + { + delete theme; + delete managerService; + } + + static QDeepinTheme *theme; + static FileDialogManagerService *managerService; +}; + +QDeepinTheme *TestQDeepinTheme::theme = nullptr; +FileDialogManagerService *TestQDeepinTheme::managerService = nullptr; + +TEST_F(TestQDeepinTheme, usePlatformNativeDialog) +{ + managerService->m_useFileChooserDialog = true; + { + // Test if environment variable take effect + EnvGuard guard{"_d_disableDBusFileDialog", "false"}; + EXPECT_TRUE(theme->usePlatformNativeDialog(QDeepinTheme::FileDialog)); + } + { + EnvGuard guard{"_d_disableDBusFileDialog", "true"}; + EXPECT_FALSE(theme->usePlatformNativeDialog(QDeepinTheme::FileDialog)); + } + managerService->m_useFileChooserDialog = false; + { + EnvGuard guard{"_d_disableDBusFileDialog", "false"}; + EXPECT_FALSE(theme->usePlatformNativeDialog(QDeepinTheme::FileDialog)); + } + { + EnvGuard guard{"_d_disableDBusFileDialog", "true"}; + EXPECT_FALSE(theme->usePlatformNativeDialog(QDeepinTheme::FileDialog)); + } +} + +TEST_F(TestQDeepinTheme, createPlatformDialogHelper) +{ + managerService->m_useFileChooserDialog = true; + auto helper = theme->createPlatformDialogHelper(QPlatformTheme::FileDialog); + EXPECT_NE(nullptr, helper); +} + +// Test if right icon engine is choosed +TEST_F(TestQDeepinTheme, createIconEngine) +{ + auto engine = theme->createIconEngine("icon_Layout"); + ASSERT_NE(nullptr, engine); +} + +TEST_F(TestQDeepinTheme, settings) +{ + ASSERT_NE(nullptr, theme->settings()); +} diff --git a/tests/test-recoverage-qmake.sh b/tests/test-recoverage-qmake.sh deleted file mode 100755 index e432824a..00000000 --- a/tests/test-recoverage-qmake.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -set -e -BUILD_DIR=`pwd`/../build-ut -HTML_DIR=${BUILD_DIR}/html -XML_DIR=${BUILD_DIR}/report -cd ../ -rm -rf $BUILD_DIR -mkdir $BUILD_DIR -cd $BUILD_DIR -qmake ../ CONFIG+=debug BASED_DTK_DIR=based-dtk -make -j$(nproc) -cd ../tests/ - -rm -rf $BUILD_DIR -mkdir $BUILD_DIR -cd $BUILD_DIR -qmake ../ CONFIG+=debug BASED_DTK_DIR=based-dtk -export ASAN_OPTIONS=halt_on_error=0 -TESTARGS="--gtest_output=xml:${XML_DIR}/report_qt5integration.xml" make check -j$(nproc) - -lcov -d ./ -c -o coverage_all.info -#lcov --extract coverage_all.info $EXTRACT_ARGS --output-file coverage.info -lcov --remove coverage_all.info "*/tests/*" "*/usr/include*" "*build-ut/src*" --output-file coverage.info -cd .. -genhtml -o $HTML_DIR $BUILD_DIR/coverage.info && mv ${BUILD_DIR}/html/index.html ${BUILD_DIR}/html/cov_qt5integration.html - -test -e ${BUILD_DIR}/asan.log* && mv ${BUILD_DIR}/asan.log* ${BUILD_DIR}/asan_qt5integration.log || touch ${BUILD_DIR}/asan_qt5integration.log - -#rm -rf $BUILD_DIR -#rm -rf ../$BUILD_DIR diff --git a/tests/ut_pluginloading.cpp b/tests/ut_pluginloading.cpp new file mode 100644 index 00000000..119e64e1 --- /dev/null +++ b/tests/ut_pluginloading.cpp @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#include +#include +#include +#include +#include +#include + +struct PluginInfo { + QString path; + QString metaFilePath; +}; + +class TestPluginLoading : public testing::Test, public testing::WithParamInterface +{ +public: + static void SetUpTestSuite() + { + // Assume build directory is in project root directory +#ifdef PLUGIN_OUTPUT_BASE_DIR + pluginBaseDir = PLUGIN_OUTPUT_BASE_DIR; +#else + pluginBaseDir = "../plugins"; +#endif +#ifdef META_FILE_BASE_DIR + metaFileBaseDir = META_FILE_BASE_DIR; +#else + metaFileBaseDir = "../.."; +#endif + } + +private: + static QString pluginBaseDir; + static QString metaFileBaseDir; +}; + +QString TestPluginLoading::pluginBaseDir = ""; +QString TestPluginLoading::metaFileBaseDir = ""; + +TEST_P(TestPluginLoading, load) +{ + auto info = GetParam(); + QPluginLoader loader(info.path); + loader.load(); + // Test if loaded successfully + EXPECT_TRUE(loader.isLoaded()); + EXPECT_NE(nullptr, loader.instance()); + // Test if the meta data match, especially key + QFile metaFile{QDir(metaFileBaseDir).filePath(info.metaFilePath)}; + auto success = metaFile.open(QFile::ReadOnly); + ASSERT_TRUE(success); + QJsonParseError err; + auto doc = QJsonDocument::fromJson(metaFile.readAll(), &err); + ASSERT_EQ(err.error, QJsonParseError::NoError); + ASSERT_FALSE(doc.isNull()); + ASSERT_FALSE(doc.isEmpty()); + ASSERT_TRUE(doc.isObject()); + auto root = doc.object(); + auto meta = loader.metaData(); + // meta info must include Keys field + auto fileKeys = root.value("Keys").toArray(); + auto metaKeys = meta.value("MetaData").toObject().value("Keys").toArray(); + ASSERT_FALSE(fileKeys.isEmpty()); + ASSERT_FALSE(metaKeys.isEmpty()); + ASSERT_EQ(fileKeys.count(), metaKeys.count()); + for (int i = 0; i < fileKeys.count(); ++i) { + EXPECT_EQ(fileKeys.at(i).toString(), metaKeys.at(i).toString()); + } + loader.unload(); +} + +INSTANTIATE_TEST_SUITE_P(Default, TestPluginLoading, + testing::Values( + PluginInfo{"iconengines/libdicon.so", "iconengineplugins/diconengine/diconengine.json"}, + PluginInfo{"iconengines/libdsvgicon.so", "iconengineplugins/svgiconengine/qsvgiconengine.json"}, + PluginInfo{"imageformats/libdci.so", "imageformatplugins/dci/dci.json"}, + PluginInfo{"imageformats/libdsvg.so", "imageformatplugins/svg/svg.json"}, + PluginInfo{"platformthemes/libqdeepin.so", "platformthemeplugin/deepin.json"}, + PluginInfo{"styles/libchameleon.so", "styleplugins/chameleon/chameleon.json"} + ) +);