feat: add test for desktopentry and jobmanager

Log:
This commit is contained in:
heyuming 2023-07-19 17:56:45 +08:00 committed by black-desk
parent d288752fb3
commit 5fed3ed9f0
19 changed files with 451 additions and 92 deletions

View File

@ -32,3 +32,8 @@ License: CC0-1.0
Files: rpm/* debian/* archlinux/*
Copyright: None
License: CC0-1.0
# test
Files: tests/data/*
Copyright: None
License: CC0-1.0

View File

@ -16,7 +16,40 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Qt6 REQUIRED COMPONENTS Core DBus Concurrent)
find_package(Threads REQUIRED)
qt_add_dbus_adaptor(ApplicationManagerSource ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.ApplicationManager1.xml applicationmanager1service.h ApplicationManager1Service)
add_library(ApplicationManager OBJECT ${ApplicationManagerSource})
qt_add_dbus_adaptor(ApplicationSource ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.ApplicationManager1.Application.xml applicationservice.h ApplicationService)
add_library(Application OBJECT ${ApplicationSource})
qt_add_dbus_adaptor(InstnaceSource ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.ApplicationManager1.Instance.xml instanceservice.h InstanceService)
add_library(Instance OBJECT ${InstnaceSource})
qt_add_dbus_adaptor(JobManagerSource ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.JobManager1.xml jobmanager1service.h JobManager1Service)
add_library(JobManager OBJECT ${JobManagerSource})
qt_add_dbus_adaptor(JobSource ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.JobManager1.Job.xml jobservice.h JobService)
add_library(Job OBJECT ${JobSource})
set(AdaptorLib)
list(APPEND AdaptorLib ApplicationManager Application Instance JobManager Job)
foreach(obj IN LISTS AdaptorLib)
target_link_libraries(${obj} PUBLIC
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::DBus
Qt${QT_VERSION_MAJOR}::Concurrent
)
target_include_directories(${obj} PUBLIC
${PROJECT_SOURCE_DIR}/src/include
${PROJECT_SOURCE_DIR}/src/dbus
)
endforeach()
add_subdirectory(src)
# add_subdirectory(docs)
# add_subdirectory(tests)
# add_subdirectory(plugin)
include(CTest)
if(BUILD_TESTING)
enable_testing()
add_subdirectory(tests)
endif()

View File

@ -1,31 +1,26 @@
include(GNUInstallDirs)
set(BIN_NAME dde-application-manager)
set(LIB_NAME ddeam)
set(DBUS_INTERFACE_DIR ${CMAKE_CURRENT_LIST_DIR}/dbus)
file(GLOB_RECURSE SRCS ${CMAKE_CURRENT_LIST_DIR}/*.cpp)
set(DBUSADAPTORS "")
file(GLOB_RECURSE SRCS ${CMAKE_CURRENT_LIST_DIR}/*.cpp ${CMAKE_CURRENT_LIST_DIR}/*.h)
list(REMOVE_ITEM SRCS "${PROJECT_SOURCE_DIR}/src/utils.cpp")
qt_add_dbus_adaptor(DBUSADAPTORS ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.ApplicationManager1.xml applicationmanager1service.h ApplicationManager1Service)
qt_add_dbus_adaptor(DBUSADAPTORS ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.ApplicationManager1.Application.xml applicationservice.h ApplicationService)
qt_add_dbus_adaptor(DBUSADAPTORS ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.ApplicationManager1.Instance.xml instanceservice.h InstanceService)
qt_add_dbus_adaptor(DBUSADAPTORS ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.JobManager1.xml jobmanager1service.h JobManager1Service)
qt_add_dbus_adaptor(DBUSADAPTORS ${PROJECT_SOURCE_DIR}/api/dbus/org.desktopspec.JobManager1.Job.xml jobservice.h JobService)
add_library(${LIB_NAME} ${SRCS})
add_executable(${BIN_NAME} ${DBUSADAPTORS} ${SRCS})
target_include_directories(${BIN_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/include
${CMAKE_CURRENT_LIST_DIR}/dbus
${CMAKE_CURRENT_BINARY_DIR}/src
target_include_directories(${LIB_NAME} PRIVATE
${PROJECT_BINARY_DIR}
)
target_link_libraries(${BIN_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::DBus
Qt${QT_VERSION_MAJOR}::Concurrent
target_link_libraries(${LIB_NAME} PUBLIC
Threads::Threads
${AdaptorLib}
)
add_executable(${BIN_NAME} main.cpp utils.cpp)
target_link_libraries(${BIN_NAME} PRIVATE
${LIB_NAME}
)
install(TARGETS ${BIN_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -2,7 +2,6 @@
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "applicationmanager1service.h"
#include "applicationmanager1adaptor.h"
#include "applicationadaptor.h"
#include "global.h"
@ -46,7 +45,7 @@ QDBusObjectPath ApplicationManager1Service::Launch(const QString &id,
objectPath.prepend(DDEApplicationManager1ApplicationObjectPath);
QSharedPointer<ApplicationService> app{new ApplicationService{id}};
auto *ptr = app.data();
if (registerObjectToDbus<decltype(ptr), ApplicationAdaptor>(ptr, objectPath, getDBusInterface<ApplicationAdaptor>())) {
if (registerObjectToDbus(new ApplicationAdaptor(ptr), objectPath, getDBusInterface<ApplicationAdaptor>())) {
QDBusObjectPath path{objectPath};
m_applicationList.insert(path, app);
return path;

View File

@ -3,6 +3,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "applicationservice.h"
#include "applicationadaptor.h"
#include "instanceadaptor.h"
#include <QUuid>
@ -27,7 +28,7 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
QString objectPath{m_applicationPath.path() + "/" + QUuid::createUuid().toString()};
QSharedPointer<InstanceService> ins{new InstanceService{objectPath, ""}};
auto *ptr = ins.data();
if (registerObjectToDbus<decltype(ptr), InstanceAdaptor>(ptr, objectPath, getDBusInterface<InstanceAdaptor>())) {
if (registerObjectToDbus(new InstanceAdaptor(ptr), objectPath, getDBusInterface<InstanceAdaptor>())) {
m_Instances.insert(QDBusObjectPath{objectPath}, ins);
return QDBusObjectPath{objectPath};
}

View File

@ -33,9 +33,9 @@ public:
{
static_assert(std::is_invocable_v<F, QVariant>, "param type must be QVariant.");
QString objectPath{DDEApplicationManager1JobObjectPath + QUuid::createUuid().toString()};
QFuture<QVariantList> future = QtConcurrent::mappedReduced(
args.begin(), args.end(), func, &QVariantList::insert, QVariantList{}, QtConcurrent::ReduceOption::OrderedReduce);
QString objectPath{DDEApplicationManager1JobObjectPath + QUuid::createUuid().toString(QUuid::Id128)};
auto future = QtConcurrent::mappedReduced(
args.begin(), args.end(), func,qOverload<QVariantList::parameter_type>(&QVariantList::append), QVariantList{}, QtConcurrent::ReduceOption::OrderedReduce);
QSharedPointer<JobService> job{new JobService{future}};
auto path = QDBusObjectPath{objectPath};
{
@ -43,8 +43,8 @@ public:
m_jobs.insert(path, job); // Insertion is always successful
}
emit JobNew(path, source);
registerObjectToDbus<decltype(job.data()), JobAdaptor>(job.data(), objectPath, getDBusInterface<JobAdaptor>());
auto emitRemove = [this, job, path, future] {
registerObjectToDbus(new JobAdaptor(job.data()), objectPath, getDBusInterface<JobAdaptor>());
auto emitRemove = [this, job, path, future] (QVariantList value) {
decltype(m_jobs)::size_type removeCount{0};
{
QMutexLocker locker{&m_mutex};
@ -54,18 +54,19 @@ public:
// and we shouldn't emit jobRemoved signal because this signal may already has been emit
if (removeCount == 0) {
qCritical() << "Job already has been removed: " << path.path();
return;
return value;
}
QString result{job->status()};
for (const auto &val : future.result()) {
if (val.canConvert<QDBusError>()) {
if (val.template canConvert<QDBusError>()) {
result = "failed";
}
break;
}
emit this->JobRemoved(path, result, future.result());
return value;
};
future.then(QtFuture::Launch::Sync, emitRemove);
future.then(emitRemove);
}
Q_SIGNALS:

View File

@ -1,18 +0,0 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "demo.h"
#include <iostream>
#include <QString>
void greet()
{
std::cout << QString{"Hello"}.toStdString() <<std::endl;
}
int main()
{
greet();
return 0;
}

View File

@ -110,18 +110,16 @@ std::optional<DesktopFile> DesktopFile::searchDesktopFile(const QString &desktop
auto components = path.split(QDir::separator()).toList();
auto it = std::find(components.cbegin(), components.cend(), "applications");
if (it == components.cend()) {
qWarning() << "fatal error: file location invalid";
err = ParseError::InvalidLocation;
return std::nullopt;
qWarning() << "custom location detected, Id wouldn't be generated.";
} else {
QString FileId;
++it;
while (it != components.cend())
FileId += (*(it++) + "-");
id = FileId.chopped(1);
}
QString FileId;
++it;
while (it != components.cend())
FileId += (*(it++) + "-");
id = FileId.chopped(1);
err = ParseError::NoError;
return DesktopFile{path,id};
return DesktopFile{std::move(path),std::move(id)};
}
ParseError DesktopEntry::parse(QTextStream& stream) noexcept
@ -239,13 +237,16 @@ QString DesktopEntry::Value::toIconString(bool &ok) const noexcept
bool DesktopEntry::Value::toBoolean(bool &ok) const noexcept
{
ok = true;
const auto& str = (*this)[defaultKeyStr];
if (str.compare("true"))
return true;
if (str.compare("false"))
return false;
ok = false;
const auto& str = (*this)[defaultKeyStr];
if (str == "true") {
ok = true;
return true;
}
if (str == "false") {
ok = true;
return false;
}
return false;
}
@ -262,3 +263,41 @@ QDebug operator<<(QDebug debug, const DesktopEntry::Value &v)
debug << static_cast<const QMap<QString,QString>&>(v);
return debug;
}
QDebug operator<<(QDebug debug, const ParseError &v)
{
QDebugStateSaver saver{debug};
QString errMsg;
switch (v) {
case ParseError::NoError:{
errMsg = "no error.";
break;
}
case ParseError::NotFound:{
errMsg = "file not found.";
break;
}
case ParseError::MismatchedFile:{
errMsg = "file type is mismatched.";
break;
}
case ParseError::InvalidLocation:{
errMsg = "file location is invalid, please check $XDG_DATA_DIRS.";
break;
}
case ParseError::OpenFailed:{
errMsg = "couldn't open the file.";
break;
}
case ParseError::GroupHeaderInvalid:{
errMsg = "groupHead syntax is invalid.";
break;
}
case ParseError::EntryKeyInvalid:{
errMsg = "key syntax is invalid.";
break;
}
}
debug << errMsg;
return debug;
}

View File

@ -1,5 +0,0 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
void greet();

View File

@ -14,7 +14,6 @@ constexpr static auto defaultKeyStr = "default";
enum class ParseError {
NoError,
NotFound,
FilePathEmpty,
MismatchedFile,
InvalidLocation,
OpenFailed,
@ -37,13 +36,13 @@ public:
friend QDebug operator<<(QDebug debug, const DesktopEntry::Value &v);
private:
QString unescape(const QString& str) const noexcept;
[[nodiscard]] QString unescape(const QString &str) const noexcept;
};
DesktopEntry() = default;
~DesktopEntry() = default;
ParseError parse(QTextStream& stream) noexcept;
QMap<QString, Value> group(const QString &key) const noexcept;
[[nodiscard]] ParseError parse(QTextStream& stream) noexcept;
[[nodiscard]] QMap<QString, Value> group(const QString &key) const noexcept;
private:
QMap<QString, QMap<QString, Value>> m_entryMap;
@ -54,13 +53,23 @@ private:
struct DesktopFile
{
const QString filePath;
const QString desktopId;
DesktopFile(const DesktopFile &) = default;
DesktopFile(DesktopFile &&) = default;
DesktopFile &operator=(const DesktopFile &) = default;
DesktopFile &operator=(DesktopFile &&) = default;
~DesktopFile() = default;
const QString &filePath() const { return m_filePath; }
const QString &desktopId() const { return m_desktopId; }
static std::optional<DesktopFile> searchDesktopFile(const QString &desktopFilePath, ParseError& err) noexcept;
private:
DesktopFile() = default;
DesktopFile(QString &&path,QString &&fileId):m_filePath(std::move(path)),m_desktopId(std::move(fileId)){}
QString m_filePath;
QString m_desktopId;
};
QDebug operator<<(QDebug debug, const DesktopEntry::Value& v);
QDebug operator<<(QDebug debug, const ParseError &v);

View File

@ -52,21 +52,7 @@ private:
QString m_busAddress;
};
template <typename T, typename U>
bool registerObjectToDbus(T parent, const QString &path, const QString &interface)
{
using service_type = std::remove_const_t<T>;
static_assert(std::is_pointer_v<service_type>, "param type must be a pointer");
static_assert(std::is_base_of_v<QObject, std::remove_pointer_t<T>> and
std::is_base_of_v<QObject, U>,
"param type must derive QObject");
auto &con = ApplicationManager1DBus::instance().CustomBus();
if (!con.registerObject(path, interface, new U{parent})) {
qCritical() << "register object failed:" << path << interface << con.lastError();
return false;
}
return true;
}
bool registerObjectToDbus(QObject* o, const QString &path, const QString &interface);
template <typename T>
QString getDBusInterface()

4
src/main.cpp Normal file
View File

@ -0,0 +1,4 @@
int main()
{
return 0;
}

11
src/utils.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "global.h"
bool registerObjectToDbus(QObject *o, const QString &path, const QString &interface)
{
auto &con = ApplicationManager1DBus::instance().CustomBus();
if (!con.registerObject(path, interface, o)) {
qCritical() << "register object failed:" << path << interface << con.lastError();
return false;
}
return true;
}

39
tests/CMakeLists.txt Normal file
View File

@ -0,0 +1,39 @@
set(BIN_NAME "ut-ddeam")
include(FindGTest)
find_package(GTest REQUIRED)
add_compile_definitions(DDEAM_UNIT_TESTING)
file(GLOB_RECURSE SRCS ${PROJECT_SOURCE_DIR}/src/*.cpp)
file(GLOB_RECURSE TESTS ${CMAKE_CURRENT_LIST_DIR}/*.cpp)
list(REMOVE_ITEM SRCS "${PROJECT_SOURCE_DIR}/src/main.cpp")
list(REMOVE_ITEM SRCS "${PROJECT_SOURCE_DIR}/src/utils.cpp")
add_executable(${BIN_NAME} ${SRCS} ${TESTS})
target_include_directories(${BIN_NAME} PRIVATE
${PROJECT_BINARY_DIR}/
)
target_link_libraries(${BIN_NAME} PRIVATE
GTest::gtest
${AdaptorLib}
)
target_compile_options(${BIN_NAME} PRIVATE
-fsanitize=undefined
-fsanitize=address
)
target_link_options(${BIN_NAME} PRIVATE
-fsanitize=undefined
-fsanitize=address
)
add_test(
NAME UnitTest
COMMAND ${BIN_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)

View File

@ -0,0 +1,110 @@
[Desktop Entry]
Categories=Utility;TextEditor;
Comment=Simple and easy to use text editor
Exec=deepin-editor %F
Icon=deepin-editor
Name=Text Editor
GenericName=Text Editor
StartupNotify=false
Type=Application
X-Deepin-AppID=deepin-editor
X-MultipleArgs=false
X-Deepin-CreatedBy=com.deepin.dde.daemon.Launcher
X-Deepin-Vendor=deepin
# Translations:
# Do not manually modify!
Comment[ar]=محرر النصوص بسيط وسهل الاستخدام
Comment[bo]=
Comment[br]=An aozer testennoù simpl hag aes d'ober gantañ
Comment[ca]=Editor de text simple i fàcil d'usar
Comment[cs]=Jednoduchý a snadno se používající textový editor
Comment[da]=Simpel og letanvendelig teksteditor
Comment[de]=Einfacher, leicht zu bedienender Texteditor
Comment[es]=Editor de texto simple y fácil de usar
Comment[et]=Lihtne ja kergesti kasutatav tekstiredaktor
Comment[fi]=Yksinkertainen ja helppokäyttöinen tekstieditori
Comment[fr]=Éditeur de texte simple et facile à utiliser
Comment[gl_ES]=Editor de texto sinxelo e fácil de usar
Comment[hr]=Jednostavan i lagan za korištenje uređivač teksta
Comment[hu]=Letisztult és könnyen használható szövegszerkesztő
Comment[it]=Editor di testo semplice e facile da usare. Localizzazione italiana a cura di Massimo A. Carofano.
Comment[ko]=
Comment[lt]=Paprastas ir lengvas naudoti tekstų redaktorius
Comment[ms]=Penyunting teks yang ringkas dan mudah digunakan
Comment[nl]=Eenvoudig te gebruiken tekstbewerker
Comment[pl]=Prosty i łatwy w użyciu edytor tekstu
Comment[pt]=Editor de texto simples e fácil de usar
Comment[pt_BR]=Um editor de texto simples e fácil de usar
Comment[ru]=Простой и удобный текстовый редактор
Comment[sq]=Përpunues tekstesh i thjeshtë dhe i kollajtë për tu përdorur
Comment[sr]=Уењђивач текста који је једноставан за употребу
Comment[tr]=Basit ve kullanımı kolay metin düzenleyici
Comment[ug]=ئاددىي، قوللىنىشچان تېكىست تەھرىرلىگۈچ
Comment[uk]=Простий і доступний текстовий редактор
Comment[zh_CN]=
Comment[zh_HK]=
Comment[zh_TW]=
GenericName[ar]=محرر النصوص
GenericName[bo]=
GenericName[br]=Aozer testennoù
GenericName[ca]=Editor de text
GenericName[cs]=Textový editor
GenericName[da]=Teksteditor
GenericName[de]=Text Editor
GenericName[es]=Editor de texto
GenericName[et]=Tekstiredaktor
GenericName[fi]=Tekstieditori
GenericName[fr]=Éditeur de texte
GenericName[en_US.UTF-8@euro;collation=traditional]=just for test\;teststing=abab\;
GenericName[gl_ES]=Editor de texto
GenericName[hr]=Uređivač teksta
GenericName[hu]=Szövegszerkesztő
GenericName[it]=Editor di Testo
GenericName[ko]=
GenericName[lt]=Tekstų redaktorius
GenericName[ms]=Penyunting Teks
GenericName[nl]=Tekstbewerker
GenericName[pl]=Edytor tekstu
GenericName[pt]=Editor de texto
GenericName[pt_BR]=Editor de Textos
GenericName[ru]=Текстовый редактор
GenericName[sq]=Përpunues Tekstesh
GenericName[sr]=Уређивач Текста
GenericName[tr]=Metin Düzenleyici
GenericName[ug]=تېكىست تەھرىرلىگۈچ
GenericName[uk]=Текстовий редактор
GenericName[zh_CN]=
GenericName[zh_HK]=
GenericName[zh_TW]=
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-patch;text/x-adasrc;text/x-chdr;text/x-csrc;text/css;application/x-desktop;text/x-patch;text/x-fortran;text/html;text/x-java;text/x-tex;text/x-makefile;text/x-objcsrc;text/x-pascal;application/x-perl;application/x-perl;application/x-php;text/vnd.wap.wml;text/x-python;application/x-ruby;text/sgml;application/xml;model/vrml;image/svg+xml;application/json;
Name[ar]=محرر نصوص ديبين
Name[bo]=
Name[br]=Aozer testennoù Deepin
Name[ca]=Editor de text del Deepin
Name[cs]=Deepin textový editor
Name[da]=Deepin teksteditor
Name[de@euro]=Deepin Text Editor
Name[es]=Editor de texto
Name[et]=Deepin tekstiredaktor
Name[fi]=Deepin tekstieditori
Name[fr]=Éditeur de texte Deepin
Name[gl_ES]=Editor de texto Deepin
Name[hr]=Deepin uređivač teksta
Name[hu]=Deepin® Szövegszerkesztő
Name[it]=Editor di Testo di Deepin
Name[ko]=Deepin
Name[lt]=Deepin tekstų redaktorius
Name[ms]=Penyunting Teks Deepin
Name[nl]=Deepin Tekstbewerker
Name[pl]=Edytor Tekstu Deepin
Name[pt]=Editor de texto Deepin
Name[pt_BR]=deepin Editor de Textos
Name[ru]=Текстовый Редактор Deepin
Name[sq]=Përpunues Tekstesh Deepin
Name[sr]=Дипин Уређивач Текста
Name[tr]=Deepin Metin Düzenleyici
Name[ug]=Deepin تېكىست تەھرىرلىگۈچ
Name[uk]=Текстовий редактор Deepin
Name[zh_CN]=
Name[zh_HK]=Deepin
Name[zh_TW]=Deepin

22
tests/main.cpp Normal file
View File

@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include <QCoreApplication>
#include <gtest/gtest.h>
#include <QTimer>
#include <sanitizer/asan_interface.h>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int ret{0};
QTimer::singleShot(0, &app, [&ret] {
ret = RUN_ALL_TESTS();
QCoreApplication::quit();
});
__sanitizer_set_report_path("asan_am.log");
QCoreApplication::exec();
return ret;
}

81
tests/ut_desktopentry.cpp Normal file
View File

@ -0,0 +1,81 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "desktopentry.h"
#include <gtest/gtest.h>
#include <QTextStream>
#include <QSharedPointer>
#include <QLocale>
#include <QDir>
#include <QFile>
class TestDesktopEntry : public testing::Test
{
public:
static void SetUpTestCase()
{
auto curDir = QDir::current();
QString path{curDir.absolutePath() + "/data/desktopExample.desktop"};
ParseError err;
auto file = DesktopFile::searchDesktopFile(path,err);
if (!file.has_value()) {
qWarning() << "search " << path << "failed:" << err;
return;
}
m_file.reset(new DesktopFile{std::move(file).value()});
}
void SetUp() override
{
}
void TearDown() override {}
QSharedPointer<DesktopFile> file() { return m_file; }
private:
static inline QSharedPointer<DesktopFile> m_file;
};
TEST_F(TestDesktopEntry, desktopFile)
{
const auto& fileptr = file();
ASSERT_FALSE(fileptr.isNull());
const auto &exampleFile = file();
auto curDir = QDir::current();
QString path{curDir.absolutePath() + "/data/desktopExample.desktop"};
EXPECT_EQ(exampleFile->filePath().toStdString(), path.toStdString());
EXPECT_EQ(exampleFile->desktopId().toStdString(), "");
}
TEST_F(TestDesktopEntry, prase)
{
const auto &exampleFile = file();
ASSERT_FALSE(exampleFile.isNull());;
DesktopEntry entry;
QFile in{exampleFile->filePath()};
ASSERT_TRUE(in.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text));
QTextStream fs{&in};
auto err = entry.parse(fs);
ASSERT_EQ(err, ParseError::NoError);
auto group = entry.group("Desktop Entry");
ASSERT_FALSE(group.isEmpty());
auto name = group.constFind("Name");
ASSERT_NE(name, group.cend());
bool ok;
name->toBoolean(ok);
EXPECT_FALSE(ok);
name->toNumeric(ok);
EXPECT_FALSE(ok);
auto defaultName = name->toString(ok);
ASSERT_TRUE(ok);
EXPECT_TRUE(defaultName == "Text Editor");
auto localeString = name->toLocaleString(QLocale{"zh_CN"}, ok);
ASSERT_TRUE(ok);
EXPECT_TRUE(localeString == "文本编辑器");
}

41
tests/ut_jobmanager.cpp Normal file
View File

@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "jobmanager1service.h"
#include "jobservice.h"
#include <gtest/gtest.h>
class TestJobManager : public testing::Test
{
public:
JobManager1Service& service() { return m_jobManager; }
private:
JobManager1Service m_jobManager;
};
TEST_F(TestJobManager, addJob)
{
QDBusObjectPath sourcePath{"/org/deepin/Test1"};
QVariantList args{{"Application"}, {"Application"}, {"Application"}, {"Application"}};
auto &manager = service();
QDBusObjectPath jobPath;
QObject::connect(&manager, &JobManager1Service::JobNew, [&](const QDBusObjectPath &job, const QDBusObjectPath &source) {
jobPath = job;
EXPECT_TRUE(source == sourcePath);
});
QObject::connect(&manager,
&JobManager1Service::JobRemoved,
[&](const QDBusObjectPath &job, const QString &status, const QVariantList &result) {
EXPECT_TRUE(jobPath == job);
EXPECT_TRUE(status == "finished");
EXPECT_TRUE(result.count() == 4);
qDebug() << "job was really removed";
});
manager.addJob(sourcePath, [](auto value) -> QVariant {
EXPECT_TRUE(value.toString() == "Application");
return QVariant::fromValue(true);
}, args);
QThread::sleep(1); // force wait
}

6
tests/utils.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "global.h"
bool registerObjectToDbus(QObject *, const QString &, const QString &)
{
return true;
}