Skip to content

test(Widget): rewrite 6 Widget unit tests with 53 value-driven cases (t22) - #936

Open
add-uos wants to merge 6 commits into
linuxdeepin:masterfrom
add-uos:ut-t22
Open

add-uos wants to merge 6 commits into
linuxdeepin:masterfrom
add-uos:ut-t22

Conversation

@add-uos

@add-uos add-uos commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

重写 Issue 指定 6 个 src/Widget 源文件的 Google Test 单元测试(t22 批次),全部按值驱动 + AAA 风格组织,并复用既有 GTest 目录与 CMake 挂接方式(仅 APPEND)。

  • tests/src/ut_stub_helper.h(新增):ut_real_fn_addr 解决 GCC 虚函数成员指针打桩(vtable slot 解析),使 DDialog::exec 等虚函数可被 StubExt 安全替换(修复此前 SIGSEGV)
  • ut_btnlabel.cpp — UT_BtnLabel/UT_TipsLabel/UT_TitleLabel 14 例(linkActivated 四分支经虚表打桩覆盖)
  • ut_headerinfotablewidget.cpp — 9 例(updateData 空表/驱动/打印机/刷新合并、高度公式、reset、paint)
  • ut_drivericonwidget.cpp — 8 例(双构造重载、缩放居中、标签格式化、调色 -10/-30、主题切换恢复、反复构造析构)
  • ut_urlchooseredit.cpp — 7 例(对话框选择/取消/非本地告警、checkLocalFolder 形参被忽略实证、text 访问器)
  • ut_tipswidget.cpp — 9 例(ToolTip 标志、固定宽/边距、换行制表剥离、高度公式镜像、二次调用短路、主题恢复)
  • ut_cmdbuttonwidget.cpp — 6 例(点击信号 QSignalSpy、命名/嵌套布局、activeWindow 双分支、重复绘制几何稳定)

Verification

  • 6 个测试文件 self-check-structural 全绿(0 errors 0 warnings)
  • 53 例全部通过(offscreen,deepin-devicemanager-test 单体目标)
  • 6 个源文件行覆盖 100%(394/394 行,37/37 函数;lcov 采集)
  • 全量回归 1977 例通过;上游既有用例 UT_LogTreeView_drawRow 存在用例间状态污染(单跑通过,与本批次无关)
  • SPDX 版权头检查通过(2026 / UnionTech)
  • 疑似源码缺陷 2 项(均为 low,仅标红不改源码):UrlChooserEdit::checkLocalFolder 形参被 Q_UNUSED 忽略;CmdButtonWidget::paintEvent 存在无效 setWidth 死代码

Task

linuxdeepin/deepin-devicemanager#(对应任务 Issue 由 multica 平台跟踪)

Summary by Sourcery

Rewrite the six Widget test suites as comprehensive value-driven tests and add safe virtual-function stubbing support.

Enhancements:

  • Rewrite the six Widget unit-test suites with value-driven Google Test coverage for construction, state changes, rendering, signals, and branch behavior across 53 cases.
  • Add shared support for safely stubbing GCC virtual member functions in Widget tests.

Tests:

  • Expand coverage for BtnLabel, TipsLabel, TitleLabel, HeaderInfoTableWidget, DriverIconWidget, UrlChooserEdit, TipsWidget, and CmdButtonWidget, including edge cases and repeated operations.

Chores:

  • Standardize the rewritten tests around AAA structure and the existing test target integration.

… cases

Rewrite UT_BtnLabel/UT_TipsLabel/UT_TitleLabel (8+3+3 cases) in
value-driven AAA style: ctor state, linkActivated four branches via
DDialog::exec virtual-table stub, paintEvent flag-driven rendering.

Add tests/src/ut_stub_helper.h: ut_real_fn_addr resolves the real
implementation address for GCC virtual-member-function pointers
(vtable slot = (uintptr >> 3) when bit0 set), which allows StubExt to
patch virtual functions such as DDialog::exec without SIGSEGV.
UT_BtnLabel statics return configurable result and count invocations.

All 14 cases pass (offscreen); self-check-structural 0 errors.
…riven cases

Rewrite UT_HeaderInfoTableWidget in value-driven AAA style: ctor
config (row height, delegate, no-scrollbar), updateData empty list,
driver/printer rendering rows, refresh-merge path (second call keeps
rows), resetTableContents clearing, paintEvent direct invoke.
Drive real updateData with driver/printer info structures instead of
implementation-detail peeking; height formula row*ROW_HEIGHT+2 asserted
via constants.
… cases

Rewrite UT_DriverIconWidget in value-driven AAA style: both ctor
overloads (icon-only and title+desc), pixmap scaling and centering,
title/desc label formatting (elide, tooltip, fixed width), palette
adjustment mirroring palrtteTransparency (-10/-30), theme-change signal
restoring adjusted colors, and repeated construct/destroy robustness.
DWaterProgress::start stubbed to count invocations.
…ases

