audit menu

This commit is contained in:
2026-11-07 19:42:10 +07:00
parent a859704185
commit 66961a1026
4 changed files with 74 additions and 20 deletions
+22
View File
@@ -112,6 +112,28 @@ fn click(visual: &mut VisualTestContext, position: gpui::Point<gpui::Pixels>) {
visual.simulate_mouse_up(position, MouseButton::Left, Modifiers::default());
}
/// Every action row renders at the platform's stated menu row height,
/// whatever its content — the metric is the whole row, not a floor under
/// padding. Item 1 of the harness menu is a separator, so it is skipped.
#[test]
fn rows_render_at_the_stated_menu_row_height() {
let (cx, mut visual, _window, _changes, _activated) = menu_window(true);
let stated = cx.update(|cx| Theme::global(cx).sizes.medium.menu_item_height);
for index in [0, 2, 3, 4] {
let selector: &'static str = Box::leak(format!("menu-item-{index}").into_boxed_str());
let row = visual
.debug_bounds(selector)
.unwrap_or_else(|| panic!("row {index} should have been laid out"));
// Painted bounds are snapped to device pixels; allow half a pixel.
assert!(
(row.size.height - stated).abs() <= px(0.5),
"row {index} is {:?} tall, stated menu row height is {stated:?}",
row.size.height
);
}
}
#[test]
fn arrow_navigation_skips_separators_and_disabled_items() {
let (_cx, mut visual, _window, changes, activated) = menu_window(true);
+31 -11
View File
@@ -67,25 +67,45 @@ fn click(visual: &mut VisualTestContext, position: gpui::Point<gpui::Pixels>) {
visual.simulate_mouse_up(position, MouseButton::Left, gpui::Modifiers::default());
}
/// The trigger band is `16..46`; the panel hangs 4 px below it with a 4 px
/// inner padding, so the three rows ride `~58..90`, `~90..122`, `~122..154`.
/// Every option must answer a pointer press — a popup that clips its last
/// item never does.
/// The three option rows must answer a pointer press wherever they were laid
/// out — a popup that clips its last item never does. Row positions come from
/// the rendered bounds, so the stated menu row metric can change freely.
#[test]
fn every_option_row_answers_the_pointer() {
let (_cx, mut visual, changes) = level_window();
let expected = [
(px(74.), Level::Low),
(px(106.), Level::Mid),
(px(138.), Level::High),
];
for (y, value) in expected {
// Open once to measure where the rows were actually drawn.
click(&mut visual, point(px(100.), px(31.)));
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
let centers: Vec<gpui::Point<gpui::Pixels>> = (0..3)
.map(|index| {
let selector: &'static str = Box::leak(format!("menu-item-{index}").into_boxed_str());
let row = visual
.debug_bounds(selector)
.unwrap_or_else(|| panic!("row {index} should have been laid out"));
point(
row.left() + row.size.width / 2.0,
row.top() + row.size.height / 2.0,
)
})
.collect();
// Close again; each iteration below opens the popup fresh.
click(&mut visual, point(px(100.), px(31.)));
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
let expected = [(Level::Low, 0), (Level::Mid, 1), (Level::High, 2)];
for (value, index) in expected {
// Choosing the previous row closed the popup; reopen it.
click(&mut visual, point(px(100.), px(31.)));
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
click(&mut visual, point(px(100.), y));
click(&mut visual, centers[index]);
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});