Skip to content

test(ut): add PMS regression unit tests for severity 1/2 bug hotspots - #628

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:test/pms-ut-regression-20260929
Sep 29, 2026
Merged

deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:test/pms-ut-regression-20260929

Conversation

@add-uos

@add-uos add-uos commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

概述 / Summary

补充 PMS 缺陷热点(severity 1/2)回归单元测试,共 88 个 GTest 用例,仅涉及 tests/ 目录,不改任何源码。

内容 / Contents

  • 批次 1(TOP30 热点函数):26 用例 —— test_window / test_ddropdownmenu / test_editwrapper / test_bottombar / test_dtextedit_misc / find / mark / fileloadthread
  • 批次 2(196 行强关联函数):59 用例 —— undo 命令组(insertblock/deleteback/deletetextundo)、editor_core(cursor/event/edit/find/mark/misc)、controls_ut(tabbar/findbar)、widgets、common/common2、startmanager、editwrapper
  • 批次 3(s1/s2 覆盖审计补齐):3 用例 —— BUG102351(Settings 后端生命周期/写盘保留)、BUG331945(updateMark 多标记移除索引正确性 + 列选区分支)
  • tests/.gitignore:忽略测试工作数据目录

说明 / Notes

  • 每个用例头部带 // PMS: 注释(bug-view 链接 + 修复 commit sha),便于回溯
  • 用例命名规范:TEST_F(<Fixture>, BUG<id>_<场景>),Arrange/Act/Assert 三段式
  • 约 115 行无修复提交(blocked)或纯 UI/主题/DPR 改动不做行为断言,已在内部工作单记录理由(不入库)

验证 / Verification

22 个测试 target 全量:1542/1542 PASS(含新增 88 用例),零回归
构建:Qt6 + Dtk6 + KF6(Debug + gcov -O0)
运行环境:QT_QPA_PLATFORM=offscreen

Summary by Sourcery

Expand unit-test coverage for PMS severity 1/2 regression hotspots without modifying production code.

Enhancements:

  • Add broad PMS regression coverage for severity 1/2 hotspots across settings, utilities, file loading, editor behavior, undo/redo, widgets, tab management, and window lifecycle scenarios.

Tests:

  • Add 88 GTest regression cases covering file operations, encoding, search and marking, selections, folding, drag-and-drop, resource cleanup, tab recovery, and window lifecycle behavior.
  • Verify the full test suite with 1,542 of 1,542 tests passing, including the new regression coverage.

Chores:

  • Add test-work-data paths to tests/.gitignore.

@sourcery-ai

sourcery-ai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Reviewer's Guide

This test-only PR adds 88 PMS-traceable GTest regressions for severity 1/2 hotspot behavior, emphasizing lifecycle safety, persistence, editor interactions, undo/redo, large-file/error paths, and UI state consistency; it also ignores generated test data and reports a full 22-target pass.

File-Level Changes

Change Details Files
Added PMS-linked regression coverage for high-severity bug hotspots across window, editor, undo, wrapper, widget, control, utility, settings, and file-loading behavior.
  • Added 88 GTest cases organized into three batches: TOP30 hotspots, strongly related functions, and audit-completion cases.
  • Covered lifecycle, persistence, encoding, tab recovery, drag/drop, find/mark, selection, folding, undo/redo, memory-safety, error handling, and UI state-machine scenarios.
  • Annotated tests with PMS links, fixing commit SHAs, and standardized BUG-prefixed fixture names with Arrange/Act/Assert structure.
tests/common/test_settings.cpp
tests/common/test_utils.cpp
tests/common2/test_fileloadthread.cpp
tests/common2/test_iflytekaiassistant.cpp
tests/common2/test_textfilesaver.cpp
tests/controls_ut/test_findbar.cpp
tests/controls_ut/test_tabbar.cpp
tests/editor_areas/test_flashtween.cpp
tests/editor_core/test_dtextedit_cursor.cpp
tests/editor_core/test_dtextedit_edit.cpp
tests/editor_core/test_dtextedit_event.cpp
tests/editor_core/test_dtextedit_find.cpp
tests/editor_core/test_dtextedit_mark.cpp
tests/editor_core/test_dtextedit_misc.cpp
tests/editor_undo/test_deletebackaltcommand.cpp
tests/editor_undo/test_deletebackcommand.cpp
tests/editor_undo/test_deletetextundocommand.cpp
tests/editor_undo/test_insertblockbytextcommand.cpp
tests/editor_wrapper/test_editwrapper.cpp
tests/startmanager/test_startmanager.cpp
tests/widgets_ut/test_bottombar.cpp
tests/widgets_ut/test_colorselectwdg.cpp
tests/widgets_ut/test_ddropdownmenu.cpp
tests/widgets_ut/test_window.cpp
Added test-workspace hygiene for generated test data.
  • Ignored test working-data directories under tests/.
