diff --git a/common/test/common_tests/logic/comp_sync_test.cljc b/common/test/common_tests/logic/comp_sync_test.cljc new file mode 100644 index 000000000..1f3b8b4c2 --- /dev/null +++ b/common/test/common_tests/logic/comp_sync_test.cljc @@ -0,0 +1,495 @@ +;; 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.comp-sync-test + (:require + [app.common.data :as d] + [app.common.files.changes-builder :as pcb] + [app.common.files.shapes-helpers :as cfsh] + [app.common.geom.point :as gpt] + [app.common.logic.libraries :as cll] + [app.common.logic.shapes :as cls] + [app.common.types.component :as ctk] + [app.common.types.components-list :as ctkl] + [app.common.types.shape-tree :as ctst] + [clojure.test :as t] + [common-tests.helpers.components :as thc] + [common-tests.helpers.compositions :as tho] + [common-tests.helpers.files :as thf] + [common-tests.helpers.ids-map :as thi] + [common-tests.helpers.shapes :as ths])) + +(t/use-fixtures :each thi/test-fixture) + +(t/deftest test-sync-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 (ths/sample-fills-color + :fill-color "#abcdef")} + :copy-root-params {:children-labels [:copy-child]})) + page (thf/current-page file) + main-child (ths/get-shape file :main-child) + + ;; ==== Action + changes1 (cls/generate-update-shapes (pcb/empty-changes nil (:id page)) + #{(:id main-child)} + (fn [shape] + (assoc shape :fills (ths/sample-fills-color :fill-color "#fabada"))) + (:objects page) + {}) + + updated-file (thf/apply-changes file changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id updated-file) + (thi/id :component1) + (:id updated-file) + {(:id updated-file) updated-file} + (:id updated-file)) + + file' (thf/apply-changes updated-file changes2) + + ;; ==== Get + copy-root' (ths/get-shape file' :copy-root) + copy-child' (ths/get-shape file' :copy-child) + fills' (:fills copy-child') + fill' (first fills')] + + ;; ==== Check + (t/is (some? copy-root')) + (t/is (some? copy-child')) + (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') nil)))) + +(t/deftest test-sync-when-changing-attribute-from-library + (let [;; ==== Setup + library (-> (thf/sample-file :file1) + (tho/add-simple-component :component1 + :main-root + :main-child + :copy-root + :main-child-params {:fills (ths/sample-fills-color + :fill-color "#abcdef")})) + + file (-> (thf/sample-file :file) + (thc/instantiate-component :component1 :copy-root + :library library + :children-labels [:copy-child])) + + page (thf/current-page library) + main-child (ths/get-shape library :main-child) + + ;; ==== Action + changes1 (cls/generate-update-shapes (pcb/empty-changes nil (:id page)) + #{(:id main-child)} + (fn [shape] + (assoc shape :fills (ths/sample-fills-color :fill-color "#fabada"))) + (:objects page) + {}) + + updated-library (thf/apply-changes library changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id file) + (thi/id :component1) + (:id updated-library) + {(:id updated-library) updated-library + (:id file) file} + (:id file)) + + file' (thf/apply-changes file changes2) + + ;; ==== Get + copy-root' (ths/get-shape file' :copy-root) + copy-child' (ths/get-shape file' :copy-child) + fills' (:fills copy-child') + fill' (first fills')] + + ;; ==== Check + (t/is (some? copy-root')) + (t/is (some? copy-child')) + (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') nil)))) + +(t/deftest test-sync-when-changing-attribute-preserve-touched + (let [;; ==== Setup + file (-> (thf/sample-file :file1) + (tho/add-simple-component-with-copy :component1 + :main-root + :main-child + :copy-root + :main-child-params {:fills (ths/sample-fills-color + :fill-color "#abcdef")} + :copy-root-params {:children-labels [:copy-child]})) + page (thf/current-page file) + main-child (ths/get-shape file :main-child) + copy-child (ths/get-shape file :copy-child) + + ;; ==== Action + changes1 (-> (pcb/empty-changes nil (:id page)) + (cls/generate-update-shapes + #{(:id copy-child)} + (fn [shape] + (assoc shape :fills (ths/sample-fills-color :fill-color "#aaaaaa"))) + (:objects page) + {}) + (cls/generate-update-shapes + #{(:id main-child)} + (fn [shape] + (assoc shape :fills (ths/sample-fills-color :fill-color "#fabada"))) + (:objects page) + {})) + + updated-file (thf/apply-changes file changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id updated-file) + (thi/id :component1) + (:id updated-file) + {(:id updated-file) updated-file} + (:id updated-file)) + + file' (thf/apply-changes updated-file changes2) + + ;; ==== Get + copy-root' (ths/get-shape file' :copy-root) + copy-child' (ths/get-shape file' :copy-child) + fills' (:fills copy-child') + fill' (first fills')] + + ;; ==== Check + (t/is (some? copy-root')) + (t/is (some? copy-child')) + (t/is (= (count fills') 1)) + (t/is (= (:fill-color fill') "#aaaaaa")) + (t/is (= (:fill-opacity fill') 1)) + (t/is (= (:touched copy-root') nil)) + (t/is (= (:touched copy-child') #{:fill-group})))) + +(t/deftest test-sync-when-adding-shape + (let [;; ==== Setup + file (-> (thf/sample-file :file1) + (tho/add-simple-component-with-copy :component1 + :main-root + :main-child + :copy-root + :copy-root-params {:children-labels [:copy-child]}) + (ths/add-sample-shape :free-shape)) + + page (thf/current-page file) + main-root (ths/get-shape file :main-root) + + ;; ==== Action + changes1 (cls/generate-relocate-shapes (pcb/empty-changes) + (:objects page) + #{(:parent-id main-root)} ; parents + (thi/id :main-root) ; parent-id + (:id page) ; page-id + 0 ; to-index + #{(thi/id :free-shape)}) ; ids + + updated-file (thf/apply-changes file changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id updated-file) + (thi/id :component1) + (:id updated-file) + {(:id updated-file) updated-file} + (:id updated-file)) + + file' (thf/apply-changes updated-file changes2) + + ;; ==== Get + main-free-shape' (ths/get-shape file' :free-shape) + copy-root' (ths/get-shape file' :copy-root) + copy-new-child-id' (d/seek #(not= % (thi/id :copy-child)) (:shapes copy-root')) + copy-new-child' (ths/get-shape-by-id file' copy-new-child-id')] + + ;; ==== Check + (t/is (some? copy-root')) + (t/is (some? copy-new-child')) + (t/is (= (:touched copy-root') nil)) + (t/is (= (:touched copy-new-child') nil)) + (t/is (ctst/parent-of? copy-root' copy-new-child')) + (t/is (ctk/is-main-of? main-free-shape' copy-new-child' true)))) + +(t/deftest test-sync-when-deleting-shape + (let [;; ==== Setup + file (-> (thf/sample-file :file1) + (tho/add-simple-component-with-copy :component1 + :main-root + :main-child + :copy-root + :copy-root-params {:children-labels [:copy-child]})) + + page (thf/current-page file) + main-child (ths/get-shape file :main-child) + + ;; ==== 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 changes1] + (cls/generate-delete-shapes (pcb/empty-changes) + file + page + (:objects page) + #{(:id main-child)} + {:components-v2 true}) + + updated-file (thf/apply-changes file changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id updated-file) + (thi/id :component1) + (:id updated-file) + {(:id updated-file) updated-file} + (:id updated-file)) + + file' (thf/apply-changes updated-file changes2) + + ;; ==== Get + copy-root' (ths/get-shape file' :copy-root) + copy-child' (ths/get-shape file' :copy-child)] + + ;; ==== Check + (t/is (some? copy-root')) + (t/is (nil? copy-child')) + (t/is (= (:touched copy-root') nil)) + (t/is (empty? (:shapes copy-root'))))) + +(t/deftest test-sync-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 + :copy-root-params {:children-labels [:copy-child1 + :copy-child2 + :copy-child3]}) + (ths/add-sample-shape :free-shape)) + + page (thf/current-page file) + main-child1 (ths/get-shape file :main-child1) + + ;; ==== Action + changes1 (cls/generate-relocate-shapes (pcb/empty-changes) + (:objects page) + #{(:parent-id main-child1)} ; parents + (thi/id :main-root) ; parent-id + (:id page) ; page-id + 2 ; to-index + #{(:id main-child1)}) ; ids + + updated-file (thf/apply-changes file changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id updated-file) + (thi/id :component1) + (:id updated-file) + {(:id updated-file) updated-file} + (:id updated-file)) + + file' (thf/apply-changes updated-file changes2) + + ;; ==== Get + copy-root' (ths/get-shape file' :copy-root) + copy-child1' (ths/get-shape file' :copy-child1) + copy-child2' (ths/get-shape file' :copy-child2) + copy-child3' (ths/get-shape file' :copy-child3)] + + ;; ==== Check + (t/is (some? copy-root')) + (t/is (some? copy-child1')) + (t/is (= (:touched copy-root') nil)) + (t/is (= (:touched copy-child1') nil)) + (t/is (= (:touched copy-child2') nil)) + (t/is (= (:touched copy-child3') nil)) + (t/is (= (second (:shapes copy-root')) (:id copy-child1'))) + (t/is (= (first (:shapes copy-root')) (:id copy-child2'))) + (t/is (= (nth (:shapes copy-root') 2) (:id copy-child3'))))) + +(t/deftest test-sync-when-changing-upper + (let [;; ==== Setup + file (-> (thf/sample-file :file1) + (tho/add-nested-component-with-copy :component1 + :main1-root + :main1-child + :component2 + :main2-root + :main2-nested-head + :copy2-root + :main2-root-params {:fills (ths/sample-fills-color + :fill-color "#abcdef")})) + page (thf/current-page file) + main2-root (ths/get-shape file :main2-root) + + ;; ==== Action + changes1 (cls/generate-update-shapes (pcb/empty-changes nil (:id page)) + #{(:id main2-root)} + (fn [shape] + (assoc shape :fills (ths/sample-fills-color :fill-color "#fabada"))) + (:objects page) + {}) + + updated-file (thf/apply-changes file changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id updated-file) + (thi/id :component2) + (:id updated-file) + {(:id updated-file) updated-file} + (:id updated-file)) + + file' (thf/apply-changes updated-file changes2) + + ;; ==== Get + copy2-root' (ths/get-shape file' :copy2-root) + fills' (:fills copy2-root') + fill' (first fills')] + + ;; ==== Check + (t/is (some? copy2-root')) + (t/is (= (count fills') 1)) + (t/is (= (:fill-color fill') "#fabada")) + (t/is (= (:fill-opacity fill') 1)) + (t/is (= (:touched copy2-root') nil)))) + +(t/deftest test-sync-when-changing-lower-near + (let [;; ==== Setup + file (-> (thf/sample-file :file1) + (tho/add-nested-component-with-copy :component1 + :main1-root + :main1-child + :component2 + :main2-root + :main2-nested-head + :copy2-root + :copy2-root-params {:children-labels [:copy2-child]})) + page (thf/current-page file) + main2-nested-head (ths/get-shape file :main2-nested-head) + + ;; ==== Action + changes1 (cls/generate-update-shapes (pcb/empty-changes nil (:id page)) + #{(:id main2-nested-head)} + (fn [shape] + (assoc shape :fills (ths/sample-fills-color :fill-color "#fabada"))) + (:objects page) + {}) + + updated-file (thf/apply-changes file changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id updated-file) + (thi/id :component2) + (:id updated-file) + {(:id updated-file) updated-file} + (:id updated-file)) + + file' (thf/apply-changes updated-file changes2) + + ;; ==== Get + copy2-root' (ths/get-shape file' :copy2-root) + copy2-child' (ths/get-shape file' :copy2-child) + fills' (:fills copy2-child') + fill' (first fills')] + + ;; ==== Check + (t/is (some? copy2-root')) + (t/is (some? copy2-child')) + (t/is (= (count fills') 1)) + (t/is (= (:fill-color fill') "#fabada")) + (t/is (= (:fill-opacity fill') 1)) + (t/is (= (:touched copy2-root') nil)) + (t/is (= (:touched copy2-child') nil)))) + +(t/deftest test-sync-when-changing-lower-remote + (let [;; ==== Setup + file (-> (thf/sample-file :file1) + (tho/add-nested-component-with-copy :component1 + :main1-root + :main1-child + :component2 + :main2-root + :main2-nested-head + :copy2-root + :copy2-root-params {:children-labels [:copy2-child]})) + page (thf/current-page file) + main1-root (ths/get-shape file :main1-root) + + ;; ==== Action + changes1 (cls/generate-update-shapes (pcb/empty-changes nil (:id page)) + #{(:id main1-root)} + (fn [shape] + (assoc shape :fills (ths/sample-fills-color :fill-color "#fabada"))) + (:objects page) + {}) + + updated-file (thf/apply-changes file changes1) + + changes2 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id updated-file) + (thi/id :component1) + (:id updated-file) + {(:id updated-file) updated-file} + (:id updated-file)) + + synced-file (thf/apply-changes updated-file changes2) + + changes3 (cll/generate-sync-file-changes (pcb/empty-changes) + nil + :components + (:id synced-file) + (thi/id :component2) + (:id synced-file) + {(:id synced-file) synced-file} + (:id synced-file)) + + file' (thf/apply-changes synced-file changes3) + + ;; ==== Get + copy2-root' (ths/get-shape file' :copy2-root) + copy2-child' (ths/get-shape file' :copy2-child) + fills' (:fills copy2-child') + fill' (first fills')] + + ;; ==== Check + (t/is (some? copy2-root')) + (t/is (some? copy2-child')) + (t/is (= (count fills') 1)) + (t/is (= (:fill-color fill') "#fabada")) + (t/is (= (:fill-opacity fill') 1)) + (t/is (= (:touched copy2-root') nil)) + (t/is (= (:touched copy2-child') nil)))) \ No newline at end of file diff --git a/common/test/common_tests/logic/comp_touched_test.cljc b/common/test/common_tests/logic/comp_touched_test.cljc index c4f658fea..9293cdb27 100644 --- a/common/test/common_tests/logic/comp_touched_test.cljc +++ b/common/test/common_tests/logic/comp_touched_test.cljc @@ -118,11 +118,11 @@ ;; will not have any effect, and so the parent shape won't also be touched. changes (cls/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 + #{(: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) @@ -193,23 +193,30 @@ ;; will not have any effect, and so the parent shape won't also be touched. changes (cls/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 + #{(: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' (ths/get-shape file' :copy-root) - copy-child' (ths/get-shape file' :copy-child1)] + copy-root' (ths/get-shape file' :copy-root) + copy-child1' (ths/get-shape file' :copy-child1) + copy-child2' (ths/get-shape file' :copy-child2) + copy-child3' (ths/get-shape file' :copy-child3)] ;; ==== Check (t/is (some? copy-root')) - (t/is (some? copy-child')) + (t/is (some? copy-child1')) (t/is (= (:touched copy-root') nil)) - (t/is (= (:touched copy-child') nil)))) + (t/is (= (:touched copy-child1') nil)) + (t/is (= (:touched copy-child2') nil)) + (t/is (= (:touched copy-child3') nil)) + (t/is (= (first (:shapes copy-root')) (:id copy-child1'))) + (t/is (= (second (:shapes copy-root')) (:id copy-child2'))) + (t/is (= (nth (:shapes copy-root') 2) (:id copy-child3'))))) (t/deftest test-touched-when-changing-upper (let [;; ==== Setup @@ -290,3 +297,44 @@ (t/is (= (:fill-opacity fill') 1)) (t/is (= (:touched copy2-root') nil)) (t/is (= (:touched copy2-child') #{:fill-group})))) + +(t/deftest test-touched-when-changing-lower + (let [;; ==== Setup + file (-> (thf/sample-file :file1) + (tho/add-nested-component-with-copy :component1 + :main1-root + :main1-child + :component2 + :main2-root + :main2-nested-head + :copy2-root + :copy2-root-params {:children-labels [:copy2-child]})) + page (thf/current-page file) + copy2-child (ths/get-shape file :copy2-child) + + ;; ==== Action + update-fn (fn [shape] + (assoc shape :fills (ths/sample-fills-color :fill-color "#fabada"))) + + changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page)) + #{(:id copy2-child)} + update-fn + (:objects page) + {}) + + file' (thf/apply-changes file changes) + + ;; ==== Get + copy2-root' (ths/get-shape file' :copy2-root) + copy2-child' (ths/get-shape file' :copy2-child) + fills' (:fills copy2-child') + fill' (first fills')] + + ;; ==== Check + (t/is (some? copy2-root')) + (t/is (some? copy2-child')) + (t/is (= (count fills') 1)) + (t/is (= (:fill-color fill') "#fabada")) + (t/is (= (:fill-opacity fill') 1)) + (t/is (= (:touched copy2-root') nil)) + (t/is (= (:touched copy2-child') #{:fill-group})))) \ No newline at end of file diff --git a/frontend/test/frontend_tests/state_components_sync_test.cljs b/frontend/test/frontend_tests/state_components_sync_test.cljs deleted file mode 100644 index 381669c6a..000000000 --- a/frontend/test/frontend_tests/state_components_sync_test.cljs +++ /dev/null @@ -1,1075 +0,0 @@ -;; 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 frontend-tests.state-components-sync-test - (:require - [app.common.colors :as clr] - [app.main.data.workspace :as dw] - [app.main.data.workspace.changes :as dch] - [app.main.data.workspace.libraries :as dwl] - [app.main.data.workspace.shapes :as dwsh] - [app.main.data.workspace.state-helpers :as wsh] - [cljs.test :as t :include-macros true] - [frontend-tests.helpers.events :as the] - [frontend-tests.helpers.libraries :as thl] - [frontend-tests.helpers.pages :as thp] - [potok.v2.core :as ptk])) - -(t/use-fixtures :each - {:before thp/reset-idmap!}) - -;; === Test update component ====================== - -(t/deftest test-update-component - (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/instantiate-component :instance2 - (thp/id :component1))) - - [instance1 shape1'] - (thl/resolve-instance state (thp/id :instance1)) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;; - ;; [Page] - ;; Root Frame - ;; Rect 1 - ;; Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 <== (not updated) - ;; - ;; [Rect 1] - ;; page1 / Rect 1 - ;; - (let [[[main1 shape1] [c-main1 c-shape1] component1] - (thl/resolve-instance-and-main - new-state - (thp/id :main1)) - - [[instance1 shape2] [c-instance1 c-shape2] component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance1)) - - [[instance2 shape3] [c-instance2 c-shape3] component3] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2))] - - (t/is (= (:name main1) "Rect 1")) - (t/is (= (:touched main1) nil)) - (t/is (= (:shape-ref main1) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:fill-color shape1) clr/test)) - (t/is (= (:fill-opacity shape1) 0.5)) - (t/is (= (:touched shape1) nil)) - (t/is (= (:shape-ref shape1) nil)) - - (t/is (= (:name instance1) "Rect 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:shape-ref instance1) (:id c-main1))) - (t/is (= (:name shape2) "Rect 1")) - (t/is (= (:fill-color shape2) clr/test)) - (t/is (= (:fill-opacity shape2) 0.5)) - (t/is (= (:touched shape2) nil)) - (t/is (= (:shape-ref shape2) (:id c-shape1))) - - (t/is (= (:name instance2) "Rect 1")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:shape-ref instance2) (:id c-main1))) - (t/is (= (:name shape3) "Rect 1")) - (t/is (= (:fill-color shape3) clr/white)) - (t/is (= (:fill-opacity shape3) 1)) - (t/is (= (:touched shape3) nil)) - (t/is (= (:shape-ref shape3) (:id c-shape1))) - - (t/is (= component1 component2 component3)) - (t/is (= c-main1 main1)) - (t/is (= c-shape1 shape1)) - (t/is (= c-instance1 c-main1)) - (t/is (= c-shape2 c-shape1)) - (t/is (= c-instance2 c-main1)) - (t/is (= c-shape3 c-shape1)))))] - - (ptk/emit! - store - (dch/update-shapes [(:id shape1')] - (fn [shape] - (merge shape {:fill-color clr/test - :fill-opacity 0.5}))) - (dwl/update-component (:id instance1)) - :the/end)))) - -(t/deftest test-update-component-and-sync - (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/instantiate-component :instance2 - (thp/id :component1))) - - file (wsh/get-local-file state) - - [instance1 shape1'] - (thl/resolve-instance state (thp/id :instance1)) - - [_instance2 _shape1''] - (thl/resolve-instance state (thp/id :instance2)) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;; - ;; [Page] - ;; Root Frame - ;; Rect 1 - ;; Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; - ;; [Rect 1] - ;; page1 / Rect 1 - ;; - (let [[[main1 shape1] [c-main1 c-shape1] component1] - (thl/resolve-instance-and-main - new-state - (thp/id :main1)) - - [[instance1 shape2] [c-instance1 c-shape2] component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance1)) - - [[instance2 shape3] [c-instance2 c-shape3] component3] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2))] - - (t/is (= (:name main1) "Rect 1")) - (t/is (= (:touched main1) nil)) - (t/is (= (:shape-ref main1) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:fill-color shape1) clr/test)) - (t/is (= (:fill-opacity shape1) 0.5)) - (t/is (= (:touched shape1) nil)) - (t/is (= (:shape-ref shape1) nil)) - - (t/is (= (:name instance1) "Rect 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:shape-ref instance1) (:id c-main1))) - (t/is (= (:name shape2) "Rect 1")) - (t/is (= (:fill-color shape2) clr/test)) - (t/is (= (:fill-opacity shape2) 0.5)) - (t/is (= (:touched shape2) nil)) - (t/is (= (:shape-ref shape2) (:id c-shape1))) - - (t/is (= (:name instance2) "Rect 1")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:shape-ref instance2) (:id c-main1))) - (t/is (= (:name shape3) "Rect 1")) - (t/is (= (:fill-color shape3) clr/test)) - (t/is (= (:fill-opacity shape3) 0.5)) - (t/is (= (:touched shape3) nil)) - (t/is (= (:shape-ref shape3) (:id c-shape1))) - - (t/is (= component1 component2 component3)) - (t/is (= c-main1 main1)) - (t/is (= c-shape1 shape1)) - (t/is (= c-instance1 c-main1)) - (t/is (= c-shape2 c-shape1)) - (t/is (= c-instance2 c-main1)) - (t/is (= c-shape3 c-shape1)))))] - - (ptk/emit! - store - (dch/update-shapes [(:id shape1')] - (fn [shape] - (merge shape {:fill-color clr/test - :fill-opacity 0.5}))) - (dwl/update-component-sync (:id instance1) (:id file)) - :the/end)))) - -(t/deftest test-update-preserve-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)) - (thp/instantiate-component :instance2 - (thp/id :component1))) - - file (wsh/get-local-file state) - - [instance1 shape1'] - (thl/resolve-instance state (thp/id :instance1)) - - [_instance2 shape1''] - (thl/resolve-instance state (thp/id :instance2)) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;; - ;; [Page] - ;; Root Frame - ;; Rect 1 - ;; Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1* ---> Rect 1 - ;; #{:stroke-group} - ;; - ;; [Rect 1] - ;; page1 / Rect 1 - ;; - (let [[[main1 shape1] [c-main1 c-shape1] component1] - (thl/resolve-instance-and-main - new-state - (thp/id :main1)) - - [[instance1 shape2] [c-instance1 c-shape2] component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance1)) - - [[instance2 shape3] [c-instance2 c-shape3] component3] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2))] - - (t/is (= (:name main1) "Rect 1")) - (t/is (= (:touched main1) nil)) - (t/is (= (:shape-ref main1) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:fill-color shape1) clr/test)) - (t/is (= (:stroke-width shape1) 0.5)) - (t/is (= (:touched shape1) nil)) - (t/is (= (:shape-ref shape1) nil)) - - (t/is (= (:name instance1) "Rect 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:shape-ref instance1) (:id c-main1))) - (t/is (= (:name shape2) "Rect 1")) - (t/is (= (:fill-color shape2) clr/test)) - (t/is (= (:stroke-width shape2) 0.5)) - (t/is (= (:touched shape2) nil)) - (t/is (= (:shape-ref shape2) (:id c-shape1))) - - (t/is (= (:name instance2) "Rect 1")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:shape-ref instance2) (:id c-main1))) - (t/is (= (:name shape3) "Rect 1")) - (t/is (= (:fill-color shape3) clr/test)) - (t/is (= (:stroke-width shape3) 0.2)) - (t/is (= (:touched shape3) #{:stroke-group})) - (t/is (= (:shape-ref shape3) (:id c-shape1))) - - (t/is (= component1 component2 component3)) - (t/is (= c-main1 main1)) - (t/is (= c-shape1 shape1)) - (t/is (= c-instance1 c-main1)) - (t/is (= c-shape2 c-shape1)) - (t/is (= c-instance2 c-main1)) - (t/is (= c-shape3 c-shape1)))))] - - (ptk/emit! - store - (dch/update-shapes [(:id shape1')] - (fn [shape] - (merge shape {:fill-color clr/test - :stroke-width 0.5}))) - (dch/update-shapes [(:id shape1'')] - (fn [shape] - (merge shape {:stroke-width 0.2}))) - (dwl/update-component-sync (:id instance1) (:id file)) - :the/end)))) - -(t/deftest test-update-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/instantiate-component :instance2 - (thp/id :component1)) - (thp/sample-shape :shape2 :circle - {:name "Circle 1"})) - - file (wsh/get-local-file state) - - 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} # - ;; Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Circle 1 - ;; - ;; ========= Local library - ;; - ;; [Component: Rect 1] - ;; --> [Page 1] Rect 1 - ;; - (let [[[main1 shape1] - [c-main1 c-shape1] component1] - (thl/resolve-instance-and-main - new-state - (thp/id :main1)) - - [[instance1 shape2] - [c-instance1 c-shape2] component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance1)) - - [[instance2 shape3] - [c-instance2 c-shape3] component3] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2))] - - (t/is (= (:name main1) "Rect 1")) - (t/is (= (:touched main1) nil)) - (t/is (= (:shape-ref main1) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:touched shape1) nil)) - (t/is (= (:shape-ref shape1) nil)) - - (t/is (= (:name instance1) "Rect 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:shape-ref instance1) (:id c-main1))) - (t/is (= (:name shape2) "Rect 1")) - (t/is (= (:touched shape2) nil)) - (t/is (= (:shape-ref shape2) (:id c-shape1))) - - (t/is (= (:name instance2) "Rect 1")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:shape-ref instance2) (:id c-main1))) - (t/is (= (:name shape3) "Rect 1")) - (t/is (= (:touched shape3) nil)) - (t/is (= (:shape-ref shape2) (:id c-shape1))) - - (t/is (= component1 component2 component3)) - (t/is (= c-main1 main1)) - (t/is (= c-shape1 shape1)) - (t/is (= c-instance1 c-main1)) - (t/is (= c-shape2 c-shape1)) - (t/is (= c-instance2 c-main1)) - (t/is (= c-shape3 c-shape1)))))] - - (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 - (dwl/update-component-sync (:id instance1) (:id file)) - :the/end)))) - -(t/deftest test-update-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)) - (thp/instantiate-component :instance2 - (thp/id :component1))) - - file (wsh/get-local-file state) - - [instance1 shape1' _shape2'] - (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 - ;; Rect 2 ---> Rect 2 - ;; Component 1 #--> Component 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 2 ---> Rect 2 - ;; - ;; [Component 1] - ;; page1 / Component 1 - ;; - (let [[[main1 shape1 shape2] - [c-main1 c-shape1 c-shape2] component1] - (thl/resolve-instance-and-main - new-state - (thp/id :main1)) - - [[instance1 shape3 shape4] - [c-instance1 c-shape3 c-shape4] component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance1)) - - [[instance2 shape5 shape6] - [c-instance2 c-shape5 c-shape6] component3] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2))] - - (t/is (= (:name main1) "Component 1")) - (t/is (= (:touched main1) nil)) - (t/is (= (:shape-ref main1) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:hidden shape1) true)) ;; Instance shapes are not deleted but hidden - (t/is (= (:touched shape1) nil)) - (t/is (= (:shape-ref shape1) nil)) - (t/is (= (:name shape2) "Rect 2")) - (t/is (= (:hidden shape2) nil)) - (t/is (= (:touched shape2) nil)) - (t/is (= (:shape-ref shape2) nil)) - - (t/is (= (:name instance1) "Component 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:shape-ref instance1) (:id c-main1))) - (t/is (= (:name shape3) "Rect 1")) - (t/is (= (:hidden shape3) true)) - (t/is (= (:touched shape3) nil)) - (t/is (= (:shape-ref shape3) (:id c-shape1))) - (t/is (= (:name shape4) "Rect 2")) - (t/is (= (:hidden shape4) nil)) - (t/is (= (:touched shape4) nil)) - (t/is (= (:shape-ref shape4) (:id c-shape2))) - - (t/is (= (:name instance2) "Component 1")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:shape-ref instance2) (:id c-main1))) - (t/is (= (:name shape5) "Rect 1")) - (t/is (= (:hidden shape5) true)) - (t/is (= (:touched shape5) nil)) - (t/is (= (:shape-ref shape5) (:id c-shape1))) - (t/is (= (:name shape6) "Rect 2")) - (t/is (= (:hidden shape6) nil)) - (t/is (= (:touched shape6) nil)) - (t/is (= (:shape-ref shape6) (:id c-shape2))) - - (t/is (= component1 component2 component3)) - (t/is (= c-main1 main1)) - (t/is (= c-shape1 shape1)) - (t/is (= c-shape2 shape2)) - (t/is (= c-instance1 c-main1)) - (t/is (= c-shape3 c-shape1)) - (t/is (= c-shape4 c-shape2)) - (t/is (= c-instance2 c-main1)) - (t/is (= c-shape5 c-shape1)) - (t/is (= c-shape6 c-shape2)))))] - - (ptk/emit! - store - (dwsh/delete-shapes #{(:id shape1')}) - (dwl/update-component-sync (:id instance1) (:id file)) - :the/end)))) - -(t/deftest test-update-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)) - (thp/instantiate-component :instance2 - (thp/id :component1))) - - file (wsh/get-local-file state) - - [instance1 shape1' _shape2' _shape3'] - (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 - ;; Rect 3 - ;; Component 1 #--> Component 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 2 ---> Rect 2 - ;; Rect 3 ---> Rect 3 - ;; Component 1 #--> Component 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 2 ---> Rect 2 - ;; Rect 3 ---> Rect 3 - ;; - ;; [Component 1] - ;; page1 / Component 1 - ;; - (let [[[main1 shape1 shape2 shape3] - [c-main1 c-shape1 c-shape2 c-shape3] component1] - (thl/resolve-instance-and-main - new-state - (thp/id :main1)) - - [[instance1 shape4 shape5 shape6] - [c-instance1 c-shape4 c-shape5 c-shape6] component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance1)) - - [[instance2 shape7 shape8 shape9] - [c-instance2 c-shape7 c-shape8 c-shape9] component3] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2))] - - (t/is (= (:name main1) "Component 1")) - (t/is (= (:touched main1) nil)) - (t/is (= (:shape-ref main1) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:touched shape1) nil)) - (t/is (= (:shape-ref shape1) nil)) - (t/is (= (:name shape2) "Rect 2")) - (t/is (= (:touched shape2) nil)) - (t/is (= (:shape-ref shape2) nil)) - (t/is (= (:name shape3) "Rect 3")) - (t/is (= (:touched shape3) nil)) - (t/is (= (:shape-ref shape3) nil)) - - (t/is (= (:name instance1) "Component 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:shape-ref instance1) (:id c-main1))) - (t/is (= (:name shape4) "Rect 1")) - (t/is (= (:touched shape4) nil)) - (t/is (= (:shape-ref shape4) (:id c-shape1))) - (t/is (= (:name shape5) "Rect 2")) - (t/is (= (:touched shape5) nil)) - (t/is (= (:shape-ref shape5) (:id c-shape2))) - (t/is (= (:name shape6) "Rect 3")) - (t/is (= (:touched shape6) nil)) - (t/is (= (:shape-ref shape6) (:id c-shape3))) - - (t/is (= (:name instance2) "Component 1")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:shape-ref instance2) (:id c-main1))) - (t/is (= (:name shape7) "Rect 1")) - (t/is (= (:touched shape7) nil)) - (t/is (= (:shape-ref shape7) (:id c-shape1))) - (t/is (= (:name shape8) "Rect 2")) - (t/is (= (:touched shape8) nil)) - (t/is (= (:shape-ref shape8) (:id c-shape2))) - (t/is (= (:name shape9) "Rect 3")) - (t/is (= (:touched shape9) nil)) - (t/is (= (:shape-ref shape9) (:id c-shape3))) - - (t/is (= component1 component2 component3)) - (t/is (= c-main1 main1)) - (t/is (= c-shape1 shape1)) - (t/is (= c-shape2 shape2)) - (t/is (= c-shape3 shape3)) - (t/is (= c-instance1 c-main1)) - (t/is (= c-shape4 c-shape4)) - (t/is (= c-shape5 c-shape5)) - (t/is (= c-shape6 c-shape6)) - (t/is (= c-instance2 c-main1)) - (t/is (= c-shape7 c-shape7)) - (t/is (= c-shape8 c-shape8)) - (t/is (= c-shape9 c-shape9)))))] - - (ptk/emit! - store - (dw/relocate-shapes #{(:id shape1')} (:id instance1) 2) - (dwl/update-component-sync (:id instance1) (:id file)) - :the/end)))) - -(t/deftest test-update-from-lib - (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/move-to-library :lib1 "Library 1") - (thp/sample-page) - (thp/instantiate-component :instance1 - (thp/id :component1) - (thp/id :lib1)) - (thp/instantiate-component :instance2 - (thp/id :component1) - (thp/id :lib1))) - - [instance1 shape1'] - (thl/resolve-instance state (thp/id :instance1)) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;; - ;; [Page] - ;; Root Frame - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; - (let [[[instance1 shape1] [c-instance1 c-shape1] _component1] - (thl/resolve-instance-and-main - new-state - (thp/id :instance1)) - - [[instance2 shape2] [_c-instance2 _c-shape2] _component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2))] - - (t/is (= (:name instance1) "Rect 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:name shape1) "Rect 1")) - (t/is (= (:fill-color shape1) clr/test)) - (t/is (= (:fill-opacity shape1) 0.5)) - (t/is (= (:touched shape1) nil)) - - (t/is (= (:name c-instance1) "Rect 1")) - (t/is (= (:touched c-instance1) nil)) - (t/is (= (:name c-shape1) "Rect 1")) - (t/is (= (:fill-color c-shape1) clr/test)) - (t/is (= (:fill-opacity c-shape1) 0.5)) - (t/is (= (:touched c-shape1) nil)) - - (t/is (= (:name instance2) "Rect 1")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:name shape2) "Rect 1")) - (t/is (= (:fill-color shape2) clr/test)) - (t/is (= (:fill-opacity shape2) 0.5)) - (t/is (= (:touched shape2) nil)))))] - - (ptk/emit! - store - (dch/update-shapes [(:id shape1')] - (fn [shape] - (merge shape {:fill-color clr/test - :fill-opacity 0.5}))) - (dwl/update-component-sync (:id instance1) (thp/id :lib1)) - :the/end)))) - -(t/deftest test-update-nested-upper - (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" - :fill-color clr/black - :fill-opacity 0}) - (thp/frame-shapes :frame1 - [(thp/id :instance1) - (thp/id :shape2)]) - (thp/make-component :main2 :component2 - [(thp/id :frame1)]) - (thp/instantiate-component :instance2 - (thp/id :component2)) - (thp/instantiate-component :instance3 - (thp/id :component2))) - - file (wsh/get-local-file state) - - [instance2 _instance1 shape1' _shape2'] - (thl/resolve-instance state (thp/id :instance2)) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;; - ;; [Page] - ;; Root Frame - ;; Rect 1 - ;; Rect 1 - ;; Group - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Circle 1 - ;; Group #--> Group - ;; Rect 1 @--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Circle 1 ---> Circle 1 - ;; Group #--> Group - ;; Rect 1 @--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Circle 1 ---> Circle 1 - ;; - ;; [Rect 1] - ;; page1 / Rect 1 - ;; - ;; [Group] - ;; page1 / Group - ;; - (let [[[instance2 instance1 shape1 shape2] - [c-instance2 c-instance1 c-shape1 c-shape2] _component1] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2)) - - [[instance4 instance3 shape3 shape4] - [_c-instance4 _c-instance3 _c-shape3 _c-shape4] _component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance3))] - - (t/is (= (:name instance2) "Board")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:name shape1) "Circle 1")) - (t/is (= (:touched shape1) nil)) - (t/is (= (:fill-color shape1) clr/test)) - (t/is (= (:fill-opacity shape1) 0.5)) - (t/is (= (:name shape2) "Rect 1")) - (t/is (= (:touched shape2) nil)) - (t/is (= (:fill-color shape2) clr/white)) - (t/is (= (:fill-opacity shape2) 1)) - - (t/is (= (:name c-instance2) "Board")) - (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1")) - (t/is (= (:touched c-instance1) nil)) - (t/is (= (:name c-shape1) "Circle 1")) - (t/is (= (:touched c-shape1) nil)) - (t/is (= (:fill-color c-shape1) clr/test)) - (t/is (= (:fill-opacity c-shape1) 0.5)) - (t/is (= (:name c-shape2) "Rect 1")) - (t/is (= (:touched c-shape2) nil)) - (t/is (= (:fill-color c-shape2) clr/white)) - (t/is (= (:fill-opacity c-shape2) 1)) - - (t/is (= (:name instance4) "Board")) - (t/is (= (:touched instance4) nil)) - (t/is (= (:name instance3) "Rect 1")) - (t/is (= (:touched instance3) nil)) - (t/is (= (:name shape3) "Circle 1")) - (t/is (= (:touched shape3) nil)) - (t/is (= (:fill-color shape3) clr/test)) - (t/is (= (:fill-opacity shape3) 0.5)) - (t/is (= (:name shape4) "Rect 1")) - (t/is (= (:touched shape4) nil)) - (t/is (= (:fill-color shape4) clr/white)) - (t/is (= (:fill-opacity shape4) 1)))))] - - (ptk/emit! - store - (dch/update-shapes [(:id shape1')] - (fn [shape] - (merge shape {:fill-color clr/test - :fill-opacity 0.5}))) - (dwl/update-component-sync (:id instance2) (:id file)) - :the/end)))) - -(t/deftest test-update-nested-lower-near - (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" - :fill-color clr/black - :fill-opacity 0}) - (thp/frame-shapes :frame1 - [(thp/id :instance1) - (thp/id :shape2)]) - (thp/make-component :main2 :component2 - [(thp/id :frame1)]) - (thp/instantiate-component :instance2 - (thp/id :component2)) - (thp/instantiate-component :instance3 - (thp/id :component2))) - - file (wsh/get-local-file state) - - [instance2 instance1 _shape1' shape2'] - (thl/resolve-instance state (thp/id :instance2)) - - store (the/prepare-store state done - (fn [new-state] - ;; Expected shape tree: - ;; - ;; [Page] - ;; Root Frame - ;; Rect 1 - ;; Rect 1 - ;; Group - ;; Rect 1 #--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Circle 1 - ;; Group #--> Group - ;; Rect 1 @--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Circle 1 ---> Circle 1 - ;; Group #--> Group - ;; Rect 1 @--> Rect 1 - ;; Rect 1 ---> Rect 1 - ;; Circle 1 ---> Circle 1 - ;; - ;; [Rect 1] - ;; page1 / Rect 1 - ;; - ;; [Group] - ;; page1 / Group - ;; - (let [[[instance2 instance1 shape1 shape2] - [c-instance2 c-instance1 c-shape1 c-shape2] _component1] - (thl/resolve-instance-and-main - new-state - (thp/id :instance2)) - - [[instance4 instance3 shape3 shape4] - [_c-instance4 _c-instance3 _c-shape3 _c-shape4] _component2] - (thl/resolve-instance-and-main - new-state - (thp/id :instance3))] - - (t/is (= (:name instance2) "Board")) - (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1")) - (t/is (= (:touched instance1) nil)) - (t/is (= (:name shape1) "Circle 1")) - (t/is (= (:touched shape1) nil)) - (t/is (= (:fill-color shape1) clr/black)) - (t/is (= (:fill-opacity shape1) 0)) - (t/is (= (:name shape2) "Rect 1")) - (t/is (= (:touched shape2) nil)) - (t/is (= (:fill-color shape2) clr/test)) - (t/is (= (:fill-opacity shape2) 0.5)) - - (t/is (= (:name c-instance2) "Board")) - (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1")) - (t/is (= (:touched c-instance1) nil)) - (t/is (= (:name c-shape1) "Circle 1")) - (t/is (= (:touched c-shape1) nil)) - (t/is (= (:fill-color c-shape1) clr/black)) - (t/is (= (:fill-opacity c-shape1) 0)) - (t/is (= (:name c-shape2) "Rect 1")) - (t/is (= (:touched c-shape2) nil)) - (t/is (= (:fill-color c-shape2) clr/test)) - (t/is (= (:fill-opacity c-shape2) 0.5)) - - (t/is (= (:name instance4) "Board")) - (t/is (= (:touched instance4) nil)) - (t/is (= (:name instance3) "Rect 1")) - (t/is (= (:touched instance3) nil)) - (t/is (= (:name shape3) "Circle 1")) - (t/is (= (:touched shape3) nil)) - (t/is (= (:fill-color shape3) clr/black)) - (t/is (= (:fill-opacity shape3) 0)) - (t/is (= (:name shape4) "Rect 1")) - (t/is (= (:touched shape4) nil)) - (t/is (= (:fill-color shape4) clr/test)) - (t/is (= (:fill-opacity shape4) 0.5)))))] - - (ptk/emit! - store - (dch/update-shapes [(:id shape2')] - (fn [shape] - (merge shape {:fill-color clr/test - :fill-opacity 0.5}))) - (dwl/update-component (:id instance1)) - (dwl/update-component-sync (:id instance2) (:id file)) - :the/end)))) - -;; (t/deftest test-update-nested-lower-remote -;; (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" -;; :fill-color clr/black -;; :fill-opacity 0}) -;; (thp/frame-shapes :frame1 -;; [(thp/id :instance1) -;; (thp/id :shape2)]) -;; (thp/make-component :main2 :component2 -;; [(thp/id :frame1)]) -;; (thp/instantiate-component :instance2 -;; (thp/id :component2)) -;; (thp/instantiate-component :instance3 -;; (thp/id :component2))) -;; -;; file (wsh/get-local-file state) -;; -;; [_instance2 instance1 _shape1' shape2'] -;; (thl/resolve-instance state (thp/id :instance2)) -;; -;; store (the/prepare-store state done -;; (fn [new-state] -;; ;; Expected shape tree: -;; ;; -;; ;; [Page] -;; ;; Root Frame -;; ;; Rect 1 -;; ;; Rect 1 -;; ;; Group -;; ;; Rect 1 #--> Rect 1 -;; ;; Rect 1 ---> Rect 1 -;; ;; Circle 1 -;; ;; Group #--> Group -;; ;; Rect 1 @--> Rect 1 -;; ;; (remote-synced) -;; ;; Rect 1 ---> Rect 1 -;; ;; (remote-synced) -;; ;; Circle 1 ---> Circle 1 -;; ;; Group #--> Group -;; ;; Rect 1 @--> Rect 1 -;; ;; Rect 1 ---> Rect 1 -;; ;; Circle 1 ---> Circle 1 -;; ;; -;; ;; [Rect 1] -;; ;; page1 / Rect 1 -;; ;; -;; ;; [Group] -;; ;; page1 / Group -;; ;; -;; (let [[[instance2 instance1 shape1 shape2] -;; [c-instance2 c-instance1 c-shape1 c-shape2] _component1] -;; (thl/resolve-instance-and-main -;; new-state -;; (thp/id :instance2)) -;; -;; [[instance4 instance3 shape3 shape4] -;; [_c-instance4 _c-instance3 _c-shape3 _c-shape4] _component2] -;; (thl/resolve-instance-and-main -;; new-state -;; (thp/id :instance3))] -;; -;; (t/is (= (:name instance2) "Board")) -;; (t/is (= (:touched instance2) nil)) -;; (t/is (= (:name instance1) "Rect 1")) -;; (t/is (= (:touched instance1) nil)) -;; (t/is (= (:name shape1) "Circle 1")) -;; (t/is (= (:touched shape1) nil)) -;; (t/is (= (:fill-color shape1) clr/black)) -;; (t/is (= (:fill-opacity shape1) 0)) -;; (t/is (= (:name shape2) "Rect 1")) -;; (t/is (= (:touched shape2) nil)) -;; (t/is (= (:fill-color shape2) clr/test)) -;; (t/is (= (:fill-opacity shape2) 0.5)) -;; -;; (t/is (= (:name c-instance2) "Board")) -;; (t/is (= (:touched c-instance2) nil)) -;; (t/is (= (:name c-instance1) "Rect 1")) -;; (t/is (= (:touched c-instance1) nil)) -;; (t/is (= (:name c-shape1) "Circle 1")) -;; (t/is (= (:touched c-shape1) nil)) -;; (t/is (= (:fill-color c-shape1) clr/black)) -;; (t/is (= (:fill-opacity c-shape1) 0)) -;; (t/is (= (:name c-shape2) "Rect 1")) -;; (t/is (= (:touched c-shape2) nil)) -;; (t/is (= (:fill-color c-shape2) clr/test)) -;; (t/is (= (:fill-opacity c-shape2) 0.5)) -;; -;; (t/is (= (:name instance4) "Board")) -;; (t/is (= (:touched instance4) nil)) -;; (t/is (= (:name instance3) "Rect 1")) -;; (t/is (= (:touched instance3) nil)) -;; (t/is (= (:name shape3) "Circle 1")) -;; (t/is (= (:touched shape3) nil)) -;; (t/is (= (:fill-color shape3) clr/black)) -;; (t/is (= (:fill-opacity shape3) 0)) -;; (t/is (= (:name shape4) "Rect 1")) -;; (t/is (= (:touched shape4) nil)) -;; (t/is (= (:fill-color shape4) clr/test)) -;; (t/is (= (:fill-opacity shape4) 0.5)))))] -;; -;; (ptk/emit! -;; store -;; (dch/update-shapes [(:id shape2')] -;; (fn [shape] -;; (merge shape {:fill-color clr/test -;; :fill-opacity 0.5}))) -;; (dwl/update-component-sync (:id instance1) (:id file)) -;; :the/end))))