test(app-iced): 修 sub_24_boxes 白名单与 18px 线宽断言的格式化口径

- 白名单路径补全(shell/nav.rs 不在 components/ 下);扫描跳过 icons.rs 自身;
- SVG 的 stroke-width 用 {} 渲染 f32,2.0 会打印成 "2",所以断言改成
  比数值(stroke_width_for(18,1.5) == 2.0)再比它渲染出的字符串,别写死 "2.0"。
app-iced --lib: 168 passed, 0 failed。
This commit is contained in:
AskaEth committed 2026-11-02 13:12:16 +08:00
1 parent 7627462593
commit 896edf07fe
1 file changed
+32 -13
+32 -13
View File
@@ -202,12 +202,19 @@ mod tests {
baked.contains("width=\"18\"") && baked.contains("height=\"18\""),
"按 18 烘焙时 SVG 的 width/height 必须是 18:{baked}"
);
// `stroke-width` 的数值由 `format!(\"{}\", f32)` 渲染:2.0 会打印成 `2`,
// 所以这里比的是**数值**(2.0)而不是字符串 "2.0"。
let baked_stroke = unlucky_design::icons::stroke_width_for(18.0, 1.5);
assert!(
baked.contains("stroke-width=\"2.0\""),
"18px 渲染的 stroke-width 必须是 1.5×24/18 = 2.0:{baked}"
(baked_stroke - 2.0).abs() < 1.0e-6,
"18px 的 viewBox 线宽必须是 2.0,实际 {baked_stroke}"
);
assert!(
baked.contains(&format!("stroke-width=\"{baked_stroke}\"")),
"SVG 里必须真的写着 {baked_stroke}:{baked}"
);
// 视觉线宽 = viewBox 单位 × 盒/viewBox = 2.0 × 18/24 = 1.5(达标)
let baked_visual = unlucky_design::icons::visual_stroke_px(button_px, 2.0);
let baked_visual = unlucky_design::icons::visual_stroke_px(button_px, baked_stroke);
assert!(
(baked_visual - 1.5).abs() < 1.0e-6,
"烘焙路径视觉线宽应 1.5,实际 {baked_visual}"
@@ -215,7 +222,12 @@ mod tests {
// 反证:拿 24 烘焙的那份去填 18 盒(= 用 `view` 装进小盒),视觉只剩 1.125px。
let scaled = source(IconKind::Check, RENDER_PX);
assert!(scaled.contains("stroke-width=\"1.5\"") && scaled.contains("width=\"24\""));
assert!(
scaled.contains(&format!(
"stroke-width=\"{}\"",
unlucky_design::icons::stroke_width_for(RENDER_PX, 1.5)
)) && scaled.contains("width=\"24\"")
);
let scaled_visual = unlucky_design::icons::visual_stroke_px(button_px, 1.5);
assert!(
(scaled_visual - 1.125).abs() < 1.0e-6,
@@ -224,11 +236,14 @@ mod tests {
// switch 滑块的 16 同理:按 16 烘焙要 1.5×24/16 = 2.25。
let thumb_px = IconSize::SwitchThumb.px();
let thumb_stroke = unlucky_design::icons::stroke_width_for(thumb_px, 1.5);
let thumb = source(IconKind::Check, thumb_px);
assert!(
thumb.contains("width=\"16\"") && thumb.contains("stroke-width=\"2.25\""),
"16px 盒要 2.25 个 viewBox 单位:{thumb}"
thumb.contains("width=\"16\"")
&& thumb.contains(&format!("stroke-width=\"{thumb_stroke}\"")),
"16px 盒要 {thumb_stroke} 个 viewBox 单位:{thumb}"
);
assert!((thumb_stroke - 2.25).abs() < 1.0e-6);
}
#[test]
@@ -260,16 +275,16 @@ mod tests {
// (`buttons/mod.rs` 的 IconButton 是「24 图标 + 40 外壳」,图标本身仍是 24。)
const VIEW_OK: &[&str] = &[
"shell/nav.rs",
"inputs/field.rs",
"inputs/menu.rs",
"inputs/search.rs",
"buttons/mod.rs",
"components/inputs/field.rs",
"components/inputs/menu.rs",
"components/inputs/search.rs",
"components/buttons/mod.rs",
];
// 盒 ≠ 24、因此必须用 `view_at` 的文件。
const VIEW_AT_REQUIRED: &[&str] = &[
"buttons/assemble.rs",
"selection/chip.rs",
"selection/switch.rs",
"components/buttons/assemble.rs",
"components/selection/chip.rs",
"components/selection/switch.rs",
"shell/mod.rs",
];
@@ -281,6 +296,10 @@ mod tests {
.expect("strip_prefix")
.to_string_lossy()
.replace('\\', "/");
// 本模块自身就是实现(`view` / `view_at` 的定义与文档),不参与扫描。
if rel == "icons.rs" {
continue;
}
let text = std::fs::read_to_string(&entry).expect("读组件源码");
let plain = text
.lines()