Rewrite UT_UrlChooserEdit in value-driven AAA style: ctor UI state and
home-path display, slotChooseUrl dialog-pick (local dir accepted via
button click), cancel-restore, non-local device alert + signal,
checkLocalFolder parameter-ignored reality (Q_UNUSED(path) validated as
defect record, not patched), and text() accessor consistency.
QFileDialog::getExistingDirectory stubbed via ADDR; QStorageInfo
isValid/device via set_lamda; QDir::homePath stubbed in SetUp for
determinism.
Rewrite UT_TipsWidget in value-driven AAA style: ctor tool-tip flag,
fixed width 254 and margins 8/10, palette window==base, setText
newline/tab stripping incl. repeated-set short circuit, setAlignment,
adjustContent height formula mirrored via QFontMetricsF helper and
second-call early-return, paintEvent direct invoke, theme-change
restoration after background break.
…cases

Rewrite UT_CmdButtonWidget in value-driven AAA style: ctor layout and
button text, click-through signal cmdButtonClicked via QSignalSpy
(covers initConnections connect), object naming and nested centered
layout, paintEvent both active/inactive window branches via
QApplication::activeWindow stub, and repeated-paint geometry
stability.
@sourcery-ai

sourcery-ai Bot commented Oct 26, 2026

Copy link
Copy Markdown

Sorry @add-uos, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 2 days and 12 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Oct 26, 2026

Copy link
Copy Markdown

Reviewer's Guide

Rewrites six Widget unit-test files into AAA/value-driven suites totaling 53 cases, adding deterministic stubs for GUI, dialog, storage, theme, and window-state dependencies plus a GCC virtual-function address helper; the PR reports all targeted tests and full regression passing with 100% coverage for the six sources.

File-Level Changes

Change Details Files
Rewrote the BtnLabel, TipsLabel, and TitleLabel tests around constructor state, dialog/feedback branches, and active/inactive palette behavior.
  • Added four controlled linkActivated cases using dialog and feedback stubs.
  • Covered paintEvent palette selection for active and inactive application states, including repeat calls.
  • Separated fixtures and assertions for all three label types.
deepin-devicemanager/tests/src/Widget/ut_btnlabel.cpp
Expanded HeaderInfoTableWidget tests to validate initialization, data replacement, row coloring, sizing, reset behavior, and painting paths.
  • Verified table configuration and delegate setup.
  • Added empty, single-row, multi-row, alternating-color, and repeated-update cases.
  • Covered resetTableContents and active/inactive paint branches.
deepin-devicemanager/tests/src/Widget/ut_headerinfotablewidget.cpp
Added value-driven coverage for DriverIconWidget’s construction variants, layout/content formatting, palette adjustment, theme refresh, and destruction.
  • Tested progress and pixmap constructor chains with controlled animation startup.
  • Checked icon sizing, label truncation/tooltips, layout placement, and -10/-30 color adjustments.
  • Verified theme signal restoration and repeated construct/destruct safety.
deepin-devicemanager/tests/src/Widget/ut_drivericonwidget.cpp
Added deterministic UrlChooserEdit tests for UI initialization, directory selection outcomes, local-storage validation, signal behavior, and path accessors.
  • Stubbed home paths, file dialogs, storage metadata, and alert display.
  • Covered selected local directories, cancellation restoration, non-local alerts, and signal payloads.
  • Documented and asserted the current behavior where checkLocalFolder ignores its argument.
deepin-devicemanager/tests/src/Widget/ut_urlchooseredit.cpp
Expanded TipsWidget tests to cover widget initialization, text normalization, alignment, content sizing, painting, and theme palette refresh.
  • Verified tooltip flags, fixed dimensions, margins, opacity, and line limits.
  • Covered newline/tab stripping, repeated text updates, height calculation and early return.
  • Checked paint-driven sizing and restoration of Window to Base palette color.
deepin-devicemanager/tests/src/Widget/ut_tipswidget.cpp
Reworked CmdButtonWidget tests around construction, signal forwarding, layout naming, active-window paint branches, and geometry stability.
  • Verified command button configuration and clicked-to-cmdButtonClicked propagation.
  • Checked object and accessibility names and layout presence.
  • Stubbed activeWindow to exercise both palette branches and repeated paint behavior.
deepin-devicemanager/tests/src/Widget/ut_cmdbuttonwidget.cpp
Introduced a shared helper to safely resolve GCC Itanium-ABI virtual member-function pointers before StubExt patching.
  • Resolves virtual member pointers through the object vtable slot.
  • Preserves direct addresses for non-virtual members.
  • Enables safe stubbing of DDialog::exec and similar virtual methods.
deepin-devicemanager/tests/src/ut_stub_helper.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 91 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交重写了6个Widget单元测试文件(ut_btnlabel/ut_cmdbuttonwidget/ut_drivericonwidget/ ut_headerinfotablewidget/ut_tipswidget/ut_urlchooseredit),新增53个值驱动测试用例, 并引入ut_stub_helper.h辅助虚函数打桩。测试覆盖度和质量显著提升,采用Arrange-Act-Assert模式, 注释详尽,打桩策略合理(拦截DDialog::exec/QFileDialog/QStorageInfo等外部依赖)。 存在少量代码质量问题:UT_DriverIconWidget的TearDown遗漏delete导致内存泄漏、 ut_stub_helper.h中虚函数PMF的__delta字段未初始化(技术性UB但实际可工作)、 部分文件残留无用include和未使用的stub成员。无安全漏洞。

