Skip to content

Commit dd27f46

Browse files
authored
Add tests for GRS transform cancellation (#2467)
* tests for GRS transform cancellation * Added all the tests with not cancelling and cancelling both * remove unnecessary code from gitignore
1 parent 4e418bb commit dd27f46

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed

editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs

+210
Original file line numberDiff line numberDiff line change
@@ -699,3 +699,213 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
699699
common
700700
}
701701
}
702+
703+
#[cfg(test)]
704+
mod test_transform_layer {
705+
use crate::messages::portfolio::document::graph_operation::transform_utils;
706+
use crate::test_utils::test_prelude::*;
707+
// Use ModifyInputsContext to locate the transform node
708+
use crate::messages::portfolio::document::graph_operation::utility_types::ModifyInputsContext;
709+
use crate::messages::prelude::Message;
710+
use glam::DAffine2;
711+
use std::collections::VecDeque;
712+
713+
async fn get_layer_transform(editor: &mut EditorTestUtils, layer: LayerNodeIdentifier) -> Option<DAffine2> {
714+
let document = editor.active_document();
715+
let network_interface = &document.network_interface;
716+
let _responses: VecDeque<Message> = VecDeque::new();
717+
let transform_node_id = ModifyInputsContext::locate_node_in_layer_chain("Transform", layer, network_interface)?;
718+
let document_node = network_interface.document_network().nodes.get(&transform_node_id)?;
719+
Some(transform_utils::get_current_transform(&document_node.inputs))
720+
}
721+
722+
#[tokio::test]
723+
async fn test_grab_apply() {
724+
let mut editor = EditorTestUtils::create();
725+
editor.new_document().await;
726+
727+
editor.drag_tool(ToolType::Rectangle, 0., 0., 100., 100., ModifierKeys::empty()).await;
728+
729+
let document = editor.active_document();
730+
let layer = document.metadata().all_layers().next().unwrap();
731+
732+
let original_transform = get_layer_transform(&mut editor, layer).await.unwrap();
733+
734+
editor.handle_message(TransformLayerMessage::BeginGrab).await;
735+
736+
let translation = DVec2::new(50.0, 50.0);
737+
editor.move_mouse(translation.x, translation.y, ModifierKeys::empty(), MouseKeys::NONE).await;
738+
739+
editor
740+
.handle_message(TransformLayerMessage::PointerMove {
741+
slow_key: Key::Shift,
742+
increments_key: Key::Control,
743+
})
744+
.await;
745+
746+
editor.handle_message(TransformLayerMessage::ApplyTransformOperation { final_transform: true }).await;
747+
748+
let final_transform = get_layer_transform(&mut editor, layer).await.unwrap();
749+
750+
let translation_diff = (final_transform.translation - original_transform.translation).length();
751+
assert!(translation_diff > 10.0, "Transform should have changed after applying transformation. Diff: {}", translation_diff);
752+
}
753+
754+
#[tokio::test]
755+
async fn test_grab_cancel() {
756+
let mut editor = EditorTestUtils::create();
757+
editor.new_document().await;
758+
editor.drag_tool(ToolType::Rectangle, 0., 0., 100., 100., ModifierKeys::empty()).await;
759+
760+
let document = editor.active_document();
761+
let layer = document.metadata().all_layers().next().unwrap();
762+
let original_transform = get_layer_transform(&mut editor, layer).await.expect("Should be able to get the layer transform");
763+
764+
editor.handle_message(TransformLayerMessage::BeginGrab).await;
765+
editor.move_mouse(50.0, 50.0, ModifierKeys::empty(), MouseKeys::NONE).await;
766+
editor
767+
.handle_message(TransformLayerMessage::PointerMove {
768+
slow_key: Key::Shift,
769+
increments_key: Key::Control,
770+
})
771+
.await;
772+
773+
let during_transform = get_layer_transform(&mut editor, layer).await.expect("Should be able to get the layer transform during operation");
774+
775+
assert!(original_transform != during_transform, "Transform should change during operation");
776+
777+
editor.handle_message(TransformLayerMessage::CancelTransformOperation).await;
778+
779+
let final_transform = get_layer_transform(&mut editor, layer).await.expect("Should be able to get the final transform");
780+
let final_translation = final_transform.translation;
781+
let original_translation = original_transform.translation;
782+
783+
// Verify transform is either restored to original OR reset to identity
784+
assert!(
785+
(final_translation - original_translation).length() < 5.0 || final_translation.length() < 0.001,
786+
"Transform neither restored to original nor reset to identity. Original: {:?}, Final: {:?}",
787+
original_translation,
788+
final_translation
789+
);
790+
}
791+
792+
#[tokio::test]
793+
async fn test_rotate_apply() {
794+
let mut editor = EditorTestUtils::create();
795+
editor.new_document().await;
796+
editor.drag_tool(ToolType::Rectangle, 0., 0., 100., 100., ModifierKeys::empty()).await;
797+
798+
let document = editor.active_document();
799+
let layer = document.metadata().all_layers().next().unwrap();
800+
801+
let original_transform = get_layer_transform(&mut editor, layer).await.unwrap();
802+
803+
editor.handle_message(TransformLayerMessage::BeginRotate).await;
804+
805+
editor.move_mouse(150.0, 50.0, ModifierKeys::empty(), MouseKeys::NONE).await;
806+
807+
editor
808+
.handle_message(TransformLayerMessage::PointerMove {
809+
slow_key: Key::Shift,
810+
increments_key: Key::Control,
811+
})
812+
.await;
813+
814+
editor.handle_message(TransformLayerMessage::ApplyTransformOperation { final_transform: true }).await;
815+
816+
let final_transform = get_layer_transform(&mut editor, layer).await.unwrap();
817+
println!("Final transform: {:?}", final_transform);
818+
819+
// Check matrix components have changed (rotation affects matrix2)
820+
let matrix_diff = (final_transform.matrix2.x_axis - original_transform.matrix2.x_axis).length();
821+
assert!(matrix_diff > 0.1, "Rotation should have changed the transform matrix. Diff: {}", matrix_diff);
822+
}
823+
824+
#[tokio::test]
825+
async fn test_rotate_cancel() {
826+
let mut editor = EditorTestUtils::create();
827+
editor.new_document().await;
828+
editor.drag_tool(ToolType::Rectangle, 0., 0., 100., 100., ModifierKeys::empty()).await;
829+
830+
let document = editor.active_document();
831+
let layer = document.metadata().all_layers().next().unwrap();
832+
let original_transform = get_layer_transform(&mut editor, layer).await.unwrap();
833+
834+
editor.handle_message(TransformLayerMessage::BeginRotate).await;
835+
editor.handle_message(TransformLayerMessage::CancelTransformOperation).await;
836+
837+
let after_cancel = get_layer_transform(&mut editor, layer).await.unwrap();
838+
839+
assert!(!after_cancel.translation.x.is_nan(), "Transform is NaN after cancel");
840+
assert!(!after_cancel.translation.y.is_nan(), "Transform is NaN after cancel");
841+
842+
let translation_diff = (after_cancel.translation - original_transform.translation).length();
843+
assert!(translation_diff < 1.0, "Translation component changed too much: {}", translation_diff);
844+
}
845+
846+
#[tokio::test]
847+
async fn test_scale_apply() {
848+
let mut editor = EditorTestUtils::create();
849+
editor.new_document().await;
850+
editor.drag_tool(ToolType::Rectangle, 0., 0., 100., 100., ModifierKeys::empty()).await;
851+
852+
let document = editor.active_document();
853+
let layer = document.metadata().all_layers().next().unwrap();
854+
855+
let original_transform = get_layer_transform(&mut editor, layer).await.unwrap();
856+
857+
editor.handle_message(TransformLayerMessage::BeginScale).await;
858+
859+
editor.move_mouse(150.0, 150.0, ModifierKeys::empty(), MouseKeys::NONE).await;
860+
861+
editor
862+
.handle_message(TransformLayerMessage::PointerMove {
863+
slow_key: Key::Shift,
864+
increments_key: Key::Control,
865+
})
866+
.await;
867+
868+
editor.handle_message(TransformLayerMessage::ApplyTransformOperation { final_transform: true }).await;
869+
870+
let final_transform = get_layer_transform(&mut editor, layer).await.unwrap();
871+
872+
// Check scaling components have changed
873+
let scale_diff_x = (final_transform.matrix2.x_axis.x - original_transform.matrix2.x_axis.x).abs();
874+
let scale_diff_y = (final_transform.matrix2.y_axis.y - original_transform.matrix2.y_axis.y).abs();
875+
876+
assert!(
877+
scale_diff_x > 0.1 || scale_diff_y > 0.1,
878+
"Scaling should have changed the transform matrix. Diffs: x={}, y={}",
879+
scale_diff_x,
880+
scale_diff_y
881+
);
882+
}
883+
884+
#[tokio::test]
885+
async fn test_scale_cancel() {
886+
let mut editor = EditorTestUtils::create();
887+
editor.new_document().await;
888+
editor.drag_tool(ToolType::Rectangle, 0., 0., 100., 100., ModifierKeys::empty()).await;
889+
890+
let document = editor.active_document();
891+
let layer = document.metadata().all_layers().next().unwrap();
892+
let original_transform = get_layer_transform(&mut editor, layer).await.unwrap();
893+
894+
editor.handle_message(TransformLayerMessage::BeginScale).await;
895+
896+
// Cancel immediately without moving to ensure proper reset
897+
editor.handle_message(TransformLayerMessage::CancelTransformOperation).await;
898+
899+
let after_cancel = get_layer_transform(&mut editor, layer).await.unwrap();
900+
901+
// The scale factor is represented in the matrix2 part, so check those components
902+
assert!(
903+
(after_cancel.matrix2.x_axis.x - original_transform.matrix2.x_axis.x).abs() < 0.1 && (after_cancel.matrix2.y_axis.y - original_transform.matrix2.y_axis.y).abs() < 0.1,
904+
"Matrix scale components should be restored after cancellation"
905+
);
906+
907+
// Also check translation component is similar
908+
let translation_diff = (after_cancel.translation - original_transform.translation).length();
909+
assert!(translation_diff < 1.0, "Translation component changed too much: {}", translation_diff);
910+
}
911+
}

0 commit comments

Comments
 (0)