fix(m195): 复审 r1 三项 —— 解压检查点真守卫、presenter 接线测试、取消文案改回真话

P2-1(解压循环检查点没有真守卫):那条用例原来的断言(status/target/files/bytes/无残留暂存)
在删掉 `extract_overrides` 的检查点后**依然成立**——提交前检查点⑤会替它停一次,于是几 GB 的包
会一直解到结束而测试全绿。改成数 `ImportStage::Extract` 事件:有检查点 = 1 条、删掉 = 3 条
(两面实测)。模块文档同时如实登记"还没有真守卫"的检查点:②③④⑤、全新导入 commit 的取消
分支、phase.rs 远端下载逐条、complete.rs 补全循环的 break。

P2-2(presenter 的真令牌接线零测试):新增 `pack/tests/cancel.rs`,直接调 `import::run` 并把
传入的 `Arc<AtomicBool>` **预先置 true**,判据只能是盘上事实(目标目录不存在 + profiles.json
零实例)——"没收到 Report"那种判据两条路都成立,`run` 早退条件里的 `cancel.load()` 会把
"没接线"完全遮住。

P2-3(用户可见文案说反了话):`PackCancelled` 中英双语从「导入会在后台继续跑完 / Import keeps
running in the background…已经写下的文件会留下」改为「导入已取消 —— 后台已停手并回滚:没有留下
半包,也没有覆盖已有文件」;golden 金表同步;`model/tests.rs` 那条把旧文案钉死的用例改成钉新
语义(必须说清停手+回滚,且**禁止**出现 background);`model.rs` 的 `cancelled` 字段文档与
`dispatch.rs` 的取消注释同族修正。

验证:`cargo test -p unlucky-core -p unlucky-presenter` 1480 passed / 0 failed;
i18n 31 / 0;app-iced packui 28 / 0;三 crate clippy 零 warning。
This commit is contained in:
AskaEth committed 2026-11-09 05:06:53 +08:00
1 parent 1441a240fe
commit db5b08b9ab
9 files changed
+133 -29

No files matched your search

@@ -196,8 +196,9 @@ pub struct Pack {
pub running: Option<Running>,
/// 探测失败诊断
pub probe: Option<Probe>,
/// 用户取消过这次导入:面板收回但**后台还在跑**(core 没有取消令牌),
/// 所以要把这句话留在界面上,别让用户以为「没建成」(复审 r1 P1-2)。
/// 用户取消过这次导入:面板收回,**后台也真的停手并回滚了**(M195 起 core 有取消令牌:
/// 暂存目录删掉、落盘过的撤回、实例不登记)。这句话仍要留在界面上——取消不是"什么都没
/// 发生",而是"按你的意思停下来了",别让用户以为点空了。
pub cancelled: bool,
/// 取消提示的正文
pub cancelled_note: &'static str,
@@ -382,19 +382,17 @@ fn overwrite_is_offered_only_when_importing_into_an_existing_instance() {
}
#[test]
fn cancelled_state_is_visible_and_says_the_import_keeps_running() {
// 复审 r1 P1-2:面板收回之后,界面上必须留一句「后台还在跑」
fn cancelled_state_is_visible_and_says_the_import_stopped() {
// M195:取消是管线级的(core 停手并回滚),旧文案「后台还在跑」已是假话。
let import = unlucky_presenter::dto::ImportState {
cancelled: true,
..unlucky_presenter::dto::ImportState::default()
};
let export = unlucky_presenter::dto::ExportState::default();
let model = Pack::of(&import, &export, &PackPageState::default(), &[], catalog());
assert!(model.cancelled);
assert!(
model.cancelled_note.to_lowercase().contains("background"),
"取消提示必须说清后台还在跑:{}",
model.cancelled_note
);
assert!(!model.is_idle(), "取消态不能被当成「什么都没有」");
let note = model.cancelled_note.to_lowercase();
let stopped = note.contains("stopped") && note.contains("rolled back");
assert!(model.cancelled && !model.is_idle(), "取消态不能当成空闲");
assert!(stopped, "文案要说清停手并回滚");
assert!(!note.contains("background"), "文案不许说后台跑");
}