tests/.gitignore
Validated the expanded unit-test suite in the documented offscreen Qt environment.
  • Ran all 22 test targets with 1542/1542 tests passing, including the 88 new cases.
  • Built with Qt6, Dtk6, and KF6 in Debug plus gcov -O0.

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

@github-actions

Copy link
Copy Markdown
  • 检测到敏感词unset变动
详情
    {
    "unset": {
        "tests/editor_core/test_dtextedit_misc.cpp": {
            "b": [
                "// \u573a\u666f\uff1a\u5207\u6362\u6df1\u6d45\u4e3b\u9898\u6587\u5b57\u989c\u8272\uff0865bc75a3\uff09\u5173\u8054\u884c\uff1apasteText \u539f\u751f\u7c98\u8d34\u540e unsetMark\uff0c",
                "    // Assert: \u526a\u8d34\u677f\u5185\u5bb9\u63d2\u5165\u3001\u6807\u8bb0\u590d\u4f4d\uff08pasteText \u672b\u5c3e unsetMark\uff09"
            ]
        }
    }
}

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="tests/editor_core/test_dtextedit_cursor.cpp" line_range="898-905" />
<code_context>
+    ASSERT_GT(bar->maximum(), 0);
+    bar->setValue(bar->maximum() / 2);
+
+    // Act: 大文本滚动状态下获取首可见块
+    const int blockId = edit->getFirstVisibleBlockId();
+    const QTextBlock block = edit->firstVisibleBlock();
+
+    // Assert: 返回合法且非首块的可见块(视图已滚动),firstVisibleBlock 同步
+    ASSERT_TRUE(block.isValid());
+    EXPECT_GT(blockId, 0);
+    EXPECT_GT(block.blockNumber(), 0);
+
+    // Act: jumpToLine 跳转中部行(keepLineAtCenter=false)
</code_context>
<issue_to_address>
**issue (testing):** The test expects `getFirstVisibleBlockId()` and `firstVisibleBlock()` to report a nonzero block after scrolling, but the current implementation calculates the scroll position with integer division (`height() / maximum()` or `value() / maximum()`), producing a zero-point for the midpoint in the tested range; the assertions therefore fail instead of providing a passing regression test.

**Triggers:** When the vertical scrollbar maximum is greater than one and the document is scrolled to `maximum() / 2`.

**Suggested fix:** Either fix the production calculation to use floating-point division, or change this test to assert the behavior currently intended by the implementation and separately add a regression for the integer-division defect.
</issue_to_address>

### Comment 2
<location path="tests/common2/test_fileloadthread.cpp" line_range="456-460" />
<code_context>
+        EXPECT_TRUE(spy.at(0).at(2).toBool());
+        EXPECT_FALSE(spy.at(0).at(3).toBool());
+    }
+    // 当前代码:catch 分支提前 return(:88),deleteLater 仅在正常路径末尾(:132)注册,
+    // 故此处 guard 未清空属预期;手动补 deleteLater 防泄漏后断言回收
+    t->deleteLater();
+    QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+    EXPECT_TRUE(guard.isNull());
+}
</code_context>
<issue_to_address>
**issue (testing):** The test manually calls `deleteLater()` after the `bad_alloc` path and then asserts destruction, so it masks the production lifecycle behavior: a regression where `run()` emits the error and returns without scheduling cleanup still passes because the test supplies the missing cleanup itself.

**Triggers:** When `FileLoadThread::run()` catches the read allocation failure and returns before its normal-path cleanup.

**Suggested fix:** Assert that the error path itself schedules or performs object cleanup, or use the same ownership mechanism as production and verify the object is destroyed without calling `deleteLater()` from the test.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment on lines +898 to +905
// Act: 大文本滚动状态下获取首可见块
const int blockId = edit->getFirstVisibleBlockId();
const QTextBlock block = edit->firstVisibleBlock();

