mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Tests: native-menu tests count menu reads only in runs no other test disturbed
This commit is contained in:
@@ -386,7 +386,8 @@ fn click(at: Pos2, pressed: bool) -> Event {
|
||||
/// Run `drag` on a new app with the fake native menu, and run it again on another new app until
|
||||
/// the shortcut and plug-in generations hold still through a run (at most 20 runs). Return that app
|
||||
/// and what `drag` returned. The generations are process-wide and only grow. A test running
|
||||
/// alongside can bump them, and the app then reads the menus again.
|
||||
/// alongside can bump them, and the app then reads the menus again, so every step whose menu
|
||||
/// reads a test counts runs inside `drag`.
|
||||
fn undisturbed<R>(drag: impl Fn(&mut Mac) -> R) -> (Mac, R) {
|
||||
let generations = || (crate::shortcut_editor::GENERATION.load(std::sync::atomic::Ordering::Relaxed), crate::menus::plugin_revision());
|
||||
for _ in 0..20 {
|
||||
@@ -433,15 +434,16 @@ fn key_equivalents_run_through_the_normal_shortcut_path_once() {
|
||||
/// while the button is held, and are read when the button is released, with Undo naming the move.
|
||||
#[test]
|
||||
fn a_drag_reads_the_menus_when_it_is_released() {
|
||||
let (mut m, (start, read)) = undisturbed(|m| {
|
||||
let (m, (read, synced, ended, released)) = undisturbed(|m| {
|
||||
let start = m.start_move();
|
||||
(start, m.reads(6, |_, i| vec![Event::PointerMoved(start + vec2(8.0 * (i + 2) as f32, 0.0))]))
|
||||
let read = m.reads(6, |_, i| vec![Event::PointerMoved(start + vec2(8.0 * (i + 2) as f32, 0.0))]);
|
||||
let synced = m.fake.synced();
|
||||
m.frame(vec![click(start + vec2(56.0, 0.0), false)]);
|
||||
(read, synced, !m.app.session.in_interaction(), m.fake.synced())
|
||||
});
|
||||
assert_eq!(read, 0, "the menus weren't read at any step of the drag");
|
||||
let synced = m.fake.synced();
|
||||
m.frame(vec![click(start + vec2(56.0, 0.0), false)]);
|
||||
assert!(!m.app.session.in_interaction());
|
||||
assert_eq!(m.fake.synced(), synced + 1, "the menus were read on the release");
|
||||
assert!(ended);
|
||||
assert_eq!(released, synced + 1, "the menus were read on the release");
|
||||
assert_eq!(find(&m.fake.last(), "edit.undo").label, "Undo Move");
|
||||
}
|
||||
|
||||
@@ -449,21 +451,24 @@ fn a_drag_reads_the_menus_when_it_is_released() {
|
||||
/// the preview's rectangle gone (nothing selected, so Cut is off), and not at the steps before.
|
||||
#[test]
|
||||
fn escape_during_a_drag_reads_the_menus() {
|
||||
let (mut m, read) = undisturbed(|m| {
|
||||
let (m, read) = undisturbed(|m| {
|
||||
m.app.run("select.none", json!({})).unwrap();
|
||||
m.app.run("tool.select", json!({"tool": "rectangle"})).unwrap();
|
||||
let start = m.on_canvas(200.0, 150.0);
|
||||
m.frame(vec![Event::PointerMoved(start), click(start, true)]);
|
||||
m.frame(vec![Event::PointerMoved(start + vec2(10.0, 10.0))]);
|
||||
assert!(m.app.session.in_interaction(), "the rectangle is being drawn");
|
||||
m.reads(6, |_, i| vec![Event::PointerMoved(start + vec2(10.0, 10.0) * (i + 2) as f32)])
|
||||
let read = m.reads(6, |_, i| vec![Event::PointerMoved(start + vec2(10.0, 10.0) * (i + 2) as f32)]);
|
||||
let cut = find(&m.fake.last(), "edit.cut").enabled;
|
||||
let synced = m.fake.synced();
|
||||
m.frame(vec![Event::Key { key: Key::Escape, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE }]);
|
||||
(read, cut, synced, !m.app.session.in_interaction(), m.fake.synced())
|
||||
});
|
||||
let (read, cut, synced, dropped, escaped) = read;
|
||||
assert_eq!(read, 0, "the menus weren't read at any step of the drag");
|
||||
assert!(find(&m.fake.last(), "edit.cut").enabled, "the preview's rectangle is selected");
|
||||
let synced = m.fake.synced();
|
||||
m.frame(vec![Event::Key { key: Key::Escape, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE }]);
|
||||
assert!(!m.app.session.in_interaction(), "Escape dropped the rectangle");
|
||||
assert_eq!(m.fake.synced(), synced + 1, "the menus were read");
|
||||
assert!(cut, "the preview's rectangle is selected");
|
||||
assert!(dropped, "Escape dropped the rectangle");
|
||||
assert_eq!(escaped, synced + 1, "the menus were read");
|
||||
assert!(!find(&m.fake.last(), "edit.cut").enabled, "nothing is selected");
|
||||
}
|
||||
|
||||
@@ -472,22 +477,26 @@ fn escape_during_a_drag_reads_the_menus() {
|
||||
/// names the step before the drag.
|
||||
#[test]
|
||||
fn a_move_dragged_onto_a_panel_reads_the_menus() {
|
||||
let (mut m, (start, undo, read)) = undisturbed(|m| {
|
||||
// The whole drag, the wait over the panel and the release run undisturbed: a generation bumped
|
||||
// by a test running alongside would read the menus once more.
|
||||
let (m, (undo, read, synced, waits, over, dropped, released)) = undisturbed(|m| {
|
||||
let undo = find(&m.fake.last(), "edit.undo").label.clone();
|
||||
let start = m.start_move();
|
||||
(start, undo, m.reads(4, |_, i| vec![Event::PointerMoved(start + vec2(8.0 * (i + 2) as f32, 0.0))]))
|
||||
let read = m.reads(4, |_, i| vec![Event::PointerMoved(start + vec2(8.0 * (i + 2) as f32, 0.0))]);
|
||||
let synced = m.fake.synced();
|
||||
let panel = Pos2::new(m.app.canvas_rect.unwrap().right() + 40.0, start.y);
|
||||
// Over a panel the move waits: the menus keep the interaction's state.
|
||||
m.frame(vec![Event::PointerMoved(panel)]);
|
||||
let (waits, over) = (m.app.session.in_interaction(), m.fake.synced());
|
||||
// Released over the panel, the move is dropped and the menus are read.
|
||||
m.frame(vec![click(panel, false)]);
|
||||
(undo, read, synced, waits, over, !m.app.session.in_interaction(), m.fake.synced())
|
||||
});
|
||||
assert_eq!(read, 0, "the menus weren't read at any step of the drag");
|
||||
let synced = m.fake.synced();
|
||||
let panel = Pos2::new(m.app.canvas_rect.unwrap().right() + 40.0, start.y);
|
||||
// Over a panel the move waits: the menus keep the interaction's state.
|
||||
m.frame(vec![Event::PointerMoved(panel)]);
|
||||
assert!(m.app.session.in_interaction(), "the move waits over the panel");
|
||||
assert_eq!(m.fake.synced(), synced, "the menus weren't read");
|
||||
// Released over the panel, the move is dropped and the menus are read.
|
||||
m.frame(vec![click(panel, false)]);
|
||||
assert!(!m.app.session.in_interaction(), "the move was dropped");
|
||||
assert_eq!(m.fake.synced(), synced + 1, "the menus were read");
|
||||
assert!(waits, "the move waits over the panel");
|
||||
assert_eq!(over, synced, "the menus weren't read");
|
||||
assert!(dropped, "the move was dropped");
|
||||
assert_eq!(released, synced + 1, "the menus were read");
|
||||
assert_eq!(find(&m.fake.last(), "edit.undo").label, undo);
|
||||
}
|
||||
|
||||
@@ -496,32 +505,34 @@ fn a_move_dragged_onto_a_panel_reads_the_menus() {
|
||||
/// without a release or a key.
|
||||
#[test]
|
||||
fn a_control_port_cancel_of_a_dialog_preview_reads_the_menus() {
|
||||
let (mut m, read) = undisturbed(|m| {
|
||||
let (_m, (read, synced, closed, after)) = undisturbed(|m| {
|
||||
m.rotate_preview();
|
||||
m.angles(4)
|
||||
let read = m.angles(4);
|
||||
let synced = m.fake.synced();
|
||||
crate::tests_synthetic::control(&mut m.app, &m.ctx, "ui.dialog.cancel", json!({}));
|
||||
m.frame(vec![]);
|
||||
(read, synced, !m.app.session.in_interaction() && m.app.ui.dialog.is_none(), m.fake.synced())
|
||||
});
|
||||
assert_eq!(read, 0, "the menus weren't read while the dialog previewed the angles");
|
||||
let synced = m.fake.synced();
|
||||
crate::tests_synthetic::control(&mut m.app, &m.ctx, "ui.dialog.cancel", json!({}));
|
||||
m.frame(vec![]);
|
||||
assert!(!m.app.session.in_interaction() && m.app.ui.dialog.is_none());
|
||||
assert_eq!(m.fake.synced(), synced + 1, "the menus were read");
|
||||
assert!(closed);
|
||||
assert_eq!(after, synced + 1, "the menus were read");
|
||||
}
|
||||
|
||||
/// OK applies the rotation a dialog previews as one undo step: the menus are read then, with Undo
|
||||
/// naming it, and not for the angles previewed before.
|
||||
#[test]
|
||||
fn applying_a_dialog_preview_reads_the_menus() {
|
||||
let (mut m, read) = undisturbed(|m| {
|
||||
let (m, (read, synced, closed, after)) = undisturbed(|m| {
|
||||
m.rotate_preview();
|
||||
m.angles(4)
|
||||
let read = m.angles(4);
|
||||
let synced = m.fake.synced();
|
||||
crate::tests_synthetic::control(&mut m.app, &m.ctx, "ui.dialog.confirm", json!({}));
|
||||
m.frame(vec![]);
|
||||
(read, synced, !m.app.session.in_interaction() && m.app.ui.dialog.is_none(), m.fake.synced())
|
||||
});
|
||||
assert_eq!(read, 0, "the menus weren't read while the dialog previewed the angles");
|
||||
let synced = m.fake.synced();
|
||||
crate::tests_synthetic::control(&mut m.app, &m.ctx, "ui.dialog.confirm", json!({}));
|
||||
m.frame(vec![]);
|
||||
assert!(!m.app.session.in_interaction() && m.app.ui.dialog.is_none());
|
||||
assert_eq!(m.fake.synced(), synced + 1, "the menus were read");
|
||||
assert!(closed);
|
||||
assert_eq!(after, synced + 1, "the menus were read");
|
||||
assert_eq!(find(&m.fake.last(), "edit.undo").label, "Undo Rotate");
|
||||
}
|
||||
|
||||
@@ -538,16 +549,18 @@ fn the_font_menu_preview_reads_the_menus_when_it_ends() {
|
||||
native_menu::sync(&mut m.app, &m.ctx);
|
||||
m.fake.synced() - synced
|
||||
};
|
||||
let (mut m, read) = undisturbed(|m| {
|
||||
let (_m, read) = undisturbed(|m| {
|
||||
m.app.run("select.none", json!({})).unwrap();
|
||||
m.app.run("text.create", json!({"x": 50, "y": 50, "text": "Hi"})).unwrap();
|
||||
m.frame(vec![]);
|
||||
assert_eq!(apply(m, FontPick::Preview("Source Serif 4".into(), None)), 1, "the menus were read as the preview began");
|
||||
apply(m, FontPick::Preview("Source Sans 3".into(), None)) + apply(m, FontPick::Preview("Inter".into(), None))
|
||||
let read = apply(m, FontPick::Preview("Source Sans 3".into(), None)) + apply(m, FontPick::Preview("Inter".into(), None));
|
||||
(read, apply(m, FontPick::EndPreview), !m.app.session.in_interaction())
|
||||
});
|
||||
let (read, ended, done) = read;
|
||||
assert_eq!(read, 0, "the menus weren't read for the fonts after the first");
|
||||
assert_eq!(apply(&mut m, FontPick::EndPreview), 1, "the menus were read as the preview ended");
|
||||
assert!(!m.app.session.in_interaction());
|
||||
assert_eq!(ended, 1, "the menus were read as the preview ended");
|
||||
assert!(done);
|
||||
}
|
||||
|
||||
/// A click runs its command like an in-window click, and the menus follow: View › Show Rulers
|
||||
|
||||
Reference in New Issue
Block a user