fix(app-iced): 复审 p2 五条(方向取轨序 / 退场重开 / 遮罩口径 / 恒真断言 / 探针隔离)
- P2-1 方向改由**导航轨序**决定:新增 nav_rank(route)(NavItem::ALL 下标), Pump::observe 收 (screen, rank, detail),forward 比较 (rank, key) 而非只比屏键 —— 修掉 Logs↔Settings 的左右镜像;Download↔Content 同 rank,仍判同级水平(已登记偏离)。 - P2-2 退场途中开新框:observe_modal 先当场收尾(Hidden + 待关)再起 Opening; sync_motion 收尾时若队列里还有框就不把 dialog_model 置空。 - P2-3 只改文字:遮罩起手是**整块画布色的不透明矩形**(把页面内容遮住),不是透明看不见。 - P2-4 删掉恒真断言(单个 Option 的 <=1),写明「不累积」是字段形状 + mem::replace 给的; tests/timeline.rs 与 tests/modal.rs 的每条用例都补了「抓不住」。 - P2-5 新增 motion::configure_for_test(绕过 OS 探针),用例一律走它; 另留一条故意走真探针的用例证明 Reduced ⇒ NONE 的合成仍在产品入口上。 - 顺带:pump 的模态状态机拆到 pump/modal.rs(守 400 行硬线)。
This commit is contained in:
1 parent
4a77f1b421
commit
1edf645c2f
9 files changed
+446
-274
No files matched your search
@@ -119,7 +119,7 @@ fn every_transition_is_built_from_registered_tokens() {
|
||||
#[test]
|
||||
fn a_page_enters_over_twelve_to_twenty_frames_and_lands_on_the_endpoint() {
|
||||
let mut pump = standard();
|
||||
assert!(pump.observe(Some(2), None), "首次观察要起跑 Boot");
|
||||
assert!(pump.observe(Some(2), Some(1), None), "首次观察要起跑 Boot");
|
||||
let frames = settle(&mut pump);
|
||||
assert!(
|
||||
(12..=20).contains(&frames),
|
||||
@@ -127,7 +127,7 @@ fn a_page_enters_over_twelve_to_twenty_frames_and_lands_on_the_endpoint() {
|
||||
);
|
||||
|
||||
// 重跑一次,逐帧看端点与单调性
|
||||
pump.observe(Some(3), None); // 同级换页:medium2 = 300ms
|
||||
pump.observe(Some(3), Some(1), None); // 同级换页:medium2 = 300ms
|
||||
let trace = samples(&mut pump);
|
||||
assert!(trace.len() >= 12, "中间态太少:{}", trace.len());
|
||||
assert_eq!(
|
||||
@@ -163,10 +163,10 @@ fn a_page_enters_over_twelve_to_twenty_frames_and_lands_on_the_endpoint() {
|
||||
#[test]
|
||||
fn the_old_page_moves_the_other_way_and_leaves_first() {
|
||||
let mut pump = standard();
|
||||
pump.observe(Some(2), None);
|
||||
pump.observe(Some(2), Some(1), None);
|
||||
settle(&mut pump);
|
||||
|
||||
assert!(pump.observe(Some(3), None));
|
||||
assert!(pump.observe(Some(3), Some(1), None));
|
||||
let first = pump.page_frame();
|
||||
assert_eq!(first.enter, (12.0, 0.0));
|
||||
assert_eq!(first.exit, (0.0, 0.0), "退场起点是 0");
|
||||
@@ -201,23 +201,23 @@ fn the_old_page_moves_the_other_way_and_leaves_first() {
|
||||
#[test]
|
||||
fn direction_follows_navigation_depth() {
|
||||
let mut pump = standard();
|
||||
pump.observe(Some(1), None);
|
||||
pump.observe(Some(1), Some(0), None);
|
||||
settle(&mut pump);
|
||||
|
||||
// 向右推进(屏键 1 → 3)
|
||||
pump.observe(Some(3), None);
|
||||
pump.observe(Some(3), Some(1), None);
|
||||
assert_eq!(pump.kind(), Some(Kind::Peer { forward: true }));
|
||||
assert_eq!(pump.page_frame().enter, (12.0, 0.0), "同级往右 = 水平位移");
|
||||
settle(&mut pump);
|
||||
|
||||
// 向左退回(3 → 1)
|
||||
pump.observe(Some(1), None);
|
||||
pump.observe(Some(1), Some(0), None);
|
||||
assert_eq!(pump.kind(), Some(Kind::Peer { forward: false }));
|
||||
assert_eq!(pump.page_frame().enter, (-12.0, 0.0), "同级往左 = 镜像");
|
||||
settle(&mut pump);
|
||||
|
||||
// 进深层(同屏:列表 → 详情)
|
||||
pump.observe(Some(1), Some("instance-7"));
|
||||
pump.observe(Some(1), Some(0), Some("instance-7"));
|
||||
assert_eq!(pump.kind(), Some(Kind::Push));
|
||||
let push = pump.page_frame();
|
||||
assert_eq!(push.enter, (0.0, 16.0), "进深层 = 纵向(从下方上浮)");
|
||||
@@ -225,11 +225,42 @@ fn direction_follows_navigation_depth() {
|
||||
settle(&mut pump);
|
||||
|
||||
// 出深层(详情 → 列表)
|
||||
pump.observe(Some(1), None);
|
||||
pump.observe(Some(1), Some(0), None);
|
||||
assert_eq!(pump.kind(), Some(Kind::Pop));
|
||||
assert_eq!(pump.page_frame().enter, (0.0, -16.0), "出深层必须镜像");
|
||||
}
|
||||
|
||||
/// **左右方向看导航轨序,不看屏键**(复审 P2-1 的守卫)。
|
||||
///
|
||||
/// 两处顺序不同:`Screen::ALL` 是 `… Content / Settings / Logs`,导航轨是 `… Logs / Settings / Ai`。
|
||||
/// 用屏键判方向会让 **Logs↔Settings 镜像**。
|
||||
///
|
||||
/// 抓得住:把 `Pump::observe` 的方向改回「比较屏键」(`new > old`)——本用例里
|
||||
/// Settings(键 4 / **序 3**) → Logs(键 5 / **序 2**) 会被判成向右推进,第一条断言立即红。
|
||||
/// 也抓得住「谁调了 `Screen::ALL` 的顺序」:这里**只引用轨序**,与那张表的声明顺序解耦。
|
||||
/// 抓不住:导航轨本身的视觉位置(那是 `shell/nav.rs` 的几何,归它的守卫)。
|
||||
#[test]
|
||||
fn direction_comes_from_the_nav_rail_not_the_screen_table() {
|
||||
let mut pump = standard();
|
||||
pump.observe(Some(4), Some(3), None); // Settings:屏键 4、轨序 3
|
||||
settle(&mut pump);
|
||||
|
||||
// 轨序 3 → 2(向左)。若按屏键 4 → 5,会被判成向右 —— 那正是被修的 bug。
|
||||
pump.observe(Some(5), Some(2), None);
|
||||
assert_eq!(
|
||||
pump.kind(),
|
||||
Some(Kind::Peer { forward: false }),
|
||||
"Settings → Logs 在导航轨上是向左"
|
||||
);
|
||||
assert_eq!(pump.page_frame().enter, (-12.0, 0.0));
|
||||
settle(&mut pump);
|
||||
|
||||
// 反向:轨序 2 → 3 = 向右
|
||||
pump.observe(Some(4), Some(3), None);
|
||||
assert_eq!(pump.kind(), Some(Kind::Peer { forward: true }));
|
||||
assert_eq!(pump.page_frame().enter, (12.0, 0.0));
|
||||
}
|
||||
|
||||
/// **`MotionScale::NONE` 下位移与缩放严格为 0**(不是"很小")。
|
||||
///
|
||||
/// 抓得住:把 `play_page` 的 `is_off()` 分支删掉(变成跑一遍 0 时长动画)——那时 `frame()`
|
||||
@@ -241,13 +272,13 @@ fn none_scale_is_strictly_zero_not_merely_small() {
|
||||
assert!(pump.scale().is_off());
|
||||
|
||||
// 首屏 / 换页 / 进退层:三次状态变化都不许留下轨道,位移必须 `== 0.0`(不是 `abs() < eps`)
|
||||
for (screen, detail) in [
|
||||
(Some(1), None),
|
||||
(Some(2), None),
|
||||
(Some(2), Some("instance-7")),
|
||||
(Some(2), None),
|
||||
for (screen, rank, detail) in [
|
||||
(Some(1), Some(0), None),
|
||||
(Some(2), Some(1), None),
|
||||
(Some(2), Some(1), Some("instance-7")),
|
||||
(Some(2), Some(1), None),
|
||||
] {
|
||||
assert!(!pump.observe(screen, detail), "关掉动效时不许起跑");
|
||||
assert!(!pump.observe(screen, rank, detail), "关掉动效时不许起跑");
|
||||
let frame = pump.page_frame();
|
||||
assert_eq!(frame.enter.0, 0.0);
|
||||
assert_eq!(frame.enter.1, 0.0);
|
||||
@@ -282,11 +313,11 @@ fn none_scale_is_strictly_zero_not_merely_small() {
|
||||
#[test]
|
||||
fn repeated_paints_never_restart_the_animation() {
|
||||
let mut pump = standard();
|
||||
pump.observe(Some(3), Some("instance-9"));
|
||||
pump.observe(Some(3), Some(1), Some("instance-9"));
|
||||
settle(&mut pump);
|
||||
|
||||
for _ in 0..30 {
|
||||
assert!(!pump.observe(Some(3), Some("instance-9")));
|
||||
assert!(!pump.observe(Some(3), Some(1), Some("instance-9")));
|
||||
assert_eq!(pump.page_frame(), PageFrame::STILL);
|
||||
}
|
||||
assert!(!pump.is_animating());
|
||||
@@ -296,13 +327,19 @@ fn repeated_paints_never_restart_the_animation() {
|
||||
#[test]
|
||||
fn screens_rendered_elsewhere_never_start_a_track() {
|
||||
let mut pump = standard();
|
||||
pump.observe(Some(1), None);
|
||||
pump.observe(Some(1), Some(0), None);
|
||||
settle(&mut pump);
|
||||
|
||||
assert!(!pump.observe(None, None), "没有 pages 树可动 ⇒ 不许白开帧");
|
||||
assert!(
|
||||
!pump.observe(None, None, None),
|
||||
"没有 pages 树可动 ⇒ 不许白开帧"
|
||||
);
|
||||
assert!(!pump.is_animating());
|
||||
|
||||
assert!(pump.observe(Some(1), None), "从账户页回来仍然是换页");
|
||||
assert!(
|
||||
pump.observe(Some(1), Some(0), None),
|
||||
"从账户页回来仍然是换页"
|
||||
);
|
||||
assert_eq!(pump.kind(), Some(Kind::Boot), "没有旧页可退 ⇒ 按首屏方向");
|
||||
}
|
||||
|
||||
@@ -314,10 +351,10 @@ fn screens_rendered_elsewhere_never_start_a_track() {
|
||||
#[test]
|
||||
fn a_second_navigation_mid_flight_takes_over_cleanly() {
|
||||
let mut pump = standard();
|
||||
pump.observe(Some(1), None);
|
||||
pump.observe(Some(1), Some(0), None);
|
||||
settle(&mut pump);
|
||||
|
||||
pump.observe(Some(2), None); // 往右推进
|
||||
pump.observe(Some(2), Some(1), None); // 往右推进
|
||||
for _ in 0..4 {
|
||||
pump.advance(FRAME_MS); // 走 3~5 帧就再点一次
|
||||
}
|
||||
@@ -327,7 +364,7 @@ fn a_second_navigation_mid_flight_takes_over_cleanly() {
|
||||
"第一次过渡还在半路"
|
||||
);
|
||||
|
||||
pump.observe(Some(1), None); // 立刻退回左边
|
||||
pump.observe(Some(1), Some(0), None); // 立刻退回左边
|
||||
let restarted = pump.page_frame();
|
||||
assert_eq!(restarted.enter, (-12.0, 0.0), "新方向立刻生效(满幅起点)");
|
||||
assert_eq!(
|
||||
|
||||
Reference in new issue
Block a user