Skip to content

test(Page): rewrite unit tests for 5 Page classes (76 cases) - #906

Merged
deepin-bot[bot] merged 7 commits into
linuxdeepin:masterfrom
add-uos:ut-t15-pr
Oct 26, 2026
Merged

deepin-bot[bot] merged 7 commits into
linuxdeepin:masterfrom
add-uos:ut-t15-pr

Conversation

@add-uos

@add-uos add-uos commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Rewrite the unit tests for the 5 src/Page/ classes previously selected by
function-importance analysis, replacing the legacy suites with 76 focused
GTest cases:

Test suite Cases Line coverage
ut_pagetableheader 12 100% (73/73)
ut_pageinfo 16 98.2% (56/57)
ut_pagetablewidget 22 100% (70/70)
ut_devicewidget 19 98.5% (130/132)
ut_waitingwidget 7 100% (47/47)

What's included

  • 5 rewritten test sources under tests/src/Page/ (test code only).
  • Vendored stub-ext runtime stubbing library under tests/3rdparty/stub/,
    wrapped in namespace stub_ext to avoid ODR against the legacy
    tests/src/stub.h, plus an append-only wiring block in
    tests/CMakeLists.txt.
  • No production code, no scripts, no framework tooling.

Testing

  • All external dependencies (DeviceManager singleton, DBus, DSpinner,
    DetailTreeView parent chain) are stubbed; the suite runs offscreen with
    zero hardware dependency.
  • Rebased on upstream/master f4d271cb; the full test target builds and a
    filtered run of the touched suites passes 81/81 with exit code 0
    (76 new cases + 5 pre-existing matching ones).

Note for reviewers

ut_pageinfo.cpp TEST_P group 4 pins the current behavior of
PageInfo::packageHasInstalled (src/Page/PageInfo.cpp:80): the
contains("installed") substring match reports package 'x' is not installed as installed. The assertion documents today's behavior and must
be flipped together with the production fix.

@sourcery-ai

sourcery-ai Bot commented Oct 24, 2026

Copy link
Copy Markdown

Sorry @add-uos, your pull request is larger than the review limit of 150,000 diff characters

Rewrite the PageTableHeader test suite covering all 6 testable methods:
- constructor: two instances hold independent table widgets
- updateTable: 4-group TEST_P over row/limit/bios configurations
- setItem/clear/toString/isCurDeviceEnable: full branch coverage

Vendor the stub-ext runtime stubbing library under tests/3rdparty/stub
(wrapped in namespace stub_ext to avoid ODR against the legacy
tests/src/stub.h) and append its wiring to tests/CMakeLists.txt
(append-only, existing lines untouched).

12 cases; line coverage 100% (73/73); structural self-check passed
with 0 errors and 0 warnings.
Rewrite the PageInfo test suite. PageInfo is an abstract base class
(pure virtual updateInfo/clearWidgets/setLabel), so the pure-virtual
dispatch contract is exercised through a TestPageInfo derived class
with per-method invocation counters.

- constructor: initializes m_AllInfoNum/m_multiFlag
- packageHasInstalled: 4-group TEST_P over stubbed QProcess::readAll
  output; group 4 pins source defect DEF-DM-PAGE-001 where the
  contains("installed") substring match misreports
  'package x is not installed' as installed
- clearContent/paintEvent/isOverview/isBaseBoard and remaining
  members: full branch coverage

16 cases; line coverage 98.2% (56/57); structural self-check passed
with 0 errors and 0 warnings.
Rewrite the PageTableWidget test suite covering all 17 testable
methods. The inner DetailTreeView methods setLimitRow/
setCurDeviceState/expandCommandLinkClicked dereference an unchecked
parent chain, so they are stubbed with stub_ext to record forwarded
calls; everything else runs the real implementation.

- constructor/destructor: table and header wiring
- setColumnAndRow/setItem/clear/toString/isCurDeviceEnable:
  full branch coverage
- isOverview/isBaseBoard: forwarding verified through a TestPageInfo
  parent object

22 cases; line coverage 100% (70/70); structural self-check passed
with 0 errors and 0 warnings.
Rewrite the DeviceWidget test suite covering all 12 testable methods:
- constructor/destructor: child widgets, layout structure, QPointer
  guards verify child deletion
- clear/currentIndex/setFontChangeFlag/updateListView: forwarding
  contracts recorded via stub_ext
- updateDevice/updateOverview: empty-list and empty-map early return
  with zero side effects, plus non-empty forwarding
- resizeEvent: full branch matrix (getDeviceList failure falls back
  to the overview table, single device updates the device table,
  multi-device non-BIOS skips the update)

DeviceManager::instance is stubbed to return nullptr and
getDeviceTypes/getDeviceList/getDeviceOverview return static data,
so the suite has zero dependency on real hardware.

