CI / runtime smoke (macos arm64, probe) (push) Skipped
CI / fmt (rustfmt --check) (push) Canceled after 0s
CI / clippy (ubuntu-latest) (push) Canceled after 0s
CI / clippy (windows-latest) (push) Canceled after 0s
CI / test (ubuntu-latest) (push) Canceled after 0s
CI / test (windows-latest) (push) Canceled after 0s
CI / build release (ubuntu-latest) (push) Canceled after 0s
CI / build release (windows-latest) (push) Canceled after 0s
CI / runtime smoke (ubuntu x64, xvfb) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / presenter 零 UI 守门 (push) Canceled after 0s
Guards / design 零第三方依赖守门 (push) Canceled after 0s
Guards / unsafe 落点守门(集合必须恰好一个文件) (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
首个 iced + Material 3 Expressive 版本的源码快照。 完整历史与日常提交在 dev 分支;main 只放阶段性快照。
173 lines
5.9 KiB
Rust
173 lines
5.9 KiB
Rust
//! `cli::Options` 的解析断言(M100 从 `cli.rs` 内联的 `mod tests` 搬出来:那边 394 行,
|
||
//! 加一个 `ForcedState::Rest` 就必然破 400)。
|
||
//!
|
||
//! 搬移**不改一行断言**:只去掉了 `mod tests { }` 那一层缩进,外加 M100 新增的
|
||
//! `screenshots_default_to_the_rest_state`(见文件末尾)。
|
||
//!
|
||
//! 站位:本文件是 `crate::cli::tests`,`use super::*;` 就够(`Options` / `ForcedState` /
|
||
//! `Backend` / `Screen` 都在 `cli` 里)。
|
||
use super::*;
|
||
|
||
fn parse(args: &[&str]) -> Result<Options, String> {
|
||
Options::parse(args.iter().map(|arg| (*arg).to_owned()))
|
||
}
|
||
|
||
#[test]
|
||
fn defaults_are_auto_system_theme_and_shell() {
|
||
let options = parse(&[]).expect("空参数要能解析");
|
||
assert_eq!(options.backend, Backend::Auto);
|
||
assert_eq!((options.theme, options.screenshot), (None, None));
|
||
assert_eq!(options.screen, Screen::Shell);
|
||
}
|
||
|
||
#[test]
|
||
fn software_renderer_is_an_alias_of_cpu() {
|
||
assert_eq!(
|
||
parse(&["--software-renderer"]).unwrap().backend,
|
||
Backend::Cpu
|
||
);
|
||
assert_eq!(parse(&["--renderer=cpu"]).unwrap().backend, Backend::Cpu);
|
||
assert_eq!(parse(&["--renderer", "gpu"]).unwrap().backend, Backend::Gpu);
|
||
}
|
||
|
||
#[test]
|
||
fn both_argv_forms_are_accepted() {
|
||
let spaced = parse(&["--screenshot", "out.png"]).unwrap();
|
||
let inline = parse(&["--screenshot=out.png"]).unwrap();
|
||
assert_eq!(spaced.screenshot, Some(PathBuf::from("out.png")));
|
||
assert_eq!(spaced.screenshot, inline.screenshot);
|
||
assert_eq!(
|
||
parse(&["--diff", "a.png", "b.png"]).unwrap().diff,
|
||
Some((PathBuf::from("a.png"), PathBuf::from("b.png")))
|
||
);
|
||
assert_eq!(
|
||
parse(&["--screen", "gallery"]).unwrap().screen,
|
||
Screen::Gallery
|
||
);
|
||
assert_eq!(parse(&["--diff-scan=2"]).unwrap().diff_scan, 2);
|
||
assert_eq!(
|
||
parse(&["--force-state", "hover"]).unwrap().force_state,
|
||
Some(ForcedState::Hover)
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn screenshot_theme_wins_over_theme() {
|
||
let o = parse(&["--theme=dark", "--screenshot-theme=light"]).unwrap();
|
||
assert_eq!(
|
||
(o.theme, o.shot_flavor()),
|
||
(Some(SchemeFlavor::Dark), Some(SchemeFlavor::Light))
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn bad_values_are_reported_not_panicked() {
|
||
for args in [
|
||
&["--renderer=metal"][..],
|
||
&["--theme=blue"],
|
||
&["--scale-factor=0"],
|
||
&["--scale-factor=abc"],
|
||
&["--screenshot"],
|
||
&["--diff", "only-one.png"],
|
||
&["--screen=settings"],
|
||
&["--force-state=focus"],
|
||
&["--diff-scan=-1"],
|
||
&["--nope"],
|
||
] {
|
||
assert!(parse(args).is_err(), "{args:?} 应该报错");
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn data_dir_is_accepted_and_ignored_for_the_flip() {
|
||
// 现役 CI 冒烟:--software-renderer --screenshot <png> --data-dir <dir>
|
||
let options = parse(&[
|
||
"--software-renderer",
|
||
"--screenshot",
|
||
"shot.png",
|
||
"--data-dir",
|
||
"/d/tmp/x",
|
||
])
|
||
.expect("翻牌前必须兼容 --data-dir");
|
||
assert_eq!(options.backend, Backend::Cpu);
|
||
assert_eq!(options.screenshot, Some(PathBuf::from("shot.png")));
|
||
assert_eq!(options.data_dir, Some(PathBuf::from("/d/tmp/x")));
|
||
}
|
||
|
||
/// **取证不变量(M100)**:截图通道默认 Rest,交互模式保持 `None`,显式要态仍然优先。
|
||
///
|
||
/// 抓得住:① 谁把截图默认值改回 `None`(系统指针 hover 会重新漏进图,M99 复审实测翻盘过一次);
|
||
/// ② 谁顺手在交互模式也钉死状态(那会让真窗口永远看不到 hover)。
|
||
/// 抓不住:**产品页**上是否还有不消费 forced 的控件——那要出图比对,测试管不了。
|
||
#[test]
|
||
fn screenshots_default_to_the_rest_state() {
|
||
assert_eq!(
|
||
parse(&["--force-state=rest"]).unwrap().force_state,
|
||
Some(ForcedState::Rest),
|
||
"rest 是显式的合法取值"
|
||
);
|
||
assert_eq!(
|
||
parse(&["--screenshot", "out.png"]).unwrap().force_state,
|
||
Some(ForcedState::Rest),
|
||
"截图通道必须默认 Rest"
|
||
);
|
||
assert_eq!(
|
||
parse(&["--screenshot", "o.png", "--force-state=hover"])
|
||
.unwrap()
|
||
.force_state,
|
||
Some(ForcedState::Hover),
|
||
"显式要态时按用户给的画(状态矩阵图靠它)"
|
||
);
|
||
assert_eq!(
|
||
parse(&["--screenshot", "o.png", "--force-state=pressed"])
|
||
.unwrap()
|
||
.force_state,
|
||
Some(ForcedState::Pressed)
|
||
);
|
||
assert_eq!(
|
||
parse(&[]).unwrap().force_state,
|
||
None,
|
||
"交互模式不许替用户钉死状态"
|
||
);
|
||
assert_eq!(parse(&["--theme=dark"]).unwrap().force_state, None);
|
||
}
|
||
|
||
/// **门禁依赖**:CI 的 runtime-smoke 不带主题,截图模式必须有确定主题。
|
||
/// 退化成 `None` 的话,xvfb 里的 runner 会挂到超时(不是红,更难查)。
|
||
#[test]
|
||
fn screenshot_without_theme_defaults_to_light() {
|
||
let options = parse(&["--screenshot", "out.png"]).unwrap();
|
||
assert_eq!(options.shot_flavor(), None, "用户没给主题");
|
||
assert_eq!(
|
||
options.capture_flavor(),
|
||
Some(SchemeFlavor::Light),
|
||
"截图模式必须给确定主题(CI 冒烟依赖这条)"
|
||
);
|
||
assert!(!options.wants_system_theme(), "截图模式不许等系统主题");
|
||
}
|
||
|
||
#[test]
|
||
fn explicit_themes_still_win_in_screenshot_mode() {
|
||
let dark = parse(&["--screenshot", "a.png", "--theme=dark"]).unwrap();
|
||
assert_eq!(dark.capture_flavor(), Some(SchemeFlavor::Dark));
|
||
|
||
let both = parse(&[
|
||
"--screenshot",
|
||
"a.png",
|
||
"--theme=dark",
|
||
"--screenshot-theme=light",
|
||
]);
|
||
assert_eq!(both.unwrap().capture_flavor(), Some(SchemeFlavor::Light));
|
||
}
|
||
|
||
#[test]
|
||
fn interactive_mode_still_follows_the_system_theme() {
|
||
let interactive = parse(&[]).unwrap();
|
||
assert_eq!(interactive.capture_flavor(), None);
|
||
assert!(interactive.wants_system_theme(), "交互模式等系统主题");
|
||
|
||
let pinned = parse(&["--theme=dark"]).unwrap();
|
||
assert_eq!(pinned.capture_flavor(), Some(SchemeFlavor::Dark));
|
||
assert!(!pinned.wants_system_theme());
|
||
}
|