From ded22f432c2da2f724119f3b1f6165e25469b780 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sun, 25 Oct 2026 15:47:56 -0700 Subject: [PATCH] Tests: the Paintbrush closing cursor follows the point a release keeps The Paintbrush drops a sample less than a pixel from the last kept point, and a release there keeps that point. The new test moves the pointer inside Close Paths When Ends Are Within while the kept point stays outside it, and checks that the cursor shows no closing ring and that the release leaves the path open. --- crates/tools/src/draw2/gesture.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/crates/tools/src/draw2/gesture.rs b/crates/tools/src/draw2/gesture.rs index 8133515db..859f697ca 100644 --- a/crates/tools/src/draw2/gesture.rs +++ b/crates/tools/src/draw2/gesture.rs @@ -1282,6 +1282,31 @@ mod tests { } } + /// A Paintbrush sample under a pixel from the last point is dropped, and a release there keeps + /// the last point: the closing cursor follows that point, not the pointer. + #[test] + fn the_paintbrush_closing_cursor_follows_the_point_a_release_keeps() { + let (d, _) = doc_with_rect(); + let s = Selection::default(); + let p = paint(); + let cx = cx(&d, &s, &p); + let none = Mods::default(); + let mut t = GestureTool::new("paintbrush"); + t.set_option("closeWithin", &json!(15.0)); + for (k, x, y) in [(PointerKind::Down, 310.0, 330.0), (PointerKind::Drag, 360.0, 350.0), (PointerKind::Drag, 330.0, 390.0)] { + t.pointer(&cx, &PointerEvent::new(k, x, y)); + } + // The last point kept is 15.5 from the start, outside Close Paths When Ends Are Within. + t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 325.5, 330.0)); + assert_eq!(t.cursor(&cx, Point::new(325.5, 330.0), none), Cursor::Paintbrush, "outside the closing distance"); + // The pointer moves 0.7 to 14.8 from the start; the sample is dropped. + t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 324.8, 330.0)); + assert_eq!(t.cursor(&cx, Point::new(324.8, 330.0), none), Cursor::Paintbrush, "the dropped sample shows no ring"); + let acts = t.pointer(&cx, &PointerEvent::new(PointerKind::Up, 324.8, 330.0)); + let Some(Action::Preview(_, v)) = acts.first() else { panic!("{acts:?}") }; + assert_eq!(v["closed"], json!(false), "the release keeps the last point and leaves the path open"); + } + #[test] fn eraser_and_knife_exec_on_release() { let (d, _) = doc_with_rect();