19 cases; line coverage 98.5% (130/132); structural self-check passed
with 0 errors and 0 warnings.
Rewrite the WaitingWidget test suite covering all 4 testable methods:
- constructor: spinner/label creation, fixed spinner size, nested
  [stretch, vbox, stretch] layout structure
- start/stop: DSpinner forwarding recorded via stub_ext instead of
  driving its internal animation timers
- destructor: QPointer guards verify both children are deleted

7 cases; line coverage 100% (47/47); structural self-check passed
with 0 errors and 0 warnings.
The license-check CI requires newly added files to carry a single
current-year SPDX copyright with no year range. Update the three
vendored stub-ext files from '2021 - 2023' to '2026' so the SPDX
Year Range Checker passes.

MIT license identifiers are kept; MIT.txt is present under LICENSES/.
DEF-DM-PAGE-001 has been fixed upstream by commit 4a8e526 (exact
match on the dpkg 'Status: install ok installed' line). Flip the
parametrized case that pinned the old buggy substring behavior from
true to false, so the suite now locks in the corrected semantics.

The rewrite supersedes the PackageHasInstalled_UT cases added to the
legacy ut_pageinfo.cpp by the same upstream fix: PageInfoPackageTest
covers the same output variants through the real function with a
stubbed QProcess.
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

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

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交为 5 个 Page 类的单元测试重写(76 个用例),测试覆盖全面、文档详尽、AAA 模式规范、桩管理安全。存在 1 处 reinterpret_cast 类型安全风险(UB),3rdparty 桩代码有少量资源泄漏与异常处理瑕疵,但不影响测试正确性与安全性。四维度均通过,无安全漏洞。

🔍 详细分析

1. 语法逻辑 ✅

评价: 无编译错误,逻辑合理 ✅ 通过

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

建议: ['将 ResizeEvent_MultiDeviceNonBios_SkipsUpdate 中的 nonBiosDummy 改为 DeviceBaseInfo 的真实派生类对象(如 DeviceBios 的兄弟类),或改用 nullptr 占位并调整断言,消除 UB 风险', '3rdparty addr_any.h 建议在函数返回路径添加 regfree(&pathname_regex) 释放正则资源']


2. 代码质量 ✅

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

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

建议: ['将重复的桩设置模式抽取为 fixture 辅助方法(如 setupSetCurDeviceStateStub),减少代码重复', '3rdparty 桩代码可考虑添加 RAII 包装管理 regcomp/regfree 生命周期']


3. 代码性能 ✅

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

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

建议: []


4. 代码安全 🔒

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

🔐 发现 0 个安全漏洞

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

建议: []


💡 改进建议代码示例

// 修复 ut_devicewidget.cpp ResizeEvent_MultiDeviceNonBios_SkipsUpdate 中的 UB:
// 方案:使用 nullptr 占位(桩不解除引用,dynamic_cast 对 nullptr 返回 nullptr 安全)
TEST_F(DeviceWidgetTest, ResizeEvent_MultiDeviceNonBios_SkipsUpdate)
{
    // Arrange:两台设备且首元素非 BIOS
    stub.set_lamda(&DeviceManager::getDeviceTypes,
                   []() -> const QList<QPair<QString, QString>> & {
                       static QList<QPair<QString, QString>> types{{"CPU", "cpu"}};
                       return types;
                   });
    // 修正:使用 nullptr 占位替代 reinterpret_cast,消除 UB
    stub.set_lamda(&DeviceManager::getDeviceList,
                   [](DeviceManager *, const QString &, QList<DeviceBaseInfo *> &lst) {
                       lst.clear();
                       lst.append(nullptr);  // dynamic_cast 对 nullptr 返回 nullptr,安全
                       lst.append(nullptr);
                       return true;
                   });
    int mapUpdates = 0;
    int listUpdates = 0;
    stub.set_lamda(static_cast<void (PageInfoWidget::*)(const QMap<QString, QString> &)>(&PageInfoWidget::updateTable),
                   [&](PageInfoWidget *, const QMap<QString, QString> &) { ++mapUpdates; });
    stub.set_lamda(static_cast<void (PageInfoWidget::*)(const QString &, const QList<DeviceBaseInfo *> &)>(&PageInfoWidget::updateTable),
                   [&](PageInfoWidget *, const QString &, const QList<DeviceBaseInfo *> &) { ++listUpdates; });
    QResizeEvent event(QSize(100, 100), QSize(80, 80));

    // Act
    obj->resizeEvent(&event);

    // Assert:非 BIOS 多设备跳过更新,零副作用
    EXPECT_EQ(listUpdates, 0);
    EXPECT_EQ(mapUpdates, 0);
}

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

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

@add-uos

add-uos commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot
deepin-bot Bot merged commit 7770b25 into linuxdeepin:master Oct 26, 2026
17 checks passed
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.

3 participants