// Assert: 返回合法且非首块的可见块(视图已滚动),firstVisibleBlock 同步
ASSERT_TRUE(block.isValid());
EXPECT_GT(blockId, 0);
EXPECT_GT(block.blockNumber(), 0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (testing): The test expects getFirstVisibleBlockId() and firstVisibleBlock() to report a nonzero block after scrolling, but the current implementation calculates the scroll position with integer division (height() / maximum() or value() / maximum()), producing a zero-point for the midpoint in the tested range; the assertions therefore fail instead of providing a passing regression test.

Triggers: When the vertical scrollbar maximum is greater than one and the document is scrolled to maximum() / 2.

Suggested fix: Either fix the production calculation to use floating-point division, or change this test to assert the behavior currently intended by the implementation and separately add a regression for the integer-division defect.

Comment on lines +456 to +460
// 当前代码:catch 分支提前 return(:88),deleteLater 仅在正常路径末尾(:132)注册,
// 故此处 guard 未清空属预期;手动补 deleteLater 防泄漏后断言回收
t->deleteLater();
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
EXPECT_TRUE(guard.isNull());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (testing): The test manually calls deleteLater() after the bad_alloc path and then asserts destruction, so it masks the production lifecycle behavior: a regression where run() emits the error and returns without scheduling cleanup still passes because the test supplies the missing cleanup itself.

Triggers: When FileLoadThread::run() catches the read allocation failure and returns before its normal-path cleanup.

Suggested fix: Assert that the error path itself schedules or performs object cleanup, or use the same ownership mechanism as production and verify the object is destroyed without calling deleteLater() from the test.

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

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

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交为纯测试代码变更,新增88个GTest回归用例覆盖PMS缺陷热点。代码结构清晰、注释完整、无安全漏洞。仅存在1处轻微代码质量问题(reinterpret_cast用法),不影响测试正确性。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

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

建议: []


2. 代码质量 ✅

评价: 优秀 ✅ 通过

潜在问题:

  1. tests/editor_undo/test_insertblockbytextcommand.cpp:1732 - 使用 reinterpret_cast<EditWrapper *>(&wrapperHost) 将 QWidget 强转为 EditWrapper 指针,存在类型安全隐患。若 EditWrapper 不继承自 QWidget 或内存布局不一致,属于未定义行为。测试代码中此模式可接受但建议使用更安全的替代方案。

建议: ['建议在 test_insertblockbytextcommand.cpp 中使用 EditWrapper 的真实构造或 Mock 对象替代 reinterpret_cast,避免潜在的未定义行为。']


3. 代码性能 ✅

评价: 优秀 ✅ 通过

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

建议: []


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

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

建议: []


💡 改进建议代码示例

// 暂无代码示例

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

lzwind
lzwind previously approved these changes Sep 29, 2026
Add 88 GTest regression cases for PMS defect hotspots across editor
core/wrapper/undo/widgets/settings/common modules, with work order
and defect analysis under tests/.ut-pms/ (not committed).

新增88个GTest回归用例,覆盖编辑器核心、撤销命令、控件、设置、
公共模块的PMS缺陷热点;用例工作单与缺陷分析存于tests/.ut-pms/。

Log: 补充PMS缺陷热点回归单元测试
Influence: 仅测试文件变更,不影响应用功能;bug 回归用例覆盖提升。
@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

1 similar comment
@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

@github-actions

Copy link
Copy Markdown
  • 检测到敏感词unset变动
详情
    {
    "unset": {
        "tests/editor_core/test_dtextedit_misc.cpp": {
            "b": [
                "// \u573a\u666f\uff1a\u5207\u6362\u6df1\u6d45\u4e3b\u9898\u6587\u5b57\u989c\u8272\uff0865bc75a3\uff09\u5173\u8054\u884c\uff1apasteText \u539f\u751f\u7c98\u8d34\u540e unsetMark\uff0c",
                "    // Assert: \u526a\u8d34\u677f\u5185\u5bb9\u63d2\u5165\u3001\u6807\u8bb0\u590d\u4f4d\uff08pasteText \u672b\u5c3e unsetMark\uff09"
            ]
        }
    }
}

@add-uos

add-uos commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

This pr force merged! (status: blocked)

@deepin-bot
deepin-bot Bot merged commit cc757f0 into linuxdeepin:master Sep 29, 2026
16 of 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