Skip to content
Open
73 changes: 73 additions & 0 deletions editor/src/messages/tool/tool_messages/pen_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2498,6 +2498,79 @@ mod test_pen_tool {
const C: DVec2 = DVec2::new(200., 200.);
const D: DVec2 = DVec2::new(100., 200.);

async fn create_a_rectangle() -> EditorTestUtils {
let mut editor = EditorTestUtils::create();

editor.new_document().await;

editor.select_primary_color(Color::RED).await;
// Draw a rectangle not at the origin (so will end up with a non-identity transform)
editor.draw_rect(A.x, A.y, C.x, C.y).await;

editor
}

/// Using the path tool to merge layers (by setting the endpoint to an anchor of another layer) should produce only expected anchor positions.
#[tokio::test]
async fn merging_layers_simple() {
let mut editor = create_a_rectangle().await;

// Start the pen somewhere random
let pen_start = DVec2::new(999., 999.);
click_pen(&mut editor, pen_start).await;
// Connect to the top right of the rectangle
click_pen(&mut editor, B).await;

// Validate that these anchors are the only ones that exist (TODO: improve code reuse)
let expected_anchors = [A, B, C, D, pen_start];
let (layer, vector) = drawn_path(&editor).expect("Expected a drawn path");
let layer_to_viewport = editor.active_document().metadata().transform_to_viewport(layer);
let mut viewport_points: Vec<DVec2> = vector.point_domain.positions().iter().map(|&pos| layer_to_viewport.transform_point2(pos)).collect();

for (expected_index, &expected_position) in expected_anchors.iter().enumerate() {
let Some(viewport_index) = viewport_points.iter().position(|viewport| viewport.distance_squared(expected_position) < 1e-10) else {
panic!("The expected anchor index {expected_index} and position {expected_position} was not found in the actual anchors {viewport_points:?}");
};
println!("Successfully found expected position {expected_position} (index {expected_index}) in viewport points as index {viewport_index}");
// Remove so no other one matches
viewport_points.remove(viewport_index);
}
assert!(viewport_points.is_empty(), "Viewport point(s) were not matched: {viewport_points:?}");
}

#[tokio::test]
async fn merging_two_pen_paths() {
let mut editor = EditorTestUtils::create();
editor.new_document().await;

// Create First Pen path
click_pen(&mut editor, A).await;
click_pen(&mut editor, C).await;

// Abort the first pen process
editor.handle_message(ToolMessage::Pen(PenToolMessage::Abort)).await;

// Create a second pen stroke
click_pen(&mut editor, B).await;
click_pen(&mut editor, C).await;

// Validate that these anchors are the only ones that exist (TODO: improve code reuse)
let expected_anchors = [A, B, C];
let (layer, vector) = drawn_path(&editor).expect("Expected a drawn path");
let layer_to_viewport = editor.active_document().metadata().transform_to_viewport(layer);
let mut viewport_points: Vec<DVec2> = vector.point_domain.positions().iter().map(|&pos| layer_to_viewport.transform_point2(pos)).collect();

for (expected_index, &expected_position) in expected_anchors.iter().enumerate() {
let Some(viewport_index) = viewport_points.iter().position(|viewport| viewport.distance_squared(expected_position) < 1e-10) else {
panic!("The expected anchor index {expected_index} and position {expected_position} was not found in the actual anchors {viewport_points:?}");
};
println!("Successfully found expected position {expected_position} (index {expected_index}) in viewport points as index {viewport_index}");
// Remove so no other one matches
viewport_points.remove(viewport_index);
}
assert!(viewport_points.is_empty(), "Viewport point(s) were not matched: {viewport_points:?}");
}

#[tokio::test]
async fn each_segment_and_the_closing_click_are_their_own_history_steps() {
let mut editor = EditorTestUtils::create();
Expand Down