mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 21:56:24 +00:00
Merge pull request #6867 from dotCooCoo/fix/ui-egui-parallel-test-races
Tests: font menu and menu bar tests allow for fonts and plug-ins other tests change
This commit is contained in:
@@ -21,12 +21,13 @@ fn the_thai_filter_lists_fonts_with_thai() {
|
||||
/// stay clear of it.
|
||||
#[test]
|
||||
fn the_scroll_bar_leaves_the_stars_clear() {
|
||||
// Every family starred, so each row draws its star.
|
||||
// Every family starred, so each row draws its star. Tests running alongside add fonts and
|
||||
// composite fonts to the process-wide database, which the menu lists too: the ★ filter keeps
|
||||
// the rows to the families starred here.
|
||||
let all = vectorcraft_text::FontDb::global().families();
|
||||
let families = all.len();
|
||||
let ctx = egui::Context::default();
|
||||
let area = egui::Rect::from_min_size(egui::pos2(0.0, 0.0), egui::vec2(300.0, 160.0));
|
||||
let mut st = super::MenuState::default();
|
||||
let mut st = super::MenuState { favorites_only: true, ..Default::default() };
|
||||
let look = super::MenuLook { samples: false, favorites: &all, ..Default::default() };
|
||||
let mut stars = vec![];
|
||||
for _ in 0..3 {
|
||||
@@ -45,6 +46,7 @@ fn the_scroll_bar_leaves_the_stars_clear() {
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
let families = st.rows.len();
|
||||
assert!(!stars.is_empty() || families == 0, "{families} families, no row stars drawn");
|
||||
// The rows don't fill the list without enough families to scroll, and then there is no bar.
|
||||
if families as f32 * look.row > area.height() {
|
||||
@@ -62,6 +64,13 @@ fn family(name: &str) -> Row {
|
||||
Row::Family(name.to_string())
|
||||
}
|
||||
|
||||
/// The families the font menu lists that stay listed, in its order: the menu's list without the
|
||||
/// composite fonts at its top, which tests running alongside define and remove in the process-wide
|
||||
/// database.
|
||||
fn lasting_families() -> Vec<String> {
|
||||
vectorcraft_text::FontDb::global().family_list().iter().filter(|f| !f.starts_with('.')).cloned().collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recent_fonts_are_first_available_unique_and_expandable() {
|
||||
let names: Vec<_> = ["Alpha", "Bravo", "Charlie"].map(str::to_string).into();
|
||||
@@ -86,7 +95,7 @@ fn recent_fonts_are_first_available_unique_and_expandable() {
|
||||
|
||||
#[test]
|
||||
fn recent_section_rebuilds_and_arrows_skip_its_headings() {
|
||||
let names = vectorcraft_text::FontDb::global().menu_family_list();
|
||||
let names = lasting_families();
|
||||
if names.len() < 3 {
|
||||
return;
|
||||
}
|
||||
@@ -135,7 +144,7 @@ fn recent_section_rebuilds_and_arrows_skip_its_headings() {
|
||||
|
||||
#[test]
|
||||
fn recent_fonts_obey_search_and_favorite_filters() {
|
||||
let names = vectorcraft_text::FontDb::global().menu_family_list();
|
||||
let names = lasting_families();
|
||||
if names.len() < 3 {
|
||||
return;
|
||||
}
|
||||
@@ -176,7 +185,7 @@ fn recent_fonts_obey_search_and_favorite_filters() {
|
||||
|
||||
#[test]
|
||||
fn opening_on_another_font_keeps_the_recent_section_visible() {
|
||||
let names = vectorcraft_text::FontDb::global().menu_family_list();
|
||||
let names = lasting_families();
|
||||
let Some(current) = names.last() else { return };
|
||||
let recent = vec![names[0].clone()];
|
||||
let ctx = egui::Context::default();
|
||||
@@ -244,7 +253,7 @@ fn the_wheel_steps_one_family_per_notch_and_stops_at_the_ends() {
|
||||
/// others in the database's order, under the favourites (and other) filters.
|
||||
#[test]
|
||||
fn the_wheel_follows_the_menus_order_and_filters() {
|
||||
let names = vectorcraft_text::FontDb::global().menu_family_list();
|
||||
let names = lasting_families();
|
||||
if names.len() < 3 {
|
||||
return;
|
||||
}
|
||||
@@ -770,8 +779,9 @@ fn the_variable_filter_lists_only_variable_families() {
|
||||
assert_eq!(frame(&mut st, vec![], &favorites).0, [TWO_AXIS_FAMILY]);
|
||||
st.favorites_only = false;
|
||||
// Off again: every family is listed.
|
||||
let lasting = lasting_families();
|
||||
let again = click(&mut st, &favorites);
|
||||
assert!(!st.variable_only);
|
||||
assert_eq!(again, frame(&mut st, vec![], &[]).0);
|
||||
assert!(lasting.iter().all(|f| has(&again, f)), "{again:?}");
|
||||
assert!(has(&again, TWO_AXIS_FAMILY) && has(&again, "Source Sans 3") && has(&again, "JetBrains Mono"), "{again:?}");
|
||||
}
|
||||
|
||||
@@ -683,48 +683,51 @@ fn the_app_bar_hides_its_menus_with_the_mac_menu_bar() {
|
||||
/// answers, the menus are as before and work again.
|
||||
#[test]
|
||||
fn the_menu_bar_is_inert_while_a_file_dialog_is_open() {
|
||||
let mut m = Mac::new(true);
|
||||
m.app.services.dialogs_are_sheets = true;
|
||||
let (shown, _) = crate::tests_picks::off_the_ui_thread(&mut m.app.services);
|
||||
m.app.run("shape.rectangle", json!({"x": 200, "y": 150, "width": 20, "height": 20})).unwrap();
|
||||
m.app.run("select.none", json!({})).unwrap();
|
||||
m.frame(vec![]);
|
||||
let rows = |bar: &MenuBar| bar.items().iter().map(|it| (it.command, it.params.clone(), it.enabled)).collect::<Vec<_>>();
|
||||
let before = m.fake.last();
|
||||
let system = [native_menu::HIDE, native_menu::HIDE_OTHERS, native_menu::MINIMIZE];
|
||||
assert!(system.iter().all(|c| find(&before, c).enabled));
|
||||
assert!(m.app.run("file.open", json!({})).is_err());
|
||||
assert!(m.app.file_dialog_open());
|
||||
m.frame(vec![]);
|
||||
let inert = m.fake.last();
|
||||
for it in inert.items() {
|
||||
let kept = it.command.is_some_and(|c| system.contains(&c));
|
||||
assert_eq!(it.enabled, kept, "{:?} {} while the dialog is open", it.command, it.label);
|
||||
}
|
||||
// A click that raced the menu going inert isn't run; Minimize is.
|
||||
let rulers = (m.app.ui.view.rulers, find(&before, "view.rulers").clone());
|
||||
m.fake.report(native_menu::Event::Click(rulers.1.clone()));
|
||||
m.frame(vec![]);
|
||||
assert_eq!(m.app.ui.view.rulers, rulers.0);
|
||||
m.fake.report(native_menu::Event::Click(find(&inert, native_menu::MINIMIZE).clone()));
|
||||
assert!(m.frame(vec![]).viewport_output[&egui::ViewportId::ROOT].commands.contains(&egui::ViewportCommand::Minimized(true)));
|
||||
// A key equivalent that raced it doesn't reach egui.
|
||||
let mut k = crate::shortcuts::parse("Cmd+A").unwrap();
|
||||
k.modifiers.mac_cmd = k.modifiers.command;
|
||||
m.fake.report(native_menu::Event::Key(k));
|
||||
let mut raw = egui::RawInput::default();
|
||||
m.app.raw_input_hook(&m.ctx, &mut raw);
|
||||
assert!(!raw.events.iter().any(|e| matches!(e, Event::Key { .. })), "{:?}", raw.events);
|
||||
m.key_equivalent("Cmd+A");
|
||||
assert_eq!(m.selected(), 0, "⌘A selected nothing");
|
||||
// Cancelled: the menus are as before, and work again.
|
||||
shown.answer(&[]);
|
||||
m.frame(vec![]);
|
||||
m.frame(vec![]);
|
||||
assert!(!m.app.file_dialog_open());
|
||||
// Every row from before is back as it was (tests running alongside may add plug-in rows).
|
||||
let after = rows(&m.fake.last());
|
||||
assert!(rows(&before).iter().all(|r| after.contains(r)), "the menus are as before");
|
||||
// The menus read before the dialog and after it are compared, so the whole run is undisturbed:
|
||||
// a test running alongside can add or remove a composite font or a plug-in in between.
|
||||
let (mut m, (before, after, rulers)) = undisturbed(|m| {
|
||||
m.app.services.dialogs_are_sheets = true;
|
||||
let (shown, _) = crate::tests_picks::off_the_ui_thread(&mut m.app.services);
|
||||
m.app.run("shape.rectangle", json!({"x": 200, "y": 150, "width": 20, "height": 20})).unwrap();
|
||||
m.app.run("select.none", json!({})).unwrap();
|
||||
m.frame(vec![]);
|
||||
let before = m.fake.last();
|
||||
let system = [native_menu::HIDE, native_menu::HIDE_OTHERS, native_menu::MINIMIZE];
|
||||
assert!(system.iter().all(|c| find(&before, c).enabled));
|
||||
assert!(m.app.run("file.open", json!({})).is_err());
|
||||
assert!(m.app.file_dialog_open());
|
||||
m.frame(vec![]);
|
||||
let inert = m.fake.last();
|
||||
for it in inert.items() {
|
||||
let kept = it.command.is_some_and(|c| system.contains(&c));
|
||||
assert_eq!(it.enabled, kept, "{:?} {} while the dialog is open", it.command, it.label);
|
||||
}
|
||||
// A click that raced the menu going inert isn't run; Minimize is.
|
||||
let rulers = (m.app.ui.view.rulers, find(&before, "view.rulers").clone());
|
||||
m.fake.report(native_menu::Event::Click(rulers.1.clone()));
|
||||
m.frame(vec![]);
|
||||
assert_eq!(m.app.ui.view.rulers, rulers.0);
|
||||
m.fake.report(native_menu::Event::Click(find(&inert, native_menu::MINIMIZE).clone()));
|
||||
assert!(m.frame(vec![]).viewport_output[&egui::ViewportId::ROOT].commands.contains(&egui::ViewportCommand::Minimized(true)));
|
||||
// A key equivalent that raced it doesn't reach egui.
|
||||
let mut k = crate::shortcuts::parse("Cmd+A").unwrap();
|
||||
k.modifiers.mac_cmd = k.modifiers.command;
|
||||
m.fake.report(native_menu::Event::Key(k));
|
||||
let mut raw = egui::RawInput::default();
|
||||
m.app.raw_input_hook(&m.ctx, &mut raw);
|
||||
assert!(!raw.events.iter().any(|e| matches!(e, Event::Key { .. })), "{:?}", raw.events);
|
||||
m.key_equivalent("Cmd+A");
|
||||
assert_eq!(m.selected(), 0, "⌘A selected nothing");
|
||||
// Cancelled: the menus are as before, and work again.
|
||||
shown.answer(&[]);
|
||||
m.frame(vec![]);
|
||||
m.frame(vec![]);
|
||||
assert!(!m.app.file_dialog_open());
|
||||
(rows(&before), rows(&m.fake.last()), rulers)
|
||||
});
|
||||
// Every row from before is back as it was.
|
||||
assert!(before.iter().all(|r| after.contains(r)), "the menus are as before");
|
||||
m.fake.report(native_menu::Event::Click(rulers.1));
|
||||
m.frame(vec![]);
|
||||
assert_eq!(m.app.ui.view.rulers, !rulers.0);
|
||||
|
||||
Reference in New Issue
Block a user