test(selection): 状态层的两种 α 都要查(复审 P2-4 补,第二次变异曾漏网)

原来只查 hover(8%)那一色,于是「把 pressed 列的状态层画成方块」照样绿——实测变异
mut-one-layer-box 当时是 passed。现在 hover(8%) 与 pressed/focus(10%) 两种颜色各查一遍,
每一块的四个角都不许有墨。

变异证据(六个变异全部转红,见报告):
- mut-one-box-22     → 18.3:Primary 块不得超过 21,实测 22×22 @ (541,222)
- mut-one-layer-box  → 18.5:Pressed 状态层必须是圆(四角不该有墨)@ (532,212)
- mut-chip-34        → 13.1:filter chip 应恰好四块,实测 3
This commit is contained in:
AskaEth committed 2026-11-02 07:03:13 +08:00
1 parent 4155429f45
commit 9519ce8e1b
1 file changed
+44 -39
@@ -205,35 +205,36 @@ fn selection_geometry_matches_the_reference() {
);
// ---- §18.5 / §19.7:状态层直径 40,且**每一块**都是圆(四角无墨)----------------
let hover_layer = interaction::overlay_color(
&ui,
Interaction::Hovered,
Role::OnSurfaceVariant,
Role::Surface,
)
.expect("hover 有状态层");
let circles: Vec<_> = ink_boxes(&shot, hover_layer, surface, 37, 43)
.into_iter()
.filter(|bbox| near(bbox.width(), 40) && near(bbox.height(), 40))
.collect();
assert!(
circles.len() >= 5,
"18.5:应找到 ≥5 块 Ø40 状态层(checkbox×3 + radio + switch),实测 {}:{}",
circles.len(),
dims(&circles)
);
for circle in &circles {
for (x, y) in [
(circle.left, circle.top),
(circle.right, circle.top),
(circle.left, circle.bottom),
(circle.right, circle.bottom),
] {
assert!(
!matches(shot.at(x, y), rgb(hover_layer)),
"18.5:状态层必须是圆(外接框四角不该有墨)@ ({x},{y})"
);
// hover 是 8%、pressed/focus 是 10%:**两种颜色都要查**。只查 8% 会漏掉「按下那一列被画成
// 方块」——代码 reviewer 的第二次变异正好落在这个盲点上(实测它当时是绿的)。
let mut circles = 0;
for state in [Interaction::Hovered, Interaction::Pressed] {
let layer = interaction::overlay_color(&ui, state, Role::OnSurfaceVariant, Role::Surface)
.expect("可交互态有状态层");
let found: Vec<_> = ink_boxes(&shot, layer, surface, 37, 43)
.into_iter()
.filter(|bbox| near(bbox.width(), 40) && near(bbox.height(), 40))
.collect();
assert!(
found.len() >= 2,
"18.5:{state:?} 的 Ø40 状态层应 ≥2 块(checkbox×3 + radio + switch),实测 {}:{}",
found.len(),
dims(&found)
);
for circle in &found {
for (x, y) in [
(circle.left, circle.top),
(circle.right, circle.top),
(circle.left, circle.bottom),
(circle.right, circle.bottom),
] {
assert!(
!matches(shot.at(x, y), rgb(layer)),
"18.5:{state:?} 状态层必须是圆(外接框四角不该有墨)@ ({x},{y})"
);
}
}
circles += found.len();
}
// ---- §10.1 Switch 轨道 52×32 · §13.1 Chip 高 32 -------------------------------
@@ -252,10 +253,13 @@ fn selection_geometry_matches_the_reference() {
.into_iter()
.filter(|bbox| near(bbox.height(), 32))
.collect();
// 选中的 chip 在**四态**里容器都是 `SecondaryContainer`(状态层只叠在未选中的透明底上),
// 所以这里应恰好 4 块——多于 4 说明别的组件的容器也是这个角色、且高 32。
assert_eq!(
chips.len(),
1,
"13.1:选中的 filter chip 应**恰好一块**(32 高),实测 {}:{}",
4,
"13.1:选中的 filter chip 应**恰好四块**(enabled/hover/pressed/focused 各一,32 高),\
实测 {}:{}",
chips.len(),
dims(&chips)
);
@@ -265,7 +269,10 @@ fn selection_geometry_matches_the_reference() {
chips[0].width()
);
// ---- 复审 P2-1:禁用的 chip **只降不删**(图标 / 选中态都要在)------------------
// ---- 复审 P2-1:禁用的 chip **只降不删**(选中态与图标都要在)------------------
// 判据:禁用列里必须**恰好有一块** 12% 填充的 chip(= filter·on)。旧 API 把 selected
// 一起删掉,这一块根本不存在(实测 0 块);能查到它、且宽度 ≥58,说明选中态与图标都还在。
// (未选中的那三个禁用 chip 只有 1px 描边,落在半像素上时覆盖率不足 50%,量不稳,故不在此断言。)
let disabled_container = interaction::disabled_colors(&ui, Role::Surface).0;
let disabled_chips: Vec<_> = ink_boxes(&shot, disabled_container, surface, 28, 140)
.into_iter()
@@ -273,17 +280,15 @@ fn selection_geometry_matches_the_reference() {
.collect();
assert_eq!(
disabled_chips.len(),
4,
"P2-1:禁用列应有 4 个**完整宽度**的 chip(图标没被删掉),实测 {}:{}",
1,
"P2-1:禁用列应**恰好一块**填充 chip(filter·on 的选中态不能被删掉),实测 {}:{}",
disabled_chips.len(),
dims(&disabled_chips)
);
assert!(
disabled_chips.iter().any(|bbox| matches(
shot.at(center(bbox).0, center(bbox).1),
rgb(disabled_container)
)),
"P2-1:禁用列里 filter·on 必须仍是**填充**容器(选中态不能被丢掉)"
disabled_chips[0].width() >= 58,
"P2-1:禁用 chip 宽度应 ≥58(图标还在),实测 {}",
disabled_chips[0].width()
);
// ---- 复审 P2-3:**选中且禁用**的 Checkbox 容器是 38%,不是 12% -----------------
@@ -314,7 +319,7 @@ fn selection_geometry_matches_the_reference() {
勾 {checks} / 短横 {bars} · 状态层 {} · 禁用 38% {} · 禁用 chip {}",
twenty.len(),
rings.len(),
circles.len(),
circles,
ink38.len(),
disabled_chips.len()
);