use gpui::{
Focusable, Modifiers, MouseButton, Point, TestAppContext, VisualTestContext, point, px, size,
};
use ui::{
menu::Item,
menubar::{self, Menu, Menubar},
};
const WIDTH: gpui::Pixels = px(900.0);
const HEIGHT: gpui::Pixels = px(600.0);
const SWEEP: f32 = 2.0;
const INSIDE: gpui::Pixels = px(24.0);
const SHORT: &str = "Choose a file";
const LONG: &str = "Choose a markdown file from somewhere deep inside this workspace and open it in the editor to edit";
fn menus(description: Option<&'static str>) -> Vec<Menu> {
let open = Item::action("Open…");
vec![Menu::new(
"File",
vec![
match description {
Some(copy) => open.with_description(copy),
None => open,
},
Item::action("Close"),
],
)]
}
fn open(cx: &mut TestAppContext, description: Option<&'static str>) -> Card {
cx.update(|cx| {
theme::Theme::install(theme::Appearance::Dark, cx);
menubar::init(cx);
});
let window = cx.add_window(|_, cx| Menubar::new(menus(description), cx));
let bar = window.root(cx).unwrap();
let mut visual = VisualTestContext::from_window(window.into(), cx);
visual.simulate_resize(size(WIDTH, HEIGHT));
visual.update(|window, cx| {
let handle = bar.read(cx).focus_handle(cx);
window.focus(&handle, cx);
});
visual.simulate_keystrokes("enter");
visual.run_until_parked();
Card { bar, cx: visual }
}
struct Card {
bar: gpui::Entity<Menubar>,
cx: VisualTestContext,
}
impl Card {
fn hit(&mut self, at: Point<gpui::Pixels>) -> Option<usize> {
self.cx
.simulate_mouse_move(at, MouseButton::Left, Modifiers::default());
let bar = &self.bar;
self.cx.update(|_, cx| bar.read(cx).cursor().row())
}
fn top_of(&mut self, row: usize) -> gpui::Pixels {
for step in 0..(f32::from(HEIGHT) / SWEEP) as usize {
let y = px(step as f32 * SWEEP);
if self.hit(point(INSIDE, y)) == Some(row) {
return y;
}
}
panic!("row {row} never answered the pointer");
}
fn first_row_height(&mut self) -> gpui::Pixels {
self.top_of(1) - self.top_of(0)
}
fn inside(&mut self, x: gpui::Pixels, y: gpui::Pixels) -> bool {
let park = self.top_of(1);
self.hit(point(INSIDE, park));
self.hit(point(x, y)) == Some(0)
}
fn first_row_width(&mut self) -> gpui::Pixels {
let y = self.top_of(0) + px(SWEEP);
assert!(self.inside(INSIDE, y), "the sweep never found the card");
let mut left = (px(0.0), INSIDE);
while left.1 - left.0 > px(1.0) {
let mid = (left.0 + left.1) / 2.0;
if self.inside(mid, y) {
left.1 = mid;
} else {
left.0 = mid;
}
}
let mut right = (INSIDE, WIDTH);
while right.1 - right.0 > px(1.0) {
let mid = (right.0 + right.1) / 2.0;
if self.inside(mid, y) {
right.0 = mid;
} else {
right.1 = mid;
}
}
right.0 - left.1
}
}
#[gpui::test]
fn a_longer_description_does_not_widen_the_panel(cx: &mut TestAppContext) {
let short = open(cx, Some(SHORT)).first_row_width();
let long = open(cx, Some(LONG)).first_row_width();
assert!(
(long - short).abs() <= px(2.0),
"the panel grew with the sentence instead of clipping it: {short} then {long}"
);
}
#[gpui::test]
fn a_longer_description_does_not_heighten_the_row(cx: &mut TestAppContext) {
let short = open(cx, Some(SHORT)).first_row_height();
let long = open(cx, Some(LONG)).first_row_height();
assert!(
(long - short).abs() <= px(SWEEP),
"the description wrapped instead of staying on one line: {short} then {long}"
);
}
#[gpui::test]
fn a_described_panel_is_the_wider_one(cx: &mut TestAppContext) {
let plain = open(cx, None).first_row_width();
let described = open(cx, Some(SHORT)).first_row_width();
assert!(
described > plain,
"a described panel is no wider than a plain one: {plain} then {described}"
);
}