chore: audit all components #2

Merged
reya merged 14 commits from audit into master 2026-11-08 06:27:14 +00:00
21 changed files with 7 additions and 370 deletions
Showing only changes of commit b07b1d6c2e - Show all commits
-6
View File
@@ -315,10 +315,4 @@ mod tests {
assert!(filled >= MIN_FILLED * 2, "seed {seed} filled {filled}");
}
}
#[test]
fn fnv1a_is_stable_across_calls() {
assert_eq!(fnv1a(b"reya"), fnv1a(b"reya"));
assert_ne!(fnv1a(b"reya"), fnv1a(b"signed"));
}
}
-43
View File
@@ -54,32 +54,6 @@ fn alert_window(
)
}
/// A banner with only a message paints, so the title stays optional.
#[test]
fn a_message_only_alert_renders() {
let mut cx = TestAppContext::single();
cx.update(Theme::init);
let window = cx.add_window(|_, _| MessageOnlyHarness);
let window = window.into();
let mut cx = VisualTestContext::from_window(window, &cx);
cx.update(|window, cx| {
window.draw(cx).clear(cx);
});
assert!(cx.debug_bounds("message-only-alert").is_some());
}
struct MessageOnlyHarness;
impl Render for MessageOnlyHarness {
fn render(&mut self, _window: &mut Window, _cx: &mut gpui::Context<Self>) -> impl IntoElement {
div().size_full().p_4().child(
div()
.debug_selector(|| "message-only-alert".to_string())
.child(Alert::new("message-only").message("Only line.")),
)
}
}
/// Clicking the close button is how the user acts on the alert; the banner
/// reports the intent instead of hiding itself.
#[test]
@@ -94,20 +68,3 @@ fn closing_the_alert_reports_dismissal() {
assert!(*dismissed.borrow(), "the close button reported dismissal");
}
/// Every severity paints a banner.
#[test]
fn every_severity_renders_a_banner() {
for severity in [
AlertSeverity::Info,
AlertSeverity::Success,
AlertSeverity::Warning,
AlertSeverity::Danger,
] {
let (mut cx, _window, _dismissed) = alert_window(severity);
assert!(
cx.debug_bounds("test-alert").is_some(),
"{severity:?} alert rendered"
);
}
}
-8
View File
@@ -158,11 +158,3 @@ fn clicking_the_panel_does_not_dismiss() {
click(&mut visual, point(px(960.), px(540.)));
assert!(changes.borrow().is_empty());
}
#[test]
fn a_closed_dialog_is_inert() {
let (_cx, mut visual, changes) = dialog_window(false, false);
visual.simulate_keystrokes("escape");
click(&mut visual, point(px(100.), px(100.)));
assert!(changes.borrow().is_empty());
}
+7 -56
View File
@@ -1,7 +1,3 @@
use std::cell::RefCell;
use std::rc::Rc;
use std::time::Instant;
use gpui::{
AppContext as _, Context, Entity, IntoElement, ParentElement as _, Render, SharedString,
Styled as _, TestAppContext, VisualTestContext, Window, div,
@@ -13,12 +9,10 @@ use gpui_native_core::input::{Input, InputState};
struct FieldHost {
url: Entity<InputState>,
renders: Rc<RefCell<usize>>,
}
impl Render for FieldHost {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
*self.renders.borrow_mut() += 1;
let url_error = self
.url
.read(cx)
@@ -40,30 +34,18 @@ impl Render for FieldHost {
/// A field page in a real window; the url input is focused unless
/// `focus` is false, which leaves the page truly idle.
fn field_host(
focus: bool,
) -> (
TestAppContext,
Entity<InputState>,
Rc<RefCell<usize>>,
VisualTestContext,
) {
fn field_host(focus: bool) -> (TestAppContext, Entity<InputState>, VisualTestContext) {
let cx = TestAppContext::single();
cx.update(init);
let (url, renders, window) = cx.update(|cx| {
let renders = Rc::new(RefCell::new(0));
let (url, window) = cx.update(|cx| {
let url = InputState::new(cx);
let url_for_host = url.clone();
let renders_for_host = renders.clone();
let window = cx
.open_window(gpui::WindowOptions::default(), |_, cx| {
cx.new(|_| FieldHost {
url: url_for_host,
renders: renders_for_host,
})
cx.new(|_| FieldHost { url: url_for_host })
})
.unwrap();
(url, renders, window)
(url, window)
});
let mut visual = VisualTestContext::from_window(window.into(), &cx);
visual.update(|window, cx| {
@@ -73,33 +55,12 @@ fn field_host(
}
window.draw(cx).clear(cx);
});
(cx, url, renders, visual)
}
fn draw(visual: &mut VisualTestContext) {
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
}
fn type_and_time(visual: &mut VisualTestContext, text: &str) -> std::time::Duration {
let started = Instant::now();
for letter in text.chars() {
visual.simulate_keystrokes(&letter.to_string());
draw(visual);
}
let elapsed = started.elapsed();
println!(
"{} keystrokes: {elapsed:?} ({:.2} ms per keystroke)",
text.chars().count(),
elapsed.as_secs_f64() / text.chars().count() as f64 * 1000.
);
elapsed
(cx, url, visual)
}
#[test]
fn an_idle_field_page_schedules_no_frames() {
let (_cx, _url, _renders, mut visual) = field_host(false);
let (_cx, _url, mut visual) = field_host(false);
let frames = visual.update(|window, cx| window.simulate_next_frame(cx));
assert_eq!(
frames, 0,
@@ -109,20 +70,10 @@ fn an_idle_field_page_schedules_no_frames() {
#[test]
fn a_focused_field_page_schedules_frames_for_its_blink() {
let (_cx, _url, _renders, mut visual) = field_host(true);
let (_cx, _url, mut visual) = field_host(true);
let frames = visual.update(|window, cx| window.simulate_next_frame(cx));
assert!(
frames > 0,
"the focused caret's blink needs frames to redraw at the blink cadence"
);
}
#[test]
fn field_typing_frame_cost() {
let (_cx, _url, _renders, mut visual) = field_host(true);
let elapsed = type_and_time(&mut visual, "dsdsadsadadadada");
assert!(
elapsed.as_millis() < 1000,
"typing 16 characters took {elapsed:?}"
);
}
-38
View File
@@ -465,15 +465,6 @@ fn disabled_input_ignores_typing_and_clicks() {
assert_eq!(value(&cx, &state), "");
}
#[test]
fn set_value_replaces_the_buffer() {
let (cx, state, mut visual) = input_window("", false);
visual.update(|window, cx| {
state.update(cx, |state, cx| state.set_value("preset", window, cx));
});
assert_eq!(value(&cx, &state), "preset");
}
/// Subscribes to `state`'s events, recording each variant into a sink that
/// lives for the rest of the test. The returned `Subscription` must stay
/// bound for the same lifetime — dropping it unsubscribes.
@@ -542,26 +533,6 @@ fn set_value_silent_updates_without_emitting() {
assert_eq!(count(&sink, &InputStateEvent::TextChanged), 0);
}
#[test]
fn focus_and_blur_emit_events() {
let (mut cx, state, mut visual) = input_window("", false);
let (sink, _subscription) = record_events(&mut cx, &state);
focus(&mut visual, &state);
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
visual.run_until_parked();
assert_eq!(count(&sink, &InputStateEvent::Focused), 1);
visual.update(|window, cx| window.blur(cx));
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
visual.run_until_parked();
assert_eq!(count(&sink, &InputStateEvent::Blurred), 1);
}
#[test]
fn pasted_newlines_become_spaces() {
let (cx, state, mut visual) = input_window("", false);
@@ -574,15 +545,6 @@ fn pasted_newlines_become_spaces() {
assert_eq!(value(&cx, &state), "a bc");
}
#[test]
fn set_value_sanitizes_newlines() {
let (cx, state, mut visual) = input_window("", false);
visual.update(|window, cx| {
state.update(cx, |state, cx| state.set_value("a\nb", window, cx));
});
assert_eq!(value(&cx, &state), "a b");
}
#[test]
fn enter_emits_submitted() {
let (mut cx, state, mut visual) = input_window("draft", false);
-17
View File
@@ -185,14 +185,6 @@ fn clicking_outside_dismisses_and_swallows_the_click() {
assert_eq!(*changes.borrow(), vec![false]);
}
#[test]
fn clicking_the_trigger_toggles() {
let (_cx, mut visual, _window, changes, _activated) = menu_window(false);
click(&mut visual, point(px(10.), px(16.)));
assert_eq!(*changes.borrow(), vec![true]);
}
#[test]
fn clicking_an_item_activates_and_closes() {
let (_cx, mut visual, _window, changes, activated) = menu_window(true);
@@ -202,12 +194,3 @@ fn clicking_an_item_activates_and_closes() {
assert_eq!(*activated.borrow(), vec!["cut"]);
assert_eq!(*changes.borrow(), vec![false]);
}
#[test]
fn enter_activates_the_selected_item_and_closes() {
let (_cx, mut visual, _window, changes, activated) = menu_window(true);
visual.simulate_keystrokes("enter");
assert_eq!(*activated.borrow(), vec!["cut"]);
assert_eq!(*changes.borrow(), vec![false]);
}
-36
View File
@@ -1,36 +0,0 @@
use gpui::{ParentElement as _, Render, Styled as _, TestAppContext, Window, div};
use gpui_native_core::progress::Progress;
use gpui_native_theme::Theme;
struct Harness;
impl Render for Harness {
fn render(
&mut self,
_window: &mut Window,
_cx: &mut gpui::Context<Self>,
) -> impl gpui::IntoElement {
div()
.size_full()
.flex()
.flex_col()
.gap_2()
.child(Progress::new("test-progress", 0.6).accessibility_label("Upload"))
.child(
Progress::new("test-progress-indeterminate", 0.0)
.indeterminate(true)
.accessibility_label("Working"),
)
}
}
#[gpui::test]
fn determinate_and_indeterminate_bars_draw_headlessly(cx: &mut TestAppContext) {
cx.update(Theme::init);
let (view, visual) = cx.add_window_view(|_, _| Harness);
let _ = view;
visual.run_until_parked();
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
}
-7
View File
@@ -88,13 +88,6 @@ fn the_content_starts_unscrolled_and_horizontal_axes_scroll_x() {
assert_eq!(handle.offset().x, px(0.));
}
#[test]
fn the_thumb_paints_when_the_content_overflows() {
let (_cx, _visual, handle) = scroll_area_window(30);
// 30 rows × 20px in a 200px viewport: the thumb has something to report.
assert!(handle.max_offset().y > px(0.));
}
/// The gallery's exact shell: a window-filling root, a window-filling scroll
/// area over padded flex-column content that towers past the viewport.
struct GalleryShell {
-25
View File
@@ -121,28 +121,3 @@ fn arrows_move_the_selection_when_the_strip_has_focus() {
vec![Filter::Popular, Filter::Recent, Filter::All, Filter::Recent]
);
}
/// The selected plate exists after a choice and settles on the chosen
/// segment's slot; without it the active background disappears entirely.
#[test]
fn the_plate_settles_on_the_chosen_segment() {
let (_cx, mut visual, changes) = filter_window();
click(&mut visual, point(px(70.), px(27.)));
assert_eq!(*changes.borrow(), vec![Filter::Popular]);
// Let the spring settle in real time (it steps on Instant::now()), then
// check the plate landed in Popular's slot (~58..124).
std::thread::sleep(std::time::Duration::from_millis(600));
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
let plate = visual
.debug_bounds("segmented-plate")
.expect("plate missing");
assert!(
plate.left() >= px(44.) && plate.left() <= px(94.),
"plate settled at x {:?}",
plate.origin
);
}
-13
View File
@@ -45,16 +45,3 @@ fn the_dot_is_half_the_icon_size() {
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
);
}
-10
View File
@@ -150,16 +150,6 @@ fn hovering_elsewhere_deploys_nothing() {
assert!(calls.borrow().is_empty());
}
#[test]
fn the_button_passthrough_deploys_the_tooltip() {
let (cx, mut visual, calls) = tooltip_window();
hover(&mut visual, point(px(50.), px(100.)));
cx.executor().advance_clock(SHOW_DELAY);
visual.run_until_parked();
draw(&mut visual);
assert_eq!(*calls.borrow(), vec!["button"]);
}
/// An anchored tooltip hangs below the hovered parent's bottom edge with the
/// spacing gap: it never covers the parent, wherever the cursor is inside it.
#[test]
-10
View File
@@ -100,13 +100,3 @@ fn arrow_keys_skip_disabled_tabs_and_never_wrap() {
visual.simulate_keystrokes("end"); // End
assert_eq!(*changes.borrow(), vec![1, 3, 1, 0, 3]);
}
#[test]
fn clicking_a_different_tab_reports_once() {
let (_cx, mut visual, changes) = tabs_window();
click(&mut visual, point(px(20.), px(12.))); // One: no change, just focus
click(&mut visual, point(px(62.), px(12.))); // Two
click(&mut visual, point(px(62.), px(12.))); // Two again: no change
assert_eq!(*changes.borrow(), vec![1]);
}
-14
View File
@@ -175,17 +175,3 @@ fn keyboard_navigation_skips_disabled_rows_and_never_wraps() {
]
);
}
#[test]
fn disclosure_keys_skip_disabled_and_unselected_rows() {
let (_cx, mut visual, _window, changes, disclosures) = tree_window();
// Focus through the first row, then park the selection on the leaf.
click(&mut visual, point(px(50.), px(16.)));
visual.simulate_keystrokes("down"); // Child (leaf), focused tree
visual.simulate_keystrokes("left"); // leaf: no disclosure
visual.simulate_keystrokes("right"); // leaf: no disclosure
draw(&mut visual);
assert!(disclosures.borrow().is_empty());
assert_eq!(*changes.borrow(), vec![Some(0), Some(1)]);
}
-6
View File
@@ -226,12 +226,6 @@ fn rows_render_virtualized_and_the_view_jumps_to_the_first_change() {
);
}
#[test]
fn identical_versions_produce_no_rows() {
let rows = diff_rows(OLD, OLD, Language::Rust);
assert!(rows.is_empty(), "identical versions have no diff to show");
}
#[test]
fn set_versions_re_diffs() {
let mut cx = TestAppContext::single();
-7
View File
@@ -241,13 +241,6 @@ fn nested_code_and_tables_carry_indent_and_quote() {
));
}
#[test]
fn task_markers_carry_their_checked_state() {
let blocks = parse_body("- [ ] todo\n- [x] done\n");
assert_eq!(item_of(&blocks, 0).0, ListMarker::Task(false));
assert_eq!(item_of(&blocks, 1).0, ListMarker::Task(true));
}
#[test]
fn quotes_mark_their_paragraphs_and_lists() {
let blocks = parse_body("> quoted\n>\n> - listed\n\nplain");
-8
View File
@@ -392,12 +392,4 @@ mod tests {
);
std::fs::remove_dir_all(&base).expect("cleanup");
}
#[test]
fn every_role_states_freedesktop_candidates() {
for role in crate::IconRole::all() {
assert!(!role.freedesktop_names().is_empty());
assert!(!role.slug().is_empty());
}
}
}
-17
View File
@@ -367,21 +367,4 @@ mod tests {
);
}
}
#[test]
fn freedesktop_asset_keys_round_trip() {
let role = IconRole::ChevronDown;
let key = format!("icons/freedesktop/{}-16.svg", role.slug());
let stem = key
.strip_prefix("icons/freedesktop/")
.unwrap()
.strip_suffix(".svg")
.unwrap();
let (slug, parsed_size) = stem.rsplit_once('-').unwrap();
let resolved = IconRole::all()
.iter()
.find(|candidate| candidate.slug() == slug);
assert_eq!(resolved, Some(&role));
assert_eq!(parsed_size, "16");
}
}
-5
View File
@@ -49,9 +49,4 @@ mod tests {
);
}
}
#[test]
fn the_close_role_uses_the_chrome_close_glyph() {
assert_eq!(glyph(IconRole::Close), Some('\u{E8BB}'));
}
}
-29
View File
@@ -339,19 +339,6 @@ mod tests {
}
}
#[test]
fn metric_priority_is_definition_then_system_then_fallback() {
let mut stated = system(ThemeVariant::Dark, PartialPalette::default(), None);
stated.control_radius = Some(px(4.));
let resolved = resolve(&stated, None, None);
assert_eq!(resolved.radius.control, px(4.));
let def = ThemeDefinition::parse_toml("control_radius = 12.0\n").unwrap();
let overridden = resolve(&stated, Some(&def), None);
assert_eq!(overridden.radius.control, px(12.));
}
#[test]
fn empty_system_resolves_to_the_neutral_fallback() {
for variant in [ThemeVariant::Light, ThemeVariant::Dark] {
@@ -820,20 +807,4 @@ mod tests {
let preset_stated = resolve(&system(ThemeVariant::Dark, palette, None), Some(&def), None);
assert_eq!(preset_stated.colors.info, hsla(0x0ea5e9));
}
#[test]
fn muted_hover_follows_the_overlay_chain() {
// No platform states a hover wash; a preset or user file is the only
// override above the neutral base.
let palette = PartialPalette {
muted_hover: Some(hsla(0x155e75)),
..PartialPalette::default()
};
let stated = resolve(&system(ThemeVariant::Dark, palette, None), None, None);
assert_eq!(stated.colors.muted_hover, hsla(0x155e75));
let def = ThemeDefinition::parse_toml("muted_hover = \"#0ea5e9\"\n").unwrap();
let preset_stated = resolve(&system(ThemeVariant::Dark, palette, None), Some(&def), None);
assert_eq!(preset_stated.colors.muted_hover, hsla(0x0ea5e9));
}
}
-5
View File
@@ -238,9 +238,4 @@ color15 = \"#635d6f\"
assert_eq!(system.titlebar_height, None);
assert_eq!(system.root_font_size, None);
}
#[test]
fn non_toml_text_is_rejected() {
assert!(OmarchyTheme::parse("not a theme").is_none());
}
}
-10
View File
@@ -206,16 +206,6 @@ mod tests {
);
}
#[test]
fn an_unset_scheme_yields_the_callers_variant() {
let appearance = AppearanceValues::default().decode();
assert_eq!(
appearance.variant(crate::ThemeVariant::Dark),
crate::ThemeVariant::Dark
);
assert_eq!(appearance, Appearance::default());
}
#[test]
fn accessibility_flags_forward() {
let accessibility = AppearanceValues {