Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions autotests/dfm-search-tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ extern QObject *create_tst_ContentSearchEngine();
extern QObject *create_tst_FileNameSearchEngine();
extern QObject *create_tst_RecentSearchEngine();
extern QObject *create_tst_CliOptions();
extern QObject *create_tst_DConfigParsing();

int main(int argc, char *argv[])
{
Expand Down Expand Up @@ -111,5 +112,9 @@ int main(int argc, char *argv[])
result |= QTest::qExec(testObj19, argc, argv);
delete testObj19;

QObject *testObj20 = create_tst_DConfigParsing();
result |= QTest::qExec(testObj20, argc, argv);
delete testObj20;

return result;
}
160 changes: 160 additions & 0 deletions autotests/dfm-search-tests/tst_dconfig_parsing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include <QTest>

Check warning on line 5 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QTest> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 5 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QTest> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDebug>

Check warning on line 6 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDebug> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 6 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QDebug> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QVariant>

Check warning on line 7 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QVariant> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 7 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QVariant> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QVariantList>

Check warning on line 8 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QVariantList> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 8 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QVariantList> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QStringList>

Check warning on line 9 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QStringList> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 9 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QStringList> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <dfm-search/dsearch_global.h>

Check warning on line 11 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <dfm-search/dsearch_global.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 11 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <dfm-search/dsearch_global.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <dfm-search-lib/utils/searchutility.h>

Check warning on line 12 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <dfm-search-lib/utils/searchutility.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 12 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <dfm-search-lib/utils/searchutility.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

using namespace DFMSEARCH;

class tst_DConfigParsing : public QObject
{
Q_OBJECT

private Q_SLOTS:

Check warning on line 20 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

There is an unknown macro here somewhere. Configuration is required. If Q_SLOTS is a macro then please configure it.

Check warning on line 20 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

There is an unknown macro here somewhere. Configuration is required. If Q_SLOTS is a macro then please configure it.
void initTestCase();
void cleanupTestCase();
void testSemicolonSeparatedString();
void testSingleValueString();
void testStringListVariant();
void testVariantListVariant();
void testEmptyString();
void testEmptyStringList();
void testInvalidVariant();
void testNonConvertibleType();
void testSemicolonWithEmptyParts();
void testTrailingSemicolon();
};

void tst_DConfigParsing::initTestCase()
{
}

void tst_DConfigParsing::cleanupTestCase()
{
}

void tst_DConfigParsing::testSemicolonSeparatedString()
{
QVariant value(QString("txt;pdf;docx;xlsx"));
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(result.has_value(), "Should return a value for semicolon-separated string");
QCOMPARE(result->size(), 4);
QCOMPARE(result->at(0), QString("txt"));
QCOMPARE(result->at(1), QString("pdf"));
QCOMPARE(result->at(2), QString("docx"));
QCOMPARE(result->at(3), QString("xlsx"));
}

void tst_DConfigParsing::testSingleValueString()
{
QVariant value(QString("txt"));
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(result.has_value(), "Should return a value for single string");
QCOMPARE(result->size(), 1);
QCOMPARE(result->at(0), QString("txt"));
}

void tst_DConfigParsing::testStringListVariant()
{
QStringList list = { "txt", "pdf", "docx" };
QVariant value(list);
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(result.has_value(), "Should return a value for QStringList variant");
QCOMPARE(result->size(), 3);
QCOMPARE(result->at(0), QString("txt"));
QCOMPARE(result->at(1), QString("pdf"));
QCOMPARE(result->at(2), QString("docx"));
}

void tst_DConfigParsing::testVariantListVariant()
{
QVariantList list;
list << QVariant("home") << QVariant("usr") << QVariant("opt");
QVariant value(list);
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(result.has_value(), "Should return a value for QVariantList variant");
QCOMPARE(result->size(), 3);
QCOMPARE(result->at(0), QString("home"));
QCOMPARE(result->at(1), QString("usr"));
QCOMPARE(result->at(2), QString("opt"));
}

void tst_DConfigParsing::testEmptyString()
{
QVariant value(QString(""));
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(result.has_value(), "Should return a value for empty string");
QCOMPARE(result->size(), 1);
QVERIFY2(result->at(0).isEmpty(), "Single element should be empty string");
}

void tst_DConfigParsing::testEmptyStringList()
{
QStringList list;
QVariant value(list);
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(result.has_value(), "Should return a value for empty QStringList");
QCOMPARE(result->size(), 0);
}

void tst_DConfigParsing::testInvalidVariant()
{
QVariant value;
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(!result.has_value(), "Should return nullopt for invalid QVariant");
}

void tst_DConfigParsing::testNonConvertibleType()
{
QVariant value(42);
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(!result.has_value(), "Should return nullopt for non-convertible type (int)");
}

void tst_DConfigParsing::testSemicolonWithEmptyParts()
{
QVariant value(QString("txt;;pdf;"));
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(result.has_value(), "Should return a value");
QCOMPARE(result->size(), 4);
QCOMPARE(result->at(0), QString("txt"));
QCOMPARE(result->at(1), QString(""));
QCOMPARE(result->at(2), QString("pdf"));
QCOMPARE(result->at(3), QString(""));
}

void tst_DConfigParsing::testTrailingSemicolon()
{
QVariant value(QString("/home;/usr;/opt;"));
auto result = SearchUtility::parseVariantToStringList(value);

QVERIFY2(result.has_value(), "Should return a value");
QCOMPARE(result->size(), 4);
QCOMPARE(result->at(0), QString("/home"));
QCOMPARE(result->at(1), QString("/usr"));
QCOMPARE(result->at(2), QString("/opt"));
QCOMPARE(result->at(3), QString(""));
}

QObject *create_tst_DConfigParsing()
{
return new tst_DConfigParsing();
}

#include "tst_dconfig_parsing.moc"

Check warning on line 160 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "tst_dconfig_parsing.moc" not found.

Check warning on line 160 in autotests/dfm-search-tests/tst_dconfig_parsing.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: "tst_dconfig_parsing.moc" not found.
30 changes: 19 additions & 11 deletions src/dfm-search/dfm-search-lib/utils/searchutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,8 @@ static std::optional<QStringList> tryLoadStringListFromDConfigInternal(

QVariant value = dconfigPtr->value(keyName);

if (!value.isValid()) {
qDebug() << "DConfig: Key '" << keyName << "' not found in appId:" << appId << "schemaId:" << schemaId;
return std::nullopt; // Key not found
}

if (!value.canConvert<QStringList>()) {
qWarning() << "DConfig: Value for key '" << keyName << "' in appId:" << appId << "schemaId:" << schemaId
<< "cannot be converted to QStringList. Actual type:" << value.typeName();
return std::nullopt; // Type mismatch
}
// No need to delete dconfigPtr, dconfigParent will manage it when it goes out of scope.
return value.toString().split(';');
return SearchUtility::parseVariantToStringList(value);
}

// --- Specific Loader for "supportedFileExtensions" ---
Expand Down Expand Up @@ -887,5 +877,23 @@ QSet<QString> semanticPicExtensions()
return kExts;
}

std::optional<QStringList> parseVariantToStringList(const QVariant &value)
{
if (!value.isValid()) {
return std::nullopt;
}

if (!value.canConvert<QStringList>()) {
return std::nullopt;
}

// DConfig value 可能是 JSON 数组(list 类型)或分号分隔字符串;
// 当为 JSON 数组时 toString() 返回空,必须用 toStringList()。
if (value.type() == QVariant::List || value.type() == QVariant::StringList) {
return value.toStringList();
}
return value.toString().split(';');
}

} // namespace SearchUtility
DFM_SEARCH_END_NS
14 changes: 14 additions & 0 deletions src/dfm-search/dfm-search-lib/utils/searchutility.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
#ifndef SEARCHUTILITY_H
#define SEARCHUTILITY_H

#include <QStringList>

Check warning on line 7 in src/dfm-search/dfm-search-lib/utils/searchutility.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QStringList> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 7 in src/dfm-search/dfm-search-lib/utils/searchutility.h

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QStringList> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QString>
#include <QSet>
#include <QVariant>
#include <optional>

// SPDX-FileCopyrightText: 2025 - 2026 UnionTech Software Technology Co., Ltd.
//
Expand All @@ -28,6 +30,18 @@
*/
QStringList extractBooleanKeywords(const SearchQuery &query);

/**
* @brief Parse a DConfig QVariant value into a QStringList
*
* DConfig values may arrive as a semicolon-separated string or as a JSON array
* (QVariant::List / QVariant::StringList). When the value is a list type,
* toString() returns an empty string, so toStringList() must be used instead.
*
* @param value The QVariant from DConfig::value()
* @return The parsed string list, or std::nullopt if the value is invalid or not convertible
*/
std::optional<QStringList> parseVariantToStringList(const QVariant &value);

/**
* @brief Get the list of supported file types for Deepin Anything
* @return List of supported file types
Expand Down
Loading