penpot/frontend/test/frontend_tests/logic/path_test_helpers.cljs
Alonso Torres 217284b1e1
Improve path operations and edition (#10807)
*  Improve path operations and edition

* 🐛 Fix floating-point equality issues in path editing

Replace exact equality checks with tolerance-based comparisons
in path editing functions to handle floating-point rounding
differences after transforms, rotations, or curve fitting.

Changes:
- distribute-content: Round coordinates to 0.1 precision before
  grouping to ensure coincident nodes move together
- separate-node: Use gpt/close? instead of exact equality to
  find nodes with floating-point imprecision
- collision-step: Use mth/close? for tolerance-based comparison
  to detect paste collisions correctly
- resolve-edit-fills: Add cycle detection to prevent infinite
  loops with corrupted parent chains

Made collision-step, available-offset-step, and resolve-edit-fills
public for better testability.

Added comprehensive tests for all fixes covering both exact and
floating-point coordinate scenarios.

AI-assisted-by: qwen3.7-plus

* 🐛 Fix path editor code review findings

Fix issues identified during code review of path editor enhancements:

- Fix unused binding lint warning in distribute-content that blocked CI
- Fix collision-step floor comparison to use round instead of floor,
  correctly detecting collisions when coordinates drift slightly below
  integer boundaries
- Fix resolve-edit-fills to recurse through empty parent groups when
  searching for inherited fills in nested group hierarchies
- Fix expand-coincident-node-indices to use fuzzy comparison (gpt/close?)
  instead of exact equality, handling floating-point divergence after
  transforms or rotations
- Remove unreachable dead code in path-point* on-pointer-down handler
- Add tests for collision-step boundary cases, nested group fill
  inheritance, and coincident node alignment/flipping

AI-assisted-by: mimo-v2.5-pro

---------

Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-08-27 10:51:10 +02:00

95 lines
2.5 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC Sucursal en España SL
(ns frontend-tests.logic.path-test-helpers
(:require
[app.common.test-helpers.compositions :as ctho]
[app.common.test-helpers.files :as cthf]
[app.common.test-helpers.shapes :as cths]
[app.common.types.path :as path]
[app.main.data.workspace.edition :as dwe]
[app.main.data.workspace.path.edition :as path.edition]
[app.main.data.workspace.path.state :as path.state]))
(defn setup-rect-file
[]
(ctho/add-rect (cthf/sample-file :file1)
:rect1
:x 10
:y 20
:width 100
:height 80))
(defn start-path-edition-events
[id]
[(dwe/start-edition-mode id)
(path.edition/start-path-edit id)])
(defn move-drawing-content
[delta]
(fn [state]
(path.state/set-content
state
(path/move-content (path.state/get-path state :content) delta))))
(defn drawing-path-state
[]
(let [file (setup-rect-file)
shape (-> (cths/get-shape file :rect1)
(path/convert-to-path))]
{:workspace-drawing {:object shape}}))
(defn selectable-path-content
[]
(path/content
[{:command :move-to
:params {:x 0 :y 0}}
{:command :curve-to
:params {:c1x 2 :c1y 0
:c2x 8 :c2y 0
:x 10 :y 0}}
{:command :curve-to
:params {:c1x 12 :c1y 0
:c2x 18 :c2y 0
:x 20 :y 0}}]))
(defn selectable-path-state
[id content selection]
{:workspace-local {:edition id
:edit-path {id {:selection selection}}}
:workspace-drawing {:object {:id id
:type :path
:content content}}})
(defn mixed-corner-curve-content
[]
(path/content
[{:command :move-to
:params {:x 0 :y 0}}
{:command :line-to
:params {:x 10 :y 0}}
{:command :curve-to
:params {:c1x 12 :c1y 4
:c2x 18 :c2y 4
:x 20 :y 0}}]))
(defn corner-path-content
"Returns selectable content with a corner at `(10, 0)`."
[]
(path/content
[{:command :move-to
:params {:x 0 :y 0}}
{:command :curve-to
:params {:c1x 2 :c1y 0
:c2x 8 :c2y 0
:x 10 :y 0}}
{:command :curve-to
:params {:c1x 12 :c1y 6
:c2x 18 :c2y 0
:x 20 :y 0}}]))