Skip to content

Commit 2dee47a

Browse files
authored
Add Spline tool test for drawing with PTZ applied to the canvas view (#2573)
* Adding tests for spline PTZ * Some refactoring * Feedback applied from James * Unnecessary changes * refactor with current merged pr * Code refactoring based on guidelines * cli failing
1 parent e60a9c3 commit 2dee47a

File tree

4 files changed

+211
-52
lines changed

4 files changed

+211
-52
lines changed

editor/src/messages/portfolio/document/document_message_handler.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -2800,7 +2800,7 @@ mod document_message_handler_tests {
28002800
let document = editor.active_document();
28012801
for layer in document.metadata().all_layers() {
28022802
if let Some(bbox) = document.metadata().bounding_box_viewport(layer) {
2803-
if (bbox[0].x - min_x).abs() < 1.0 && (bbox[0].y - min_y).abs() < 1.0 {
2803+
if (bbox[0].x - min_x).abs() < 1. && (bbox[0].y - min_y).abs() < 1. {
28042804
return Some(layer);
28052805
}
28062806
}
@@ -2814,8 +2814,8 @@ mod document_message_handler_tests {
28142814
parent.children(document.metadata()).position(|child| child == layer)
28152815
}
28162816

2817-
let layer_middle = get_layer_by_bounds(&mut editor, 50.0, 50.0).await.unwrap();
2818-
let layer_top = get_layer_by_bounds(&mut editor, 100.0, 100.0).await.unwrap();
2817+
let layer_middle = get_layer_by_bounds(&mut editor, 50., 50.).await.unwrap();
2818+
let layer_top = get_layer_by_bounds(&mut editor, 100., 100.).await.unwrap();
28192819

28202820
let initial_index_top = get_layer_index(&mut editor, layer_top).await.unwrap();
28212821
let initial_index_middle = get_layer_index(&mut editor, layer_middle).await.unwrap();
@@ -2915,7 +2915,7 @@ mod document_message_handler_tests {
29152915
// Applying transform to folder1 (translation)
29162916
editor.handle_message(NodeGraphMessage::SelectedNodesSet { nodes: vec![folder1.to_node()] }).await;
29172917
editor.handle_message(TransformLayerMessage::BeginGrab).await;
2918-
editor.move_mouse(100.0, 50.0, ModifierKeys::empty(), MouseKeys::NONE).await;
2918+
editor.move_mouse(100., 50., ModifierKeys::empty(), MouseKeys::NONE).await;
29192919
editor
29202920
.handle_message(TransformLayerMessage::PointerMove {
29212921
slow_key: Key::Shift,
@@ -2927,7 +2927,7 @@ mod document_message_handler_tests {
29272927
// Applying different transform to folder2 (translation)
29282928
editor.handle_message(NodeGraphMessage::SelectedNodesSet { nodes: vec![folder2.to_node()] }).await;
29292929
editor.handle_message(TransformLayerMessage::BeginGrab).await;
2930-
editor.move_mouse(200.0, 100.0, ModifierKeys::empty(), MouseKeys::NONE).await;
2930+
editor.move_mouse(200., 100., ModifierKeys::empty(), MouseKeys::NONE).await;
29312931
editor
29322932
.handle_message(TransformLayerMessage::PointerMove {
29332933
slow_key: Key::Shift,
@@ -2946,7 +2946,7 @@ mod document_message_handler_tests {
29462946
editor.handle_message(DocumentMessage::MoveSelectedLayersTo { parent: folder1, insert_index: 0 }).await;
29472947

29482948
editor.handle_message(TransformLayerMessage::BeginGrab).await;
2949-
editor.move_mouse(50.0, 25.0, ModifierKeys::empty(), MouseKeys::NONE).await;
2949+
editor.move_mouse(50., 25., ModifierKeys::empty(), MouseKeys::NONE).await;
29502950
editor
29512951
.handle_message(TransformLayerMessage::PointerMove {
29522952
slow_key: Key::Shift,
@@ -2967,10 +2967,10 @@ mod document_message_handler_tests {
29672967
let rect_bbox_after = document.metadata().bounding_box_viewport(rect_layer).unwrap();
29682968

29692969
// Verifing the rectangle maintains approximately the same position in viewport space
2970-
let before_center = (rect_bbox_before[0] + rect_bbox_before[1]) / 2.0;
2971-
let after_center = (rect_bbox_after[0] + rect_bbox_after[1]) / 2.0;
2970+
let before_center = (rect_bbox_before[0] + rect_bbox_before[1]) / 2.;
2971+
let after_center = (rect_bbox_after[0] + rect_bbox_after[1]) / 2.;
29722972
let distance = before_center.distance(after_center);
29732973

2974-
assert!(distance < 1.0, "Rectangle should maintain its viewport position after moving between transformed groups");
2974+
assert!(distance < 1., "Rectangle should maintain its viewport position after moving between transformed groups");
29752975
}
29762976
}

editor/src/messages/tool/tool_messages/line_tool.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,8 @@ mod test_line_tool {
462462
if let Some((start_input, end_input)) = get_line_node_inputs(&mut editor).await {
463463
match (start_input, end_input) {
464464
(start_input, end_input) => {
465-
assert!((start_input - DVec2::ZERO).length() < 1.0, "Start point should be near (0,0)");
466-
assert!((end_input - DVec2::new(100.0, 100.0)).length() < 1.0, "End point should be near (100,100)");
465+
assert!((start_input - DVec2::ZERO).length() < 1., "Start point should be near (0,0)");
466+
assert!((end_input - DVec2::new(100., 100.)).length() < 1., "End point should be near (100,100)");
467467
}
468468
}
469469
}
@@ -473,26 +473,30 @@ mod test_line_tool {
473473
async fn test_line_tool_with_transformed_viewport() {
474474
let mut editor = EditorTestUtils::create();
475475
editor.new_document().await;
476-
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 2.0 }).await;
477-
editor.handle_message(NavigationMessage::CanvasPan { delta: DVec2::new(100.0, 50.0) }).await;
478-
editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 30.0_f64.to_radians() }).await;
476+
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 2. }).await;
477+
editor.handle_message(NavigationMessage::CanvasPan { delta: DVec2::new(100., 50.) }).await;
478+
editor
479+
.handle_message(NavigationMessage::CanvasTiltSet {
480+
angle_radians: (30. as f64).to_radians(),
481+
})
482+
.await;
479483
editor.drag_tool(ToolType::Line, 0., 0., 100., 100., ModifierKeys::empty()).await;
480484
if let Some((start_input, end_input)) = get_line_node_inputs(&mut editor).await {
481485
let document = editor.active_document();
482486
let document_to_viewport = document.metadata().document_to_viewport;
483487
let viewport_to_document = document_to_viewport.inverse();
484488

485489
let expected_start = viewport_to_document.transform_point2(DVec2::ZERO);
486-
let expected_end = viewport_to_document.transform_point2(DVec2::new(100.0, 100.0));
490+
let expected_end = viewport_to_document.transform_point2(DVec2::new(100., 100.));
487491

488492
assert!(
489-
(start_input - expected_start).length() < 1.0,
493+
(start_input - expected_start).length() < 1.,
490494
"Start point should match expected document coordinates. Got {:?}, expected {:?}",
491495
start_input,
492496
expected_start
493497
);
494498
assert!(
495-
(end_input - expected_end).length() < 1.0,
499+
(end_input - expected_end).length() < 1.,
496500
"End point should match expected document coordinates. Got {:?}, expected {:?}",
497501
end_input,
498502
expected_end
@@ -519,7 +523,7 @@ mod test_line_tool {
519523
let updated_line_vec = updated_end - updated_start;
520524
let updated_angle = updated_line_vec.angle_to(DVec2::X);
521525
assert!((original_angle - updated_angle).abs() < 0.1, "Line angle should be locked when Ctrl is kept pressed");
522-
assert!((updated_start - updated_end).length() > 1.0, "Line should be able to change length when Ctrl is kept pressed");
526+
assert!((updated_start - updated_end).length() > 1., "Line should be able to change length when Ctrl is kept pressed");
523527
}
524528
}
525529
}
@@ -538,8 +542,8 @@ mod test_line_tool {
538542
(start_input, end_input) => {
539543
let expected_start = DVec2::new(0., 100.);
540544
let expected_end = DVec2::new(200., 100.);
541-
assert!((start_input - expected_start).length() < 1.0, "start point should be near (0,100)");
542-
assert!((end_input - expected_end).length() < 1.0, "end point should be near (200,100)");
545+
assert!((start_input - expected_start).length() < 1., "start point should be near (0,100)");
546+
assert!((end_input - expected_end).length() < 1., "end point should be near (200,100)");
543547
}
544548
}
545549
}
@@ -556,9 +560,9 @@ mod test_line_tool {
556560
let line_vec = end_input - start_input;
557561
let angle_radians = line_vec.angle_to(DVec2::X);
558562
let angle_degrees = angle_radians.to_degrees();
559-
let nearest_angle = (angle_degrees / 15.0).round() * 15.0;
563+
let nearest_angle = (angle_degrees / 15.).round() * 15.;
560564

561-
assert!((angle_degrees - nearest_angle).abs() < 1.0, "Angle should snap to the nearest 15 degrees");
565+
assert!((angle_degrees - nearest_angle).abs() < 1., "Angle should snap to the nearest 15 degrees");
562566
}
563567
}
564568
}

editor/src/messages/tool/tool_messages/spline_tool.rs

+151
Original file line numberDiff line numberDiff line change
@@ -648,4 +648,155 @@ mod test_spline_tool {
648648

649649
assert_point_positions(&extended_vector_data, layer_to_viewport, &all_expected_points, 1e-10);
650650
}
651+
652+
#[tokio::test]
653+
async fn test_spline_with_zoomed_view() {
654+
let mut editor = EditorTestUtils::create();
655+
editor.new_document().await;
656+
657+
// Zooming the viewport
658+
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 2.0 }).await;
659+
660+
// Selecting the spline tool
661+
editor.select_tool(ToolType::Spline).await;
662+
663+
// Adding points by clicking at different positions
664+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50.0, 50.0), ModifierKeys::empty()).await;
665+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100.0, 50.0), ModifierKeys::empty()).await;
666+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150.0, 100.0), ModifierKeys::empty()).await;
667+
668+
// Finish the spline
669+
editor.handle_message(SplineToolMessage::Confirm).await;
670+
671+
// Evaluate the graph to ensure everything is processed
672+
editor.eval_graph().await;
673+
674+
// Get the layer and vector data
675+
let document = editor.active_document();
676+
let network_interface = &document.network_interface;
677+
let layer = network_interface
678+
.selected_nodes()
679+
.selected_visible_and_unlocked_layers(network_interface)
680+
.next()
681+
.expect("Should have a selected layer");
682+
let vector_data = network_interface.compute_modified_vector(layer).expect("Should have vector data");
683+
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
684+
685+
// Expected points in viewport coordinates
686+
let expected_points = vec![DVec2::new(50.0, 50.0), DVec2::new(100.0, 50.0), DVec2::new(150.0, 100.0)];
687+
688+
// Assert all points are correctly positioned
689+
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
690+
}
691+
692+
#[tokio::test]
693+
async fn test_spline_with_panned_view() {
694+
let mut editor = EditorTestUtils::create();
695+
editor.new_document().await;
696+
697+
let pan_amount = DVec2::new(200.0, 150.0);
698+
editor.handle_message(NavigationMessage::CanvasPan { delta: pan_amount }).await;
699+
700+
editor.select_tool(ToolType::Spline).await;
701+
702+
// Add points by clicking at different positions
703+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50.0, 50.0), ModifierKeys::empty()).await;
704+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100.0, 50.0), ModifierKeys::empty()).await;
705+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150.0, 100.0), ModifierKeys::empty()).await;
706+
707+
editor.handle_message(SplineToolMessage::Confirm).await;
708+
709+
// Evaluating the graph to ensure everything is processed
710+
editor.eval_graph().await;
711+
712+
// Get the layer and vector data
713+
let document = editor.active_document();
714+
let network_interface = &document.network_interface;
715+
let layer = network_interface
716+
.selected_nodes()
717+
.selected_visible_and_unlocked_layers(network_interface)
718+
.next()
719+
.expect("Should have a selected layer");
720+
let vector_data = network_interface.compute_modified_vector(layer).expect("Should have vector data");
721+
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
722+
723+
// Expected points in viewport coordinates
724+
let expected_points = vec![DVec2::new(50.0, 50.0), DVec2::new(100.0, 50.0), DVec2::new(150.0, 100.0)];
725+
726+
// Assert all points are correctly positioned
727+
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
728+
}
729+
730+
#[tokio::test]
731+
async fn test_spline_with_tilted_view() {
732+
let mut editor = EditorTestUtils::create();
733+
editor.new_document().await;
734+
735+
// Tilt/rotate the viewport (45 degrees)
736+
editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 45.0_f64.to_radians() }).await;
737+
editor.select_tool(ToolType::Spline).await;
738+
739+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50.0, 50.0), ModifierKeys::empty()).await;
740+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100.0, 50.0), ModifierKeys::empty()).await;
741+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150.0, 100.0), ModifierKeys::empty()).await;
742+
743+
editor.handle_message(SplineToolMessage::Confirm).await;
744+
745+
// Evaluating the graph to ensure everything is processed
746+
editor.eval_graph().await;
747+
748+
// Get the layer and vector data
749+
let document = editor.active_document();
750+
let network_interface = &document.network_interface;
751+
let layer = network_interface
752+
.selected_nodes()
753+
.selected_visible_and_unlocked_layers(network_interface)
754+
.next()
755+
.expect("Should have a selected layer");
756+
let vector_data = network_interface.compute_modified_vector(layer).expect("Should have vector data");
757+
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
758+
759+
// Expected points in viewport coordinates
760+
let expected_points = vec![DVec2::new(50.0, 50.0), DVec2::new(100.0, 50.0), DVec2::new(150.0, 100.0)];
761+
762+
// Assert all points are correctly positioned
763+
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
764+
}
765+
766+
#[tokio::test]
767+
async fn test_spline_with_combined_transformations() {
768+
let mut editor = EditorTestUtils::create();
769+
editor.new_document().await;
770+
771+
// Applying multiple transformations
772+
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 1.5 }).await;
773+
editor.handle_message(NavigationMessage::CanvasPan { delta: DVec2::new(100.0, 75.0) }).await;
774+
editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 30.0_f64.to_radians() }).await;
775+
776+
editor.select_tool(ToolType::Spline).await;
777+
778+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50.0, 50.0), ModifierKeys::empty()).await;
779+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100.0, 50.0), ModifierKeys::empty()).await;
780+
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150.0, 100.0), ModifierKeys::empty()).await;
781+
782+
editor.handle_message(SplineToolMessage::Confirm).await;
783+
editor.eval_graph().await;
784+
785+
// Get the layer and vector data
786+
let document = editor.active_document();
787+
let network_interface = &document.network_interface;
788+
let layer = network_interface
789+
.selected_nodes()
790+
.selected_visible_and_unlocked_layers(network_interface)
791+
.next()
792+
.expect("Should have a selected layer");
793+
let vector_data = network_interface.compute_modified_vector(layer).expect("Should have vector data");
794+
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
795+
796+
// Expected points in viewport coordinates
797+
let expected_points = vec![DVec2::new(50.0, 50.0), DVec2::new(100.0, 50.0), DVec2::new(150.0, 100.0)];
798+
799+
// Assert all points are correctly positioned
800+
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
801+
}
651802
}

0 commit comments

Comments
 (0)