fix(app-iced): 动效全局态按「测试隔离」修 —— 串行门 + 探针旁路(复审 P2-5 返工)

tip 8b6f090 上 7 条用例在 -j 2 下红,根因两层:
1) P2-5 引入的 configure_for_test 只挡调用点,而 App::update(Boot) 会走**产品** configure
   再按真探针定档 —— 本机(RDP 会话)SPI_GETCLIENTAREAANIMATION 报「动画关」⇒ 档位被压成
   NONE ⇒ 位移恒 0 ⇒ 门槛 B/C 的守卫全红(日志里 [motion] scale=0.00 就是它)。
2) 动效全局态(档位 + 进程级时间轴)在并行用例间共享,谁先写谁赢。

修法(判据一条没动):
- components :: motion :: serialize():**跨模块共用的唯一一把**串行门,subscription.rs 与
  update/motion_sync.rs 的用例都取它(idle_app 把 guard 一起返回,活到用例结束)。
- configure_for_test 置 thread-local BYPASS_PROBE,configure 读它 ⇒ 产品启动路径也不会再按
  探针改档;reset() 清旁路,供「故意走真探针」那条用例使用。
- NONE 仍要求严格 0、STANDARD 仍要求 12~20 帧与端点归位。
This commit is contained in:
AskaEth committed 2026-11-12 10:50:03 +08:00
1 parent 1edf645c2f
commit c21c6df51b
3 files changed
+55 -29

No files matched your search

@@ -211,7 +211,9 @@ mod tests {
///
/// **定档走 `configure_for_test`(复审 P2-5)**:产品入口 `configure` 会读宿主机「减少动效」
/// 开关,用例在关了系统动画的机器上就会红。真探针的接线由 `motion::tests::modal` 里那条用例守。
fn idle_app() -> App {
fn idle_app() -> (App, std::sync::MutexGuard<'static, ()>) {
// **串行门**(复审 P2-5 第二半):动效全局态由本用例独占,别与并行用例互踩。
let gate = motion::serialize();
motion::reset();
motion::configure_for_test(MotionScale::STANDARD, None);
let mut app = headless();
@@ -222,7 +224,7 @@ mod tests {
// 再走一条消息:`sync_motion` 在那一拍把启动期换页留下的 `previous_view` 烧掉。
let _ = app.update(Message::Frame);
assert!(!motion::needs_frames(), "前提:首屏动效已经跑完");
app
(app, gate)
}
/// 屏键 / 轨序两张表:**方向只听轨序**(复审 P2-1 的守卫)。
@@ -276,7 +278,7 @@ mod tests {
/// 旧版 `usize::from(is_some()) <= 1` 恒真。真要证明释放得靠析构计数插桩——**没做**。
#[test]
fn the_previous_page_model_is_dropped_and_never_accumulates() {
let mut app = idle_app();
let (mut app, _gate) = idle_app();
assert!(app.previous_view.is_none(), "前提:静息态没有旧页");
let _ = app.update(Message::Page(pages::Message::Navigate(Route::Download)));
@@ -308,7 +310,7 @@ mod tests {
/// 画面上两个页面同时在动内容。抓不住:`States`(外观/组状态/设置快照)不随模型冻结(偏离 #4)。
#[test]
fn the_previous_page_is_a_frozen_snapshot() {
let mut app = idle_app();
let (mut app, _gate) = idle_app();
let _ = app.update(Message::Page(pages::Message::Navigate(Route::Download)));
let before = app
.previous_view
@@ -339,7 +341,7 @@ mod tests {
use crate::app::update::dialog::{escape, on_dialog};
use unlucky_presenter::dialogs::{DialogKind, DialogSource};
let mut app = idle_app();
let (mut app, _gate) = idle_app();
let _ = app.state.dialogs.push(
DialogSource::UserAction,
"删除世界",