feat(app-iced,pages): M100 取证密闭 + harness 参数拆分 + 设置页测试按 section 下放
四件前置事,都是为了设置页正文四条 section 线能并行(不写任何 section 正文):
1. 取证密闭(两条通道各有各的机制,证据分开算)
- 产品 bin:`cli::ForcedState` 加 `Rest`(静息态),给了 `--screenshot` 且没显式
`--force-state` 时默认 `Some(Rest)`;交互模式仍是 `None`(`shell::overridden`
与 `app/view.rs` 的 `model()` 各补一支)。
- harness:截图窗口开 `window::enable_mouse_passthrough`(winit 的
`set_cursor_hittest(false)`)⇒ 窗口收不到指针事件 ⇒ 全树控件恒为 Active。
为什么用通道级而不是逐控件灌 forced:设置页「外观」区的滑块/文本框/裸 button 都不消费
forced,逐控件做要改十几个组件文件,而新产品组件随时会漏。
- harness 同时数指针事件并打进日志(`指针事件=N`):让「这张图见过几个鼠标事件」变成
可读数字,替代「连跑几次 hash 一样」那种恒真的假绿。
2. harness 的外观真状态入口:`--appearance=real` 让设置页走 `appearance: Some(..)`
(工厂态 + `ULL_APPEARANCE_*`),新入口 `pages::app_with_appearance`。
`--screen=settings` 之前就有了,但 `appearance` 恒为 None,D30 要的那一屏根本不存在。
3. `pages/harness.rs` 400 行 → 拆 `pages/harness/request.rs`(`#[path]` 范式),
纯搬移部分 240 行 + 新增密闭代码。拆分等价性:同一 argv 的 PNG sha256 与拆分前一致。
4. `pages/settings/tests.rs` 按 section 下放成 `tests/{general,appearance,java,download}_section.rs`,
mod 层只留跨 section 断言(每条写清守什么、为什么不能下放)。
给某组加一条新断言 = 只改它自己那个文件。
顺带:`shell/mod.rs` 在 HEAD 就 399 行、`cli.rs` 394 行,两处都按同一范式把 tests 搬成
`shell/tests.rs` / `cli/tests.rs`(断言一字不动,逐字节可 diff)。
变异验证:把四处实现各改坏一处(默认 Rest、passthrough 默认值、overridden 的 Rest 分支、
view 的 Rest 映射),对应 4 条断言全红(390 passed / 4 failed),恢复后 394 passed。
This commit is contained in:
1 parent
2ad808d55c
commit
2061296615
16 files changed
+1152
-469
No files matched your search
@@ -309,6 +309,9 @@ pub(super) fn label<'a>(
|
||||
/// 取证用的状态覆盖(`--force-state`):只改画出来的状态,不动任何状态机。
|
||||
pub(super) fn overridden(forced: Option<ForcedState>, status: button::Status) -> button::Status {
|
||||
match forced {
|
||||
// `Rest` = 取证图的常态:**明确**画成 Active,把系统光标带来的 hover/pressed 压掉。
|
||||
// 截图通道默认就是它(见 `cli::Options::parse` 的尾部),否则同一份代码会因指针位置出不同的图。
|
||||
Some(ForcedState::Rest) => button::Status::Active,
|
||||
Some(ForcedState::Hover) => button::Status::Hovered,
|
||||
Some(ForcedState::Pressed) => button::Status::Pressed,
|
||||
None => status,
|
||||
@@ -323,77 +326,5 @@ pub(super) fn filled(color: Color) -> container::Style {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use unlucky_design::color::SchemeFlavor;
|
||||
use unlucky_design::component_map::Component;
|
||||
use unlucky_design::typography::Platform;
|
||||
|
||||
use crate::theme::Families;
|
||||
|
||||
fn ui(flavor: SchemeFlavor) -> Ui {
|
||||
Ui::with_platform(
|
||||
flavor,
|
||||
Platform::Windows,
|
||||
Families {
|
||||
text: "Segoe UI",
|
||||
display: "Segoe UI",
|
||||
mono: "Consolas",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_screen_only_uses_four_text_sizes_at_most() {
|
||||
let ui = ui(SchemeFlavor::Dark);
|
||||
let card = Component::OutlinedCard.spec();
|
||||
let sizes = [
|
||||
ui.emphasized(TypeRole::TitleLarge).size_px,
|
||||
ui.emphasized(TypeRole::LabelLarge).size_px,
|
||||
ui.emphasized(card.text).size_px,
|
||||
ui.style(card.support.unwrap_or(card.text)).size_px,
|
||||
ui.style(TypeRole::LabelMedium).size_px,
|
||||
];
|
||||
let mut unique = sizes.to_vec();
|
||||
unique.sort_by(f32::total_cmp);
|
||||
unique.dedup();
|
||||
assert!(
|
||||
unique.len() <= 4,
|
||||
"rubric D4:一屏字号档 ≤4(实际 {} 档 {unique:?})",
|
||||
unique.len()
|
||||
);
|
||||
assert!(unique[0] >= 12.0, "最小档不下 12px(caption ≥11)");
|
||||
assert!(unique[unique.len() - 1] <= 28.0, "列表页标题不得 >28px");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flavor_slug_is_stable_for_filenames() {
|
||||
assert_eq!(crate::shot::flavor_slug(&ui(SchemeFlavor::Light)), "light");
|
||||
assert_eq!(crate::shot::flavor_slug(&ui(SchemeFlavor::Dark)), "dark");
|
||||
}
|
||||
|
||||
/// M86:标题栏 caption 图标缩到 20 后,**容器一个数都没动**(46×48),图标也还在框里。
|
||||
#[test]
|
||||
fn caption_icon_shrinks_without_touching_the_container() {
|
||||
let ui = ui(SchemeFlavor::Light);
|
||||
let metrics = ui.metrics();
|
||||
let caption = icons::CAPTION_PX;
|
||||
assert_eq!(metrics.titlebar_button_width, 46.0, "容器宽不许跟着图标改");
|
||||
assert_eq!(metrics.titlebar_height, 48.0, "容器高不许跟着图标改");
|
||||
assert!(
|
||||
caption < metrics.titlebar_button_width,
|
||||
"图标 {caption} 必须小于按钮宽 {}",
|
||||
metrics.titlebar_button_width
|
||||
);
|
||||
assert!(
|
||||
caption < metrics.titlebar_height,
|
||||
"图标 {caption} 必须小于按钮高 {}",
|
||||
metrics.titlebar_height
|
||||
);
|
||||
// 官方口径 24 仍在令牌里(`IconSize::Toolbar`),偏离只发生在 caption 这一个入口。
|
||||
assert!(
|
||||
caption < unlucky_design::icons::IconSize::Toolbar.px(),
|
||||
"caption 图标必须小于官方 24(缩小是用户点名的)"
|
||||
);
|
||||
}
|
||||
}
|
||||
#[path = "tests.rs"]
|
||||
mod tests;
|
||||
Reference in new issue
Block a user