|


🔍 详细分析

1. 语法逻辑 ✅

评价: 语法正确,逻辑清晰 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: [{'ut_stub_helper.h': '将MemFn out;改为MemFn out = pmf;,先完整复制PMF保留正确的__delta,再覆盖__pfn为真实地址'}]


2. 代码质量 ✅

评价: 代码结构清晰,注释完整 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: [{'ut_drivericonwidget.cpp': 'TearDown中添加delete m_widget; m_widget = nullptr;'}, {'ut_drivericonwidget.cpp和ut_cmdbuttonwidget.cpp': '移除#include "ut_Head.h"'}, {'ut_tipswidget.cpp': '移除未使用的stub成员、stub.clear()调用和#include "stubext.h"'}, {'ut_cmdbuttonwidget.cpp': '将EXPECT_GT(widthBefore, 0)改为EXPECT_GE(widthBefore, 0)或在SetUp中显式resize'}]


3. 代码性能 ✅

评价: 性能良好,资源使用合理 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: ['将m_probeDialog改为仅在需要打桩DDialog::exec的测试用例中创建局部变量']


4. 代码安全 🔒

评价: 存在0个安全漏洞 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: []


💡 改进建议代码示例

// ut_drivericonwidget.cpp — 修复TearDown内存泄漏
class UT_DriverIconWidget : public ::testing::Test
{
public:
    void SetUp()
    {
        g_utWaterStartCount = 0;
    }
    void TearDown()
    {
        stub.clear();
        delete m_widget;      // 修复:添加遗漏的delete
        m_widget = nullptr;
    }
    // ...
};

// ut_stub_helper.h — 修复未初始化__delta
template <typename MemFn>
inline MemFn ut_real_fn_addr(void *obj, MemFn pmf)
{
    MemFn out = pmf;  // 修复:先完整复制PMF,保留正确的__delta
    unsigned long bits = 0;
    std::memcpy(&bits, &pmf, sizeof(bits));
    if (bits & 1UL) {
        void **vptr = *reinterpret_cast<void ***>(obj);
        const unsigned long slot = bits >> 3;
        const unsigned long real = reinterpret_cast<unsigned long>(vptr[slot]);
        std::memcpy(&out, &real, sizeof(real));  // 仅覆盖__pfn
    }
    return out;
}

本报告由 AI 代码审查工具自动生成

add-uos added a commit to add-uos/deepin-devicemanager that referenced this pull request Oct 26, 2026
1. Root cause: checkLocalFolder(const QString &path) discarded the
   parameter via Q_UNUSED(path) and used member mp_folderPath instead,
   making the API misleading; CmdButtonWidget::paintEvent called
   this->rect().setWidth(808) on a temporary QRect copy, which is
   dead code since the next line achieves the intent correctly
2. Fix: remove Q_UNUSED(path) and use the path parameter in
   QStorageInfo constructor; remove the dead code line in paintEvent;
   update UT_UrlChooserEdit_checkLocalFolder_001 to pass smb:// path
   matching mp_folderPath so the test validates fixed behavior
3. Impact: checkLocalFolder now validates the actual parameter passed
   by the caller; paintEvent behavior unchanged since the dead line
   had no effect; test case now correctly expects alert for non-local
   path; current callers pass the same value so no behavior change

Influence:
1. Test checkLocalFolder with a local valid folder path
2. Test checkLocalFolder with a non-local or invalid path
3. Verify CmdButtonWidget paint rendering is unchanged

fix: 修复checkLocalFolder忽略形参及更新测试用例

1. 根因:checkLocalFolder(const QString &path) 通过 Q_UNUSED(path)
   丢弃形参,实际使用成员 mp_folderPath,导致 API 语义误导;
   CmdButtonWidget::paintEvent 中 this->rect().setWidth(808) 对
   临时 QRect 副本调用,属于死代码,下一行已正确实现相同逻辑
2. 方案:移除 Q_UNUSED(path),将 QStorageInfo info(mp_folderPath)
   改为 QStorageInfo info(path);移除 paintEvent 中的死代码行;
   更新 UT_UrlChooserEdit_checkLocalFolder_001 传入 smb:// 路径
   与 mp_folderPath 一致,使测试验证修复后的正确行为
3. 影响:checkLocalFolder 现在校验实际传入的形参;paintEvent 行为
   不变(死代码行本就无效果);测试用例现在正确期望非本地路径
   触发告警;当前调用点传入值与成员相同,实际无行为变化

Influence:
1. 测试 checkLocalFolder 传入本地有效文件夹路径
2. 测试 checkLocalFolder 传入非本地或无效路径
3. 验证 CmdButtonWidget 绘制效果无变化

Fixes: linuxdeepin#936
PMS: BUG-bug-fix-936-1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants