diff --git a/common/src/app/common/files/libraries_helpers.cljc b/common/src/app/common/files/libraries_helpers.cljc index 2aceb35fdd..9ac32219fc 100644 --- a/common/src/app/common/files/libraries_helpers.cljc +++ b/common/src/app/common/files/libraries_helpers.cljc @@ -34,6 +34,23 @@ ;; Change this to :info :debug or :trace to debug this module, or :warn to reset to default (log/set-level! :warn) +(defn generate-update-shapes + [changes ids update-fn objects {:keys [attrs ignore-tree ignore-touched with-objects?]}] + (let [changes (reduce + (fn [changes id] + (let [opts {:attrs attrs + :ignore-geometry? (get ignore-tree id) + :ignore-touched ignore-touched + :with-objects? with-objects?}] + (pcb/update-shapes changes [id] update-fn (d/without-nils opts)))) + (-> changes + (pcb/with-objects objects)) + ids) + grid-ids (->> ids (filter (partial ctl/grid-layout? objects))) + changes (pcb/update-shapes changes grid-ids ctl/assign-cell-positions {:with-objects? true}) + changes (pcb/reorder-grid-children changes ids)] + changes)) + (declare generate-sync-container) (declare generate-sync-shape) (declare generate-sync-text-shape) diff --git a/common/test/common_tests/helpers/compositions.cljc b/common/test/common_tests/helpers/compositions.cljc index e28526ee67..d8b9cbe8b2 100644 --- a/common/test/common_tests/helpers/compositions.cljc +++ b/common/test/common_tests/helpers/compositions.cljc @@ -6,39 +6,76 @@ (ns common-tests.helpers.compositions (:require - [common-tests.helpers.files :as thf] - [common-tests.helpers.ids-map :as thi])) + [app.common.data :as d] + [common-tests.helpers.files :as thf])) (defn add-rect - [file rect-label] + [file rect-label & {:keys [] :as params}] (thf/add-sample-shape file rect-label - :type :rect - :name "Rect1")) + (merge {:type :rect + :name "Rect1"} + params))) (defn add-frame - ([file frame-label & {:keys [parent-label]}] - (thf/add-sample-shape file frame-label - :type :frame - :name "Frame1" - :parent-label parent-label))) + [file frame-label & {:keys [] :as params}] + (thf/add-sample-shape file frame-label + (merge {:type :frame + :name "Frame1"} + params))) (defn add-frame-with-child - [file frame-label child-label] + [file frame-label child-label & {:keys [frame-params child-params]}] (-> file - (add-frame frame-label) + (add-frame frame-label frame-params) (thf/add-sample-shape child-label - :type :rect - :name "Rect1" - :parent-label frame-label))) + (merge {:type :rect + :name "Rect1" + :parent-label frame-label} + child-params)))) (defn add-simple-component - [file component-label root-label child-label] + [file component-label root-label child-label + & {:keys [component-params root-params child-params]}] (-> file - (add-frame-with-child root-label child-label) - (thf/make-component component-label root-label))) + (add-frame-with-child root-label child-label :frame-params root-params :child-params child-params) + (thf/make-component component-label root-label component-params))) (defn add-simple-component-with-copy - [file component-label main-root-label main-child-label copy-root-label] + [file component-label main-root-label main-child-label copy-root-label + & {:keys [component-params main-root-params main-child-params copy-root-params]}] (-> file - (add-simple-component component-label main-root-label main-child-label) - (thf/instantiate-component component-label copy-root-label))) + (add-simple-component component-label + main-root-label + main-child-label + :component-params component-params + :root-params main-root-params + :child-params main-child-params) + (thf/instantiate-component component-label copy-root-label copy-root-params))) + +(defn add-component-with-many-children + [file component-label root-label child-labels + & {:keys [component-params root-params child-params-list]}] + (as-> file $ + (add-frame $ root-label root-params) + (reduce (fn [file [label params]] + (thf/add-sample-shape file + label + (merge {:type :rect + :name "Rect1" + :parent-label root-label} + params))) + $ + (d/zip-all child-labels child-params-list)) + (thf/make-component $ component-label root-label component-params))) + +(defn add-component-with-many-children-and-copy + [file component-label root-label child-labels copy-root-label + & {:keys [component-params root-params child-params-list copy-root-params]}] + (-> file + (add-component-with-many-children component-label + root-label + child-labels + :component-params component-params + :root-params root-params + :child-params-list child-params-list) + (thf/instantiate-component component-label copy-root-label copy-root-params))) diff --git a/common/test/common_tests/helpers/files.cljc b/common/test/common_tests/helpers/files.cljc index bf605f5dc3..b6349636b6 100644 --- a/common/test/common_tests/helpers/files.cljc +++ b/common/test/common_tests/helpers/files.cljc @@ -6,6 +6,7 @@ (ns common-tests.helpers.files (:require + [app.common.colors :as clr] [app.common.data.macros :as dm] [app.common.features :as ffeat] [app.common.files.changes :as cfc] @@ -169,7 +170,7 @@ ;; ----- Components (defn make-component - [file label root-label] + [file label root-label & {:keys [] :as params}] (let [page (current-page file) root (get-shape file root-label)] @@ -194,12 +195,12 @@ #(update % :objects assoc (:id shape) shape))) $ updated-shapes) - (ctkl/add-component $ - {:id (:component-id updated-root) - :name (:name updated-root) - :main-instance-id (:id updated-root) - :main-instance-page (:id page) - :shapes updated-shapes}))))))) + (ctkl/add-component $ (assoc params + :id (:component-id updated-root) + :name (:name updated-root) + :main-instance-id (:id updated-root) + :main-instance-page (:id page) + :shapes updated-shapes)))))))) (defn get-component [file label] @@ -306,7 +307,21 @@ [label & {:keys [] :as params}] (ctc/make-color (assoc params :id (thi/new-id! label)))) -(defn add-sample-color +(defn sample-fill-color + [& {:keys [fill-color fill-opacity] :as params}] + (let [params (cond-> params + (nil? fill-color) + (assoc :fill-color clr/black) + + (nil? fill-opacity) + (assoc :fill-opacity 1))] + params)) + +(defn sample-fills-color + [& {:keys [] :as params}] + [(sample-fill-color params)]) + +(defn add-sample-library-color [file label & {:keys [] :as params}] (let [color (sample-color label params)] (ctf/update-file-data file #(ctcl/add-color % color)))) diff --git a/common/test/common_tests/logic/logic_comp_creation_test.cljc b/common/test/common_tests/logic/component_creation_test.cljc similarity index 92% rename from common/test/common_tests/logic/logic_comp_creation_test.cljc rename to common/test/common_tests/logic/component_creation_test.cljc index 577bef06f3..3e6499fb2b 100644 --- a/common/test/common_tests/logic/logic_comp_creation_test.cljc +++ b/common/test/common_tests/logic/component_creation_test.cljc @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns common-tests.logic.logic-comp-creation-test +(ns common-tests.logic.component-creation-test (:require [app.common.files.changes-builder :as pcb] [app.common.files.libraries-helpers :as cflh] @@ -15,14 +15,14 @@ (t/use-fixtures :each thi/test-fixture) (t/deftest test-add-component-from-single-shape - (let [; Setup + (let [;; Setup file (-> (thf/sample-file :file1) (thf/add-sample-shape :shape1 :type :frame)) page (thf/current-page file) shape1 (thf/get-shape file :shape1) - ; Action + ;; Action [_ component-id changes] (cflh/generate-add-component (pcb/empty-changes) [shape1] @@ -35,11 +35,11 @@ file' (thf/apply-changes file changes) - ; Get + ;; Get component (thf/get-component-by-id file' component-id) root (thf/get-shape-by-id file' (:main-instance-id component))] - ; Check + ;; Check (t/is (some? component)) (t/is (some? root)) (t/is (= (:component-id root) (:id component))))) diff --git a/common/test/common_tests/logic/components_touched_test.cljc b/common/test/common_tests/logic/components_touched_test.cljc new file mode 100644 index 0000000000..4d912a6411 --- /dev/null +++ b/common/test/common_tests/logic/components_touched_test.cljc @@ -0,0 +1,152 @@ +;; 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 + +(ns common-tests.logic.components-touched-test + (:require + [app.common.files.changes-builder :as pcb] + [app.common.files.libraries-helpers :as cflh] + [clojure.test :as t] + [common-tests.helpers.compositions :as tho] + [common-tests.helpers.files :as thf] + [common-tests.helpers.ids-map :as thi])) + +(t/use-fixtures :each thi/test-fixture) + +(t/deftest test-touched-when-changing-attribute + (let [;; Setup + file (-> (thf/sample-file :file1) + (tho/add-simple-component-with-copy :component1 + :main-root + :main-child + :copy-root + :main-child-params {:fills (thf/sample-fills-color + :fill-color "#abcdef")})) + page (thf/current-page file) + copy-root (thf/get-shape file :copy-root) + + ;; Action + update-fn (fn [shape] + (assoc shape :fills (thf/sample-fills-color :fill-color "#fabada"))) + + changes (cflh/generate-update-shapes (pcb/empty-changes nil (:id page)) + (:shapes copy-root) + update-fn + (:objects page) + {}) + + file' (thf/apply-changes file changes) + + ;; Get + copy-root' (thf/get-shape file' :copy-root) + copy-child' (thf/get-shape-by-id file' (first (:shapes copy-root'))) + fills' (:fills copy-child') + fill' (first fills')] + + ;; Check + (t/is (= (count fills') 1)) + (t/is (= (:fill-color fill') "#fabada")) + (t/is (= (:fill-opacity fill') 1)) + (t/is (= (:touched copy-root') nil)) + (t/is (= (:touched copy-child') #{:fill-group})))) + +(t/deftest test-not-touched-when-adding-shape + (let [;; Setup + file (-> (thf/sample-file :file1) + (tho/add-simple-component-with-copy :component1 + :main-root + :main-child + :copy-root) + (thf/add-sample-shape :free-shape)) + + page (thf/current-page file) + copy-root (thf/get-shape file :copy-root) + + ;; Action + ;; IMPORTANT: as modifying copies structure is now forbidden, this action + ;; will not have any effect, and so the parent shape won't also be touched. + changes (cflh/generate-relocate-shapes (pcb/empty-changes) + (:objects page) + #{(:parent-id copy-root)} ; parents + (thi/id :copy-root) ; parent-id + (:id page) ; page-id + 0 ; to-index + #{(thi/id :free-shape)}) ; ids + + file' (thf/apply-changes file changes) + + ;; Get + copy-root' (thf/get-shape file' :copy-root) + copy-child' (thf/get-shape-by-id file' (first (:shapes copy-root')))] + + ;; Check + (t/is (= (:touched copy-root') nil)) + (t/is (= (:touched copy-child') nil)))) + +(t/deftest test-touched-when-deleting-shape + (let [;; Setup + file (-> (thf/sample-file :file1) + (tho/add-simple-component-with-copy :component1 + :main-root + :main-child + :copy-root)) + + page (thf/current-page file) + copy-root (thf/get-shape file :copy-root) + + ;; Action + ;; IMPORTANT: as modifying copies structure is now forbidden, this action will not + ;; delete the child shape, but hide it (thus setting the visibility group). + [_all-parents changes] + (cflh/generate-delete-shapes (pcb/empty-changes) + file + page + (:objects page) + (set (:shapes copy-root)) + {:components-v2 true}) + + file' (thf/apply-changes file changes) + + ;; Get + copy-root' (thf/get-shape file' :copy-root) + copy-child' (thf/get-shape-by-id file' (first (:shapes copy-root')))] + + ;; Check + (t/is (= (:touched copy-root') nil)) + (t/is (= (:touched copy-child') #{:visibility-group})))) + +(t/deftest test-not-touched-when-moving-shape + (let [;; Setup + file (-> (thf/sample-file :file1) + (tho/add-component-with-many-children-and-copy :component1 + :main-root + [:main-child1 :main-child2 :main-child3] + :copy-root) + (thf/add-sample-shape :free-shape)) + + page (thf/current-page file) + copy-root (thf/get-shape file :copy-root) + copy-child1 (thf/get-shape-by-id file (first (:shapes copy-root))) + + ;; Action + ;; IMPORTANT: as modifying copies structure is now forbidden, this action + ;; will not have any effect, and so the parent shape won't also be touched. + changes (cflh/generate-relocate-shapes (pcb/empty-changes) + (:objects page) + #{(:parent-id copy-child1)} ; parents + (thi/id :copy-root) ; parent-id + (:id page) ; page-id + 2 ; to-index + #{(:id copy-child1)}) ; ids + + file' (thf/apply-changes file changes) + + ;; Get + copy-root' (thf/get-shape file' :copy-root) + copy-child' (thf/get-shape-by-id file' (first (:shapes copy-root')))] + + ;; Check + (t/is (= (:touched copy-root') nil)) + (t/is (= (:touched copy-child') nil)))) diff --git a/common/test/common_tests/types/types_libraries_test.cljc b/common/test/common_tests/types/types_libraries_test.cljc index 0eab0db078..d95232824d 100644 --- a/common/test/common_tests/types/types_libraries_test.cljc +++ b/common/test/common_tests/types/types_libraries_test.cljc @@ -70,21 +70,21 @@ (t/is (= (:name f1) "Test file")))) (t/deftest test-absorb-components - (let [; Setup + (let [;; Setup library (-> (thf/sample-file :library :is-shared true) (tho/add-simple-component :component1 :main-root :rect1)) file (-> (thf/sample-file :file) (thf/instantiate-component :component1 :copy-root :library library)) - ; Action + ;; Action file' (ctf/update-file-data file #(ctf/absorb-assets % (:data library))) _ (thf/validate-file! file') - ; Get + ;; Get pages' (ctpl/pages-seq (ctf/file-data file')) components' (ctkl/components-seq (ctf/file-data file')) component' (first components') @@ -92,7 +92,7 @@ copy-root' (thf/get-shape file' :copy-root) main-root' (ctf/get-ref-shape (ctf/file-data file') component' copy-root')] - ; Check + ;; Check (t/is (= (count pages') 2)) (t/is (= (:name (first pages')) "Page 1")) (t/is (= (:name (second pages')) "Main components")) @@ -104,10 +104,10 @@ (t/is (ctk/main-instance-of? (:id main-root') (:id (second pages')) component')))) (t/deftest test-absorb-colors - (let [; Setup + (let [;; Setup library (-> (thf/sample-file :library :is-shared true) - (thf/add-sample-color :color1 {:name "Test color" - :color "#abcdef"})) + (thf/add-sample-library-color :color1 {:name "Test color" + :color "#abcdef"})) file (-> (thf/sample-file :file) (thf/add-sample-shape :shape1 @@ -118,19 +118,19 @@ :fill-color-ref-id (thi/id :color1) :fill-color-ref-file (thi/id :library)}])) - ; Action + ;; Action file' (ctf/update-file-data file #(ctf/absorb-assets % (:data library))) _ (thf/validate-file! file') - ; Get + ;; Get colors' (ctcl/colors-seq (ctf/file-data file')) shape1' (thf/get-shape file' :shape1) fill' (first (:fills shape1'))] - ; Check + ;; Check (t/is (= (count colors') 1)) (t/is (= (:id (first colors')) (thi/id :color1))) (t/is (= (:name (first colors')) "Test color")) @@ -141,7 +141,7 @@ (t/is (= (:fill-color-ref-file fill') (:id file'))))) (t/deftest test-absorb-typographies - (let [; Setup + (let [;; Setup library (-> (thf/sample-file :library :is-shared true) (thf/add-sample-typography :typography1 {:name "Test typography"})) @@ -169,18 +169,19 @@ :letter-spacing "0" :fills [{:fill-color "#000000" :fill-opacity 1}]}]}]}]})) - ; Action + ;; Action file' (ctf/update-file-data file #(ctf/absorb-assets % (:data library))) _ (thf/validate-file! file') - ; Get + ;; Get typographies' (ctyl/typographies-seq (ctf/file-data file')) shape1' (thf/get-shape file' :shape1) text-node' (d/seek #(some? (:text %)) (txt/node-seq (:content shape1')))] + ;; Check (t/is (= (count typographies') 1)) (t/is (= (:id (first typographies')) (thi/id :typography1))) (t/is (= (:name (first typographies')) "Test typography")) diff --git a/frontend/src/app/main/data/workspace/changes.cljs b/frontend/src/app/main/data/workspace/changes.cljs index b2d5950865..87dec4048f 100644 --- a/frontend/src/app/main/data/workspace/changes.cljs +++ b/frontend/src/app/main/data/workspace/changes.cljs @@ -12,10 +12,10 @@ [app.common.files.changes :as cpc] [app.common.files.changes-builder :as pcb] [app.common.files.helpers :as cph] + [app.common.files.libraries-helpers :as cflh] [app.common.logging :as log] [app.common.schema :as sm] [app.common.types.shape-tree :as ctst] - [app.common.types.shape.layout :as ctl] [app.common.uuid :as uuid] [app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.undo :as dwu] @@ -74,23 +74,19 @@ (filter #(some update-layout-attr? (pcb/changed-attrs % objects update-fn {:attrs attrs :with-objects? with-objects?}))) (map :id)) - changes (reduce - (fn [changes id] - (let [opts {:attrs attrs - :ignore-geometry? (get ignore-tree id) - :ignore-touched ignore-touched - :with-objects? with-objects?}] - (pcb/update-shapes changes [id] update-fn (d/without-nils opts)))) - (-> (pcb/empty-changes it page-id) - (pcb/set-save-undo? save-undo?) - (pcb/set-stack-undo? stack-undo?) - (pcb/with-objects objects) - (cond-> undo-group - (pcb/set-undo-group undo-group))) - ids) - grid-ids (->> ids (filter (partial ctl/grid-layout? objects))) - changes (pcb/update-shapes changes grid-ids ctl/assign-cell-positions {:with-objects? true}) - changes (pcb/reorder-grid-children changes ids) + changes (-> (pcb/empty-changes it page-id) + (pcb/set-save-undo? save-undo?) + (pcb/set-stack-undo? stack-undo?) + (cflh/generate-update-shapes ids + update-fn + objects + {:attrs attrs + :ignore-tree ignore-tree + :ignore-touched ignore-touched + :with-objects? with-objects?}) + (cond-> undo-group + (pcb/set-undo-group undo-group))) + changes (add-undo-group changes state)] (rx/concat (if (seq (:redo-changes changes)) diff --git a/frontend/test/frontend_tests/state_components_sync_test.cljs b/frontend/test/frontend_tests/state_components_sync_test.cljs index 4928ad74c0..8ae88562a1 100644 --- a/frontend/test/frontend_tests/state_components_sync_test.cljs +++ b/frontend/test/frontend_tests/state_components_sync_test.cljs @@ -7,7 +7,6 @@ (ns frontend-tests.state-components-sync-test (:require [app.common.colors :as clr] - [app.common.types.file :as ctf] [app.main.data.workspace :as dw] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.libraries :as dwl] @@ -24,264 +23,6 @@ ;; === Test touched ====================== -(t/deftest test-touched - (t/async done - (let [state (-> thp/initial-state - (thp/sample-page) - (thp/sample-shape :shape1 :rect - {:name "Rect 1" - :fill-color clr/white - :fill-opacity 1}) - (thp/make-component :main1 :component1 - [(thp/id :shape1)]) - (thp/instantiate-component :instance1 - (thp/id :component1))) - - [_group1 shape1'] - (thl/resolve-instance state (thp/id :instance1)) - - store (the/prepare-store state done - (fn [new-state] - ;; Uncomment to debug - ;; (ctf/dump-tree (get new-state :workspace-data) - ;; (get new-state :current-page-id) - ;; (get new-state :workspace-libraries) - ;; false true) - ;; Expected shape tree: - ;;; - ;; [Page] - ;; Root Frame - ;; Rect 1 - ;; Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1* ---> Rect 1 - ;; #{:fill-group} - ;;; - ;; [Rect 1] - ;; page1 / Rect 1 - ;;; - (let [[[group shape1] [c-group c-shape1] _component] - (thl/resolve-instance-and-main - new-state - (thp/id :instance1))] - - (t/is (= (:name group) "Rect 1")) - (t/is (= (:touched group) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:touched shape1) #{:fill-group})) - (t/is (= (:fill-color shape1) clr/test)) - (t/is (= (:fill-opacity shape1) 0.5)) - - (t/is (= (:name c-group) "Rect 1")) - (t/is (= (:touched c-group) nil)) - (t/is (= (:name c-shape1) "Rect 1")) - (t/is (= (:touched c-shape1) nil)) - (t/is (= (:fill-color c-shape1) clr/white)) - (t/is (= (:fill-opacity c-shape1) 1)))))] - - (ptk/emit! - store - (dch/update-shapes [(:id shape1')] - (fn [shape] - (merge shape {:fill-color clr/test - :fill-opacity 0.5}))) - :the/end)))) - -(t/deftest test-touched-children-add - (t/async done - (let [state (-> thp/initial-state - (thp/sample-page) - (thp/sample-shape :shape1 :rect - {:name "Rect 1" - :fill-color clr/white - :fill-opacity 1}) - (thp/make-component :main1 :component1 - [(thp/id :shape1)]) - (thp/instantiate-component :instance1 - (thp/id :component1)) - (thp/sample-shape :shape2 :circle - {:name "Circle 1"})) - - instance1 (thp/get-shape state :instance1) - shape2 (thp/get-shape state :shape2) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;; [Page: Page 1] - ;; Root Frame - ;; {Rect 1} - ;; Rect1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Circle 1 - ;; - ;; [Component: Rect 1] core.cljs:200:23 - ;; --> [Page 1] Rect 1 - - (let [[[group shape1] [c-group c-shape1] _component] - (thl/resolve-instance-and-main-allow-dangling - new-state - (thp/id :instance1))] - - (t/is (= (:name group) "Rect 1")) - (t/is (nil? (:touched group))) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:touched shape1) nil)) - (t/is (not= (:shape-ref shape1) nil)) - - (t/is (= (:name c-group) "Rect 1")) - (t/is (= (:touched c-group) nil)) - (t/is (= (:shape-ref c-group) nil)) - (t/is (= (:name c-shape1) "Rect 1")) - (t/is (= (:touched c-shape1) nil)) - (t/is (= (:shape-ref c-shape1) nil)))))] - - (ptk/emit! - store - (dw/relocate-shapes #{(:id shape2)} (:id instance1) 0) ;; We cant't change the structure of component copies, so this operation will do nothing - :the/end)))) - -(t/deftest test-touched-children-delete - (t/async done - (let [state (-> thp/initial-state - (thp/sample-page) - (thp/sample-shape :shape1 :rect - {:name "Rect 1"}) - (thp/sample-shape :shape2 :rect - {:name "Rect 2"}) - (thp/make-component :main1 :component1 - [(thp/id :shape1) - (thp/id :shape2)]) - (thp/instantiate-component :instance1 - (thp/id :component1))) - - [_group1 shape1'] - (thl/resolve-instance state (thp/id :instance1)) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;;; - ;; [Page] - ;; Root Frame - ;; Component 1 - ;; Rect 1 - ;; Rect 2 - ;; Component 1 #--> Component 1 - ;; Rect 1* ---> Rect 1 - ;; #{:visibility-group} - ;; Rect 2 ---> Rect 2 - ;;; - ;; [Component 1] - ;; page1 / Component 1 - ;; - (let [[[group shape1 shape2] [c-group c-shape1 c-shape2] _component] - (thl/resolve-instance-and-main-allow-dangling - new-state - (thp/id :instance1))] - - (t/is (= (:name group) "Component 1")) - (t/is (= (:touched group) nil)) - (t/is (not= (:shape-ref group) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:hidden shape1) true)) ; Instance shapes are not deleted but hidden - (t/is (= (:touched shape1) #{:visibility-group})) - (t/is (not= (:shape-ref shape1) nil)) - (t/is (= (:name shape2) "Rect 2")) - (t/is (= (:touched shape2) nil)) - (t/is (not= (:shape-ref shape2) nil)) - - (t/is (= (:name c-group) "Component 1")) - (t/is (= (:touched c-group) nil)) - (t/is (= (:shape-ref c-group) nil)) - (t/is (= (:name c-shape1) "Rect 1")) - (t/is (= (:touched c-shape1) nil)) - (t/is (= (:shape-ref c-shape1) nil)) - (t/is (= (:name c-shape2) "Rect 2")) - (t/is (= (:touched c-shape2) nil)) - (t/is (= (:shape-ref c-shape2) nil)))))] - - (ptk/emit! - store - (dwsh/delete-shapes #{(:id shape1')}) - :the/end)))) - -(t/deftest test-touched-children-move - (t/async done - (let [state (-> thp/initial-state - (thp/sample-page) - (thp/sample-shape :shape1 :rect - {:name "Rect 1"}) - (thp/sample-shape :shape2 :rect - {:name "Rect 2"}) - (thp/sample-shape :shape3 :rect - {:name "Rect 3"}) - (thp/make-component :main1 :component1 - [(thp/id :shape1) - (thp/id :shape2) - (thp/id :shape3)]) - (thp/instantiate-component :instance1 - (thp/id :component1))) - - [group1' shape1'] - (thl/resolve-instance state (thp/id :instance1)) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;; [Page: Page 1] - ;; Root Frame - ;; {Component 1} # - ;; Rect 1 - ;; Rect 2 - ;; Rect 3 - ;; Component 1 #--> Component 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 2 ---> Rect 2 - ;; Rect 3 ---> Rect 3 - ;; - ;; ========= Local library - ;; - ;; [Component: Component 1] - ;; --> [Page 1] Component 1 - - (let [[[group shape1 shape2 shape3] - [c-group c-shape1 c-shape2 c-shape3] _component] - (thl/resolve-instance-and-main-allow-dangling - new-state - (thp/id :instance1))] - - (t/is (= (:name group) "Component 1")) - (t/is (nil? (:touched group))) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:touched shape1) nil)) - (t/is (not= (:shape-ref shape1) nil)) - (t/is (= (:name shape2) "Rect 2")) - (t/is (= (:touched shape2) nil)) - (t/is (not= (:shape-ref shape2) nil)) - (t/is (= (:name shape3) "Rect 3")) - (t/is (= (:touched shape3) nil)) - (t/is (not= (:shape-ref shape3) nil)) - - (t/is (= (:name c-group) "Component 1")) - (t/is (= (:touched c-group) nil)) - (t/is (= (:shape-ref c-group) nil)) - (t/is (= (:name c-shape1) "Rect 1")) - (t/is (= (:touched c-shape1) nil)) - (t/is (= (:shape-ref c-shape1) nil)) - (t/is (= (:name c-shape2) "Rect 2")) - (t/is (= (:touched c-shape2) nil)) - (t/is (= (:shape-ref c-shape2) nil)) - (t/is (= (:name c-shape3) "Rect 3")) - (t/is (= (:touched c-shape3) nil)) - (t/is (= (:shape-ref c-shape3) nil)))))] - - (ptk/emit! - store - (dw/relocate-shapes #{(:id shape1')} (:id group1') 2) ;; We cant't change the structure of component copies, so this operation will do nothing - :the/end)))) - (t/deftest test-touched-from-lib (t/async done