-
-
Notifications
You must be signed in to change notification settings - Fork 577
Add tests for auto-panning #2597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
898fd4e
7599eda
ff20fd2
7ea118e
f9a6b17
cc6ebbd
8f24e08
25b18e1
965bed8
1ce786d
5d1f2b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,3 +86,302 @@ impl AutoPanning { | |
Some(delta) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test_auto_panning { | ||
use crate::messages::input_mapper::utility_types::input_mouse::EditorMouseState; | ||
use crate::messages::input_mapper::utility_types::input_mouse::ScrollDelta; | ||
use crate::messages::tool::tool_messages::select_tool::SelectToolPointerKeys; | ||
use crate::test_utils::test_prelude::*; | ||
|
||
#[tokio::test] | ||
async fn test_select_tool_drawing_box_auto_panning() { | ||
let mut editor = EditorTestUtils::create(); | ||
editor.new_document().await; | ||
editor.drag_tool(ToolType::Rectangle, 50., 50., 150., 150., ModifierKeys::empty()).await; | ||
editor.select_tool(ToolType::Select).await; | ||
// Starting selection box inside viewport | ||
editor.left_mousedown(100., 100., ModifierKeys::empty()).await; | ||
// Moving cursor far outside viewport to trigger auto-panning | ||
editor.move_mouse(2000., 100., ModifierKeys::empty(), MouseKeys::LEFT).await; | ||
|
||
let pointer_keys = SelectToolPointerKeys { | ||
axis_align: Key::Shift, | ||
snap_angle: Key::Control, | ||
center: Key::Alt, | ||
duplicate: Key::Alt, | ||
}; | ||
|
||
// Sending multiple pointer outside events to simulate auto-panning over time | ||
for _ in 0..5 { | ||
editor.handle_message(SelectToolMessage::PointerOutsideViewport(pointer_keys.clone())).await; | ||
} | ||
|
||
editor | ||
.mouseup( | ||
EditorMouseState { | ||
editor_position: DVec2::new(2000., 100.), | ||
mouse_keys: MouseKeys::empty(), | ||
scroll_delta: ScrollDelta::default(), | ||
}, | ||
ModifierKeys::empty(), | ||
) | ||
.await; | ||
|
||
let document = editor.active_document(); | ||
let selected_node_count = document.network_interface.selected_nodes().selected_nodes_ref().len(); | ||
assert!(selected_node_count > 0, "Selection should have included at least one object"); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_select_tool_dragging_auto_panning() { | ||
let mut editor = EditorTestUtils::create(); | ||
editor.new_document().await; | ||
editor.drag_tool(ToolType::Rectangle, 50., 50., 150., 150., ModifierKeys::empty()).await; | ||
let layer = editor.active_document().metadata().all_layers().next().unwrap(); | ||
let initial_transform = editor.active_document().metadata().transform_to_viewport(layer); | ||
// Select and start dragging the rectangle | ||
editor.select_tool(ToolType::Select).await; | ||
editor.left_mousedown(100., 100., ModifierKeys::empty()).await; | ||
|
||
// Moving cursor outside viewport to trigger auto-panning | ||
editor.move_mouse(2000., 100., ModifierKeys::empty(), MouseKeys::LEFT).await; | ||
|
||
let pointer_keys = SelectToolPointerKeys { | ||
axis_align: Key::Shift, | ||
snap_angle: Key::Control, | ||
center: Key::Alt, | ||
duplicate: Key::Alt, | ||
}; | ||
|
||
// Sending multiple outside viewport events to simulate continuous auto-panning | ||
for _ in 0..5 { | ||
editor.handle_message(SelectToolMessage::PointerOutsideViewport(pointer_keys.clone())).await; | ||
} | ||
|
||
editor | ||
.mouseup( | ||
EditorMouseState { | ||
editor_position: DVec2::new(2000., 100.), | ||
mouse_keys: MouseKeys::empty(), | ||
scroll_delta: ScrollDelta::default(), | ||
}, | ||
ModifierKeys::empty(), | ||
) | ||
.await; | ||
|
||
// Verifying the rectngle has moved significantly due to auto-panning | ||
let final_transform = editor.active_document().metadata().transform_to_viewport(layer); | ||
let translation_diff = (final_transform.translation - initial_transform.translation).length(); | ||
|
||
assert!(translation_diff > 10., "Rectangle should have moved significantly due to auto-panning (moved by {})", translation_diff); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_select_tool_resizing_auto_panning() { | ||
let mut editor = EditorTestUtils::create(); | ||
editor.new_document().await; | ||
editor.drag_tool(ToolType::Rectangle, 50., 50., 150., 150., ModifierKeys::empty()).await; | ||
let layer = editor.active_document().metadata().all_layers().next().unwrap(); | ||
let initial_transform = editor.active_document().metadata().transform_to_viewport(layer); | ||
|
||
editor.select_tool(ToolType::Select).await; | ||
editor.left_mousedown(150., 150., ModifierKeys::empty()).await; // Click near edge for resize handle | ||
editor | ||
.mouseup( | ||
EditorMouseState { | ||
editor_position: DVec2::new(150., 150.), | ||
mouse_keys: MouseKeys::empty(), | ||
scroll_delta: ScrollDelta::default(), | ||
}, | ||
ModifierKeys::empty(), | ||
) | ||
.await; | ||
|
||
editor.handle_message(TransformLayerMessage::BeginScale).await; | ||
|
||
// Moving cursor to trigger auto-panning | ||
editor.move_mouse(2000., 2000., ModifierKeys::empty(), MouseKeys::LEFT).await; | ||
|
||
let pointer_keys = SelectToolPointerKeys { | ||
axis_align: Key::Shift, | ||
snap_angle: Key::Control, | ||
center: Key::Alt, | ||
duplicate: Key::Alt, | ||
}; | ||
|
||
// Simulatiing auto-panning for several frames | ||
for _ in 0..5 { | ||
editor.handle_message(SelectToolMessage::PointerOutsideViewport(pointer_keys.clone())).await; | ||
} | ||
|
||
editor.handle_message(TransformLayerMessage::ApplyTransformOperation { final_transform: true }).await; | ||
|
||
// Verifying the transform has changed (scale component should be different) | ||
let final_transform = editor.active_document().metadata().transform_to_viewport(layer); | ||
|
||
// Comparing transform matrices to detect scale changes | ||
let initial_scale = initial_transform.matrix2.determinant().sqrt(); | ||
let final_scale = final_transform.matrix2.determinant().sqrt(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have assumed that the scale is uniform. Please justify this in a comment. |
||
let scale_ratio = final_scale / initial_scale; | ||
|
||
assert!( | ||
scale_ratio > 1.1 || scale_ratio < 0.9, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why can you not determine what happens to the scale? Surely the scale should increase. |
||
"Rectangle should have been resized due to auto-panning (scale ratio: {})", | ||
scale_ratio | ||
); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_artboard_tool_drawing_auto_panning() { | ||
let mut editor = EditorTestUtils::create(); | ||
editor.new_document().await; | ||
|
||
editor.select_tool(ToolType::Artboard).await; | ||
editor.left_mousedown(100., 100., ModifierKeys::empty()).await; | ||
|
||
// Moving cursor outside viewport to trigger auto-panning | ||
editor.move_mouse(2000., 100., ModifierKeys::empty(), MouseKeys::LEFT).await; | ||
|
||
// Sending pointer outside event multiple times to simulate auto-panning | ||
for _ in 0..5 { | ||
editor | ||
.handle_message(ArtboardToolMessage::PointerOutsideViewport { | ||
constrain_axis_or_aspect: Key::Shift, | ||
center: Key::Alt, | ||
}) | ||
.await; | ||
} | ||
|
||
editor | ||
.mouseup( | ||
EditorMouseState { | ||
editor_position: DVec2::new(2000., 100.), | ||
mouse_keys: MouseKeys::empty(), | ||
scroll_delta: ScrollDelta::default(), | ||
Comment on lines
+260
to
+261
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can just to |
||
}, | ||
ModifierKeys::empty(), | ||
) | ||
.await; | ||
|
||
// Verifying that an artboard was created with significant width due to auto-panning | ||
let artboards = get_artboards(&mut editor).await; | ||
assert!(!artboards.is_empty(), "Artboard should have been created"); | ||
assert!( | ||
artboards[0].dimensions.x > 200, | ||
"Artboard should have significant width due to auto-panning: {}", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What led you to decide that this was «significant». Please justify in a comment. |
||
artboards[0].dimensions.x | ||
); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_artboard_tool_dragging_auto_panning() { | ||
let mut editor = EditorTestUtils::create(); | ||
editor.new_document().await; | ||
editor.drag_tool(ToolType::Artboard, 50., 50., 150., 150., ModifierKeys::empty()).await; | ||
|
||
let artboards = get_artboards(&mut editor).await; | ||
assert!(!artboards.is_empty(), "Artboard should have been created"); | ||
let initial_location = artboards[0].location; | ||
|
||
editor.select_tool(ToolType::Artboard).await; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Artboard is already selected. |
||
editor.left_mousedown(100., 100., ModifierKeys::empty()).await; | ||
|
||
// Moving cursor outside viewport to trigger auto-panning | ||
editor.move_mouse(2000., 100., ModifierKeys::empty(), MouseKeys::LEFT).await; | ||
|
||
// Sending pointer outside event multiple times to simulate auto-panning | ||
for _ in 0..5 { | ||
editor | ||
.handle_message(ArtboardToolMessage::PointerOutsideViewport { | ||
constrain_axis_or_aspect: Key::Shift, | ||
center: Key::Alt, | ||
}) | ||
.await; | ||
} | ||
|
||
editor | ||
.mouseup( | ||
EditorMouseState { | ||
editor_position: DVec2::new(2000., 100.), | ||
mouse_keys: MouseKeys::empty(), | ||
scroll_delta: ScrollDelta::default(), | ||
}, | ||
ModifierKeys::empty(), | ||
) | ||
.await; | ||
|
||
// Verifying the artboard moved due to auto-panning | ||
let artboards = get_artboards(&mut editor).await; | ||
let final_location = artboards[0].location; | ||
|
||
assert!( | ||
(final_location.x - initial_location.x).abs() > 10 || (final_location.y - initial_location.y).abs() > 10, | ||
"Artboard should have moved significantly due to auto-panning: {:?} -> {:?}", | ||
initial_location, | ||
final_location | ||
); | ||
} | ||
|
||
// This test is marked as ignored due to inconsistent behavior when run as part of the test suite. | ||
// It passes when run individually but frequently fails when run with other tests. | ||
// The issue appears to be related to difficulty consistently capturing resize handles with mouse events | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please elaborate further. |
||
// and unpredictable behavior of auto-panning in the test environment. | ||
// TODO: Implement a more deterministic approach to test artboard resizing with auto-panning. | ||
#[ignore = "Flaky test - passes alone but fails in suite"] | ||
#[tokio::test] | ||
async fn test_artboard_tool_resizing_auto_panning() { | ||
let mut editor = EditorTestUtils::create(); | ||
editor.new_document().await; | ||
editor.drag_tool(ToolType::Artboard, 50., 50., 150., 150., ModifierKeys::empty()).await; | ||
|
||
let artboards = get_artboards(&mut editor).await; | ||
assert!(!artboards.is_empty(), "Artboard should have been created"); | ||
let initial_dimensions = artboards[0].dimensions; | ||
|
||
// Selecting the artboard and click on edge to prepare for resizing | ||
editor.select_tool(ToolType::Artboard).await; | ||
editor.left_mousedown(150., 150., ModifierKeys::empty()).await; | ||
|
||
// Moving cursor outside viewport to trigger auto-panning | ||
editor.move_mouse(2000., 2000., ModifierKeys::empty(), MouseKeys::LEFT).await; | ||
|
||
// Sending pointer outside event multiple times to simulate auto-panning | ||
for _ in 0..5 { | ||
editor | ||
.handle_message(ArtboardToolMessage::PointerOutsideViewport { | ||
constrain_axis_or_aspect: Key::Shift, | ||
center: Key::Alt, | ||
}) | ||
.await; | ||
} | ||
|
||
editor | ||
.mouseup( | ||
EditorMouseState { | ||
editor_position: DVec2::new(2000., 2000.), | ||
mouse_keys: MouseKeys::empty(), | ||
scroll_delta: ScrollDelta::default(), | ||
}, | ||
ModifierKeys::empty(), | ||
) | ||
.await; | ||
|
||
// Verifying the artboard was resized due to auto-panning | ||
let artboards = get_artboards(&mut editor).await; | ||
let final_dimensions = artboards[0].dimensions; | ||
|
||
assert!( | ||
final_dimensions.x > initial_dimensions.x || final_dimensions.y > initial_dimensions.y, | ||
"Artboard should have been resized due to auto-panning: {:?} -> {:?}", | ||
initial_dimensions, | ||
final_dimensions | ||
); | ||
} | ||
|
||
// Helper function to get artboards | ||
async fn get_artboards(editor: &mut EditorTestUtils) -> Vec<graphene_core::Artboard> { | ||
let instrumented = editor.eval_graph().await; | ||
instrumented.grab_all_input::<graphene_core::append_artboard::ArtboardInput>(&editor.runtime).collect() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make a function instead of duplicating so much code.