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,且**每一块**都是圆(四角无墨)---------------- // ---- §18.5 / §19.7:状态层直径 40,且**每一块**都是圆(四角无墨)----------------
let hover_layer = interaction::overlay_color( // hover 是 8%、pressed/focus 是 10%:**两种颜色都要查**。只查 8% 会漏掉「按下那一列被画成
&ui, // 方块」——代码 reviewer 的第二次变异正好落在这个盲点上(实测它当时是绿的)。
Interaction::Hovered, let mut circles = 0;
Role::OnSurfaceVariant, for state in [Interaction::Hovered, Interaction::Pressed] {
Role::Surface, let layer = interaction::overlay_color(&ui, state, Role::OnSurfaceVariant, Role::Surface)
) .expect("可交互态有状态层");
.expect("hover 有状态层"); let found: Vec<_> = ink_boxes(&shot, layer, surface, 37, 43)
let circles: Vec<_> = ink_boxes(&shot, hover_layer, surface, 37, 43) .into_iter()
.into_iter() .filter(|bbox| near(bbox.width(), 40) && near(bbox.height(), 40))
.filter(|bbox| near(bbox.width(), 40) && near(bbox.height(), 40)) .collect();
.collect(); assert!(
assert!( found.len() >= 2,
circles.len() >= 5, "18.5:{state:?} 的 Ø40 状态层应 ≥2 块(checkbox×3 + radio + switch),实测 {}:{}",
"18.5:应找到 ≥5 块 Ø40 状态层(checkbox×3 + radio + switch),实测 {}:{}", found.len(),
circles.len(), dims(&found)
dims(&circles) );
); for circle in &found {
for circle in &circles { for (x, y) in [
for (x, y) in [ (circle.left, circle.top),
(circle.left, circle.top), (circle.right, circle.top),
(circle.right, circle.top), (circle.left, circle.bottom),
(circle.left, circle.bottom), (circle.right, circle.bottom),
(circle.right, circle.bottom), ] {
] { assert!(
assert!( !matches(shot.at(x, y), rgb(layer)),
!matches(shot.at(x, y), rgb(hover_layer)), "18.5:{state:?} 状态层必须是圆(外接框四角不该有墨)@ ({x},{y})"
"18.5:状态层必须是圆(外接框四角不该有墨)@ ({x},{y})" );
); }
} }
circles += found.len();
} }
// ---- §10.1 Switch 轨道 52×32 · §13.1 Chip 高 32 ------------------------------- // ---- §10.1 Switch 轨道 52×32 · §13.1 Chip 高 32 -------------------------------
@@ -252,10 +253,13 @@ fn selection_geometry_matches_the_reference() {
.into_iter() .into_iter()
.filter(|bbox| near(bbox.height(), 32)) .filter(|bbox| near(bbox.height(), 32))
.collect(); .collect();
// 选中的 chip 在**四态**里容器都是 `SecondaryContainer`(状态层只叠在未选中的透明底上),
// 所以这里应恰好 4 块——多于 4 说明别的组件的容器也是这个角色、且高 32。
assert_eq!( assert_eq!(
chips.len(), chips.len(),
1, 4,
"13.1:选中的 filter chip 应**恰好一块**(32 高),实测 {}:{}", "13.1:选中的 filter chip 应**恰好四块**(enabled/hover/pressed/focused 各一,32 高),\
实测 {}:{}",
chips.len(), chips.len(),
dims(&chips) dims(&chips)
); );
@@ -265,7 +269,10 @@ fn selection_geometry_matches_the_reference() {
chips[0].width() 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_container = interaction::disabled_colors(&ui, Role::Surface).0;
let disabled_chips: Vec<_> = ink_boxes(&shot, disabled_container, surface, 28, 140) let disabled_chips: Vec<_> = ink_boxes(&shot, disabled_container, surface, 28, 140)
.into_iter() .into_iter()
@@ -273,17 +280,15 @@ fn selection_geometry_matches_the_reference() {
.collect(); .collect();
assert_eq!( assert_eq!(
disabled_chips.len(), disabled_chips.len(),
4, 1,
"P2-1:禁用列应有 4 个**完整宽度**的 chip(图标没被删掉),实测 {}:{}", "P2-1:禁用列应**恰好一块**填充 chip(filter·on 的选中态不能被删掉),实测 {}:{}",
disabled_chips.len(), disabled_chips.len(),
dims(&disabled_chips) dims(&disabled_chips)
); );
assert!( assert!(
disabled_chips.iter().any(|bbox| matches( disabled_chips[0].width() >= 58,
shot.at(center(bbox).0, center(bbox).1), "P2-1:禁用 chip 宽度应 ≥58(图标还在),实测 {}",
rgb(disabled_container) disabled_chips[0].width()
)),
"P2-1:禁用列里 filter·on 必须仍是**填充**容器(选中态不能被丢掉)"
); );
// ---- 复审 P2-3:**选中且禁用**的 Checkbox 容器是 38%,不是 12% ----------------- // ---- 复审 P2-3:**选中且禁用**的 Checkbox 容器是 38%,不是 12% -----------------
@@ -314,7 +319,7 @@ fn selection_geometry_matches_the_reference() {
勾 {checks} / 短横 {bars} · 状态层 {} · 禁用 38% {} · 禁用 chip {}", 勾 {checks} / 短横 {bars} · 状态层 {} · 禁用 38% {} · 禁用 chip {}",
twenty.len(), twenty.len(),
rings.len(), rings.len(),
circles.len(), circles,
ink38.len(), ink38.len(),
disabled_chips.len() disabled_chips.len()
); );