use gpui::{ AppContext as _, IntoElement, ParentElement as _, Render, Styled as _, TestAppContext, VisualTestContext, Window, div, }; use gpui_native_core::status_dot::{StatusDot, StatusDotVariant}; use gpui_native_theme::{ActiveTheme as _, Theme}; struct DotHost; impl Render for DotHost { fn render(&mut self, _window: &mut Window, _cx: &mut gpui::Context) -> impl IntoElement { div().size_full().p_4().child( StatusDot::new("test-dot") .variant(StatusDotVariant::Success) .label("Synced"), ) } } fn dot_window() -> (TestAppContext, gpui::AnyWindowHandle) { let mut cx = TestAppContext::single(); cx.update(Theme::init); let window = cx.add_window(|_, _| DotHost); let window: gpui::AnyWindowHandle = window.into(); cx.update_window(window, |_, window, cx| { window.draw(cx).clear(cx); }) .unwrap(); (cx, window) } /// A medium dot is half the theme's icon size — big enough to read a state /// from, small enough to sit beside row text. The label must not grow it. #[test] fn the_dot_is_half_the_icon_size() { let (cx, window) = dot_window(); let mut visual = VisualTestContext::from_window(window, &cx); let dot = visual.debug_bounds("test-dot").expect("dot missing"); let side = cx.update(|cx| cx.theme().sizes.medium.icon_size) / 2.; assert!( ((dot.size.width - side).abs() <= gpui::px(0.5)) && ((dot.size.height - side).abs() <= gpui::px(0.5)), "the dot must be {side:?} wide, got {:?}", dot.size ); } #[test] fn the_dot_keeps_a_square_footprint() { let (cx, window) = dot_window(); let mut visual = VisualTestContext::from_window(window, &cx); let dot = visual.debug_bounds("test-dot").expect("dot missing"); assert!( (dot.size.width - dot.size.height).abs() <= gpui::px(0.5), "the dot must stay circular: {:?}", dot.size ); }