diff --git a/deepin-devicemanager/tests/src/LogConfigRead/ut_mlogger.cpp b/deepin-devicemanager/tests/src/LogConfigRead/ut_mlogger.cpp new file mode 100644 index 000000000..7b76766a4 --- /dev/null +++ b/deepin-devicemanager/tests/src/LogConfigRead/ut_mlogger.cpp @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_Head.h" +#include "stub.h" + +#include +#include + +#define private public +#define protected public +#include "LogConfigread.h" +#undef private +#undef protected + +// ---- DConfig stub helpers ------------------------------------------------- + +// Pre-created DConfig used as the return value of the stubbed create(). +static Dtk::Core::DConfig *ut_mlogger_config = nullptr; + +// Replacement for DConfig::create(appId, name, subpath, parent). +static Dtk::Core::DConfig *ut_dconfig_create(const QString &, const QString &, + const QString &, QObject *) +{ + return ut_mlogger_config; +} + +// Replacement for DConfig::value(key, fallback) — returns empty so that +// appendRules receives nothing and only env-var rules end up in m_rules. +static QVariant ut_dconfig_value(const Dtk::Core::DConfig *, const QString &, + const QVariant &) +{ + return QVariant(QByteArray("")); +} + +// =========================================================================== +class UT_MLogger : public UT_HEAD +{ +public: + void SetUp() override + { + // MLogger ctor reads QT_LOGGING_RULES then unsets it. + qputenv("QT_LOGGING_RULES", "a.debug=true"); + ut_mlogger_config = new Dtk::Core::DConfig("org.deepin.devicemanager"); + + m_stub.set( + (Dtk::Core::DConfig * (*)(const QString &, const QString &, const QString &, QObject *)) + &Dtk::Core::DConfig::create, + ut_dconfig_create); + m_stub.set( + (QVariant (Dtk::Core::DConfig::*)(const QString &, const QVariant &) const) + &Dtk::Core::DConfig::value, + ut_dconfig_value); + } + + void TearDown() override + { + + delete ut_mlogger_config; + ut_mlogger_config = nullptr; + qunsetenv("QT_LOGGING_RULES"); + } + + Stub m_stub; +}; + +// ---- Constructor ----------------------------------------------------------- +TEST_F(UT_MLogger, UT_MLogger_ctor_readsEnvLoggingRules) +{ + MLogger logger; + // env "a.debug=true" has no ';' → m_rules should equal env value as-is. + EXPECT_EQ(QString("a.debug=true"), logger.m_rules); +} + +TEST_F(UT_MLogger, UT_MLogger_ctor_readsEnvLoggingRulesWithSemicolons) +{ + qputenv("QT_LOGGING_RULES", "a.debug=true;b.debug=false"); + MLogger logger; + // ctor calls setRules internally → ';' replaced with '\n'. + EXPECT_EQ(QString("a.debug=true\nb.debug=false"), logger.m_rules); +} + +// ---- setRules -------------------------------------------------------------- +TEST_F(UT_MLogger, UT_MLogger_setRules_replacesSemicolons) +{ + MLogger logger; + logger.setRules("a.debug=true;b.debug=false;c.debug=true"); + EXPECT_EQ(QString("a.debug=true\nb.debug=false\nc.debug=true"), logger.m_rules); +} + +TEST_F(UT_MLogger, UT_MLogger_setRules_noSemicolons) +{ + MLogger logger; + logger.setRules("a.debug=true"); + EXPECT_EQ(QString("a.debug=true"), logger.m_rules); +} + +TEST_F(UT_MLogger, UT_MLogger_setRules_emptyString) +{ + MLogger logger; + logger.setRules(""); + EXPECT_EQ(QString(""), logger.m_rules); +} + +// ---- appendRules ----------------------------------------------------------- +TEST_F(UT_MLogger, UT_MLogger_appendRules_appendsNewRules) +{ + MLogger logger; + logger.m_rules = "a.debug=true"; + logger.appendRules("b.debug=false"); + EXPECT_EQ(QString("a.debug=true\nb.debug=false"), logger.m_rules); +} + +TEST_F(UT_MLogger, UT_MLogger_appendRules_deduplicatesExistingRules) +{ + MLogger logger; + logger.m_rules = "a.debug=true"; + logger.appendRules("a.debug=true"); + // Duplicate rule should not be appended. + EXPECT_EQ(QString("a.debug=true"), logger.m_rules); +} + +TEST_F(UT_MLogger, UT_MLogger_appendRules_emptyRulesDoesNothing) +{ + MLogger logger; + logger.m_rules = "a.debug=true"; + logger.appendRules(""); + // Empty input → split gives [""], which is "contained" → no append. + EXPECT_EQ(QString("a.debug=true"), logger.m_rules); +} + +TEST_F(UT_MLogger, UT_MLogger_appendRules_mixedNewAndExisting) +{ + MLogger logger; + logger.m_rules = "a.debug=true"; + logger.appendRules("a.debug=true;b.debug=false"); + // Only the new rule "b.debug=false" should be appended. + EXPECT_EQ(QString("a.debug=true\nb.debug=false"), logger.m_rules); +} + +TEST_F(UT_MLogger, UT_MLogger_appendRules_toEmptyRules) +{ + MLogger logger; + logger.m_rules = ""; + logger.appendRules("a.debug=true"); + // When m_rules is empty, tmplist.join is assigned directly. + EXPECT_EQ(QString("a.debug=true"), logger.m_rules); +} + +// ---- rules() getter -------------------------------------------------------- +TEST_F(UT_MLogger, UT_MLogger_rules_returnsMRules) +{ + MLogger logger; + logger.m_rules = "test.rule=true"; + EXPECT_EQ(QString("test.rule=true"), logger.rules()); +} + +// ---- Destructor ------------------------------------------------------------ +TEST_F(UT_MLogger, UT_MLogger_destructor_noCrash) +{ + MLogger *logger = new MLogger; + delete logger; + SUCCEED(); +} diff --git a/deepin-devicemanager/tests/src/Widget/ut_headerinfotabledelegate.cpp b/deepin-devicemanager/tests/src/Widget/ut_headerinfotabledelegate.cpp new file mode 100644 index 000000000..9c1a5264f --- /dev/null +++ b/deepin-devicemanager/tests/src/Widget/ut_headerinfotabledelegate.cpp @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "headerinfotableDelegate.h" +#include "ut_Head.h" +#include "stub.h" + +#include +#include +#include + +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE + +DStyle *ut_HeaderInfoDelegate_style = nullptr; + +static DStyle *ut_headerinfo_style() +{ + return ut_HeaderInfoDelegate_style; +} + +class UT_HeaderInfoDelegate : public UT_HEAD +{ +public: + void SetUp() override + { + m_tableWidget = new QTableWidget; + m_delegate = new HeaderInfoDelegate(m_tableWidget); + m_tableWidget->setItemDelegate(m_delegate); + m_tableWidget->setColumnCount(1); + m_tableWidget->insertRow(0); + m_tableWidget->setItem(0, 0, new QTableWidgetItem("test")); + ut_HeaderInfoDelegate_style = new DStyle; + } + + void TearDown() override + { + delete m_tableWidget; + delete ut_HeaderInfoDelegate_style; + ut_HeaderInfoDelegate_style = nullptr; + } + + QTableWidget *m_tableWidget = nullptr; + HeaderInfoDelegate *m_delegate = nullptr; +}; + +// ---- Constructor ----------------------------------------------------------- +TEST_F(UT_HeaderInfoDelegate, UT_HeaderInfoDelegate_ctor) +{ + EXPECT_NE(nullptr, m_delegate); +} + +// ---- paint (non-selected state) -------------------------------------------- +TEST_F(UT_HeaderInfoDelegate, UT_HeaderInfoDelegate_paint_nonSelected) +{ + QStyleOptionViewItem option; + QPainter painter(m_tableWidget); + QModelIndex index = m_tableWidget->model()->index(0, 0); + + Stub stub; + stub.set(ADDR(DApplication, style), ut_headerinfo_style); + + m_delegate->paint(&painter, option, index); + EXPECT_FALSE(m_tableWidget->grab().isNull()); +} + +// ---- paint (selected state) ------------------------------------------------ +TEST_F(UT_HeaderInfoDelegate, UT_HeaderInfoDelegate_paint_selected) +{ + QStyleOptionViewItem option; + option.state |= QStyle::State_Selected; + QPainter painter(m_tableWidget); + QModelIndex index = m_tableWidget->model()->index(0, 0); + + Stub stub; + stub.set(ADDR(DApplication, style), ut_headerinfo_style); + + m_delegate->paint(&painter, option, index); + EXPECT_FALSE(m_tableWidget->grab().isNull()); +} + +// ---- paint with no active window (inactive palette path) ------------------- +TEST_F(UT_HeaderInfoDelegate, UT_HeaderInfoDelegate_paint_noActiveWindow) +{ + QStyleOptionViewItem option; + QPainter painter(m_tableWidget); + QModelIndex index = m_tableWidget->model()->index(0, 0); + + Stub stub; + stub.set(ADDR(DApplication, style), ut_headerinfo_style); + + // DApplication::activeWindow() returns nullptr when no window is active. + // This exercises the DPalette::Inactive branch. + m_delegate->paint(&painter, option, index); + EXPECT_FALSE(m_tableWidget->grab().isNull()); +}