Repository: GraphiteEditor/Graphite
File: editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs (Rust)

Code before:

		// Rotate the document view (45 degrees)
		editor.handle_message(NavigationMessage::BeginCanvasTilt { was_dispatched_from_menu: false }).await;
		editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 45.0_f64.to_radians() }).await;
		editor.handle_message(TransformLayerMessage::BeginRotate).await;

		editor.handle_message(TransformLayerMessage::TypeDigit { digit: 9 }).await;
		editor.handle_message(TransformLayerMessage::TypeDigit { digit: 0 }).await;
		editor.handle_message(TransformLayerMessage::ApplyTransformOperation { final_transform: true }).await;

		let final_transform = get_layer_transform(&mut editor, layer).await.unwrap();

		let original_angle = original_transform.to_scale_angle_translation().1;
		let final_angle = final_transform.to_scale_angle_translation().1;
		let angle_change = (final_angle - original_angle).to_degrees();

		// Normalize angle between 0 and 360
		let angle_change = ((angle_change % 360.0) + 360.0) % 360.0;
		assert!((angle_change - 90.0).abs() < 0.1, "Expected rotation of 90 degrees, got: {}", angle_change);
	}

	#[tokio::test]
	async fn test_grs_single_anchor() {
		let mut editor = EditorTestUtils::create();
		editor.new_document().await;
		editor.drag_tool(ToolType::Rectangle, 100., 100., 200., 200., ModifierKeys::empty()).await;
		let document = editor.active_document();
		let layer = document.metadata().all_layers().next().unwrap();

		let modification_type = VectorModificationType::InsertPoint {
			id: PointId::generate(),
			position: DVec2::ZERO,
		};
		editor.handle_message(GraphOperationMessage::Vector { layer, modification_type }).await;
		editor.handle_message(ToolMessage::ActivateTool { tool_type: ToolType::Select }).await;

		// Testing grab operation - just checking that it doesn't crash
		editor.handle_message(TransformLayerMessage::BeginGrab).await;
		editor.move_mouse(150.0, 150.0, ModifierKeys::empty(), MouseKeys::NONE).await;
		editor
			.handle_message(TransformLayerMessage::PointerMove {
				slow_key: Key::Shift,
				increments_key: Key::Control,
			})
			.await;
		editor.handle_message(TransformLayerMessage::ApplyTransformOperation { final_transform: true }).await;

		let final_transform = get_layer_transform(&mut editor, layer).await;
		// Verifying a transform node was created
		assert!(final_transform.is_some(), "Transform node should exist after grab operation");
	}

Review comment (suggestion):
Since you've created a rectangle, this will have 4 points already.

You can create an empty layer with no points using `DocumentMessage::CreateEmptyFolder` (a folder is the same as a layer).

Code after:
		editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 45.0_f64.to_radians() }).await;
		editor.handle_message(TransformLayerMessage::BeginRotate).await;

		editor.handle_message(TransformLayerMessage::TypeDigit { digit: 9 }).await;
		editor.handle_message(TransformLayerMessage::TypeDigit { digit: 0 }).await;
		editor.handle_message(TransformLayerMessage::ApplyTransformOperation { final_transform: true }).await;

		let final_transform = get_layer_transform(&mut editor, layer).await.unwrap();

		let original_angle = original_transform.to_scale_angle_translation().1;
		let final_angle = final_transform.to_scale_angle_translation().1;
		let angle_change = (final_angle - original_angle).to_degrees();

		// Normalize angle between 0 and 360
		let angle_change = ((angle_change % 360.0) + 360.0) % 360.0;
		assert!((angle_change - 90.0).abs() < 0.1, "Expected rotation of 90 degrees, got: {}", angle_change);
	}

	#[tokio::test]
	async fn test_grs_single_anchor() {
		let mut editor = EditorTestUtils::create();
		editor.new_document().await;
		editor.handle_message(DocumentMessage::CreateEmptyFolder).await;
		let document = editor.active_document();
		let layer = document.metadata().all_layers().next().unwrap();

		let point_id = PointId::generate();
		let modification_type = VectorModificationType::InsertPoint {
			id: point_id,
			position: DVec2::new(100.0, 100.0),
		};
		editor.handle_message(GraphOperationMessage::Vector { layer, modification_type }).await;
		editor.handle_message(ToolMessage::ActivateTool { tool_type: ToolType::Select }).await;

		// Testing grab operation - just checking that it doesn't crash.
		editor.handle_message(TransformLayerMessage::BeginGrab).await;
		editor.move_mouse(150.0, 150.0, ModifierKeys::empty(), MouseKeys::NONE).await;
		editor
			.handle_message(TransformLayerMessage::PointerMove {
				slow_key: Key::Shift,
				increments_key: Key::Control,
			})
			.await;
		editor.handle_message(TransformLayerMessage::ApplyTransformOperation { final_transform: true }).await;

		let final_transform = get_layer_transform(&mut editor, layer).await;
		assert!(final_transform.is_some(), "Transform node should exist after grab operation");
	}
}