From 2e3addc6dad7ee0d80de5d9d5a6585d9de1e585b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Tue, 22 Mar 2022 19:01:34 +0100 Subject: [PATCH] :tada: Add more unit tests --- frontend/test/app/components_basic_test.cljs | 2 + frontend/test/app/components_sync_test.cljs | 1403 +++++++++++++++-- frontend/test/app/test_helpers/libraries.cljs | 2 +- 3 files changed, 1269 insertions(+), 138 deletions(-) diff --git a/frontend/test/app/components_basic_test.cljs b/frontend/test/app/components_basic_test.cljs index 591b353d2..b392e7100 100644 --- a/frontend/test/app/components_basic_test.cljs +++ b/frontend/test/app/components_basic_test.cljs @@ -597,6 +597,8 @@ new-state new-instance-id)] + ; TODO: get and check the instance inside component [Rect-2] + (t/is (not= (:id instance1) (:id instance3))) (t/is (= (:id component) component-id)) (t/is (= (:name instance3) "Rect-3")) diff --git a/frontend/test/app/components_sync_test.cljs b/frontend/test/app/components_sync_test.cljs index 2b2c79c95..a34af0f16 100644 --- a/frontend/test/app/components_sync_test.cljs +++ b/frontend/test/app/components_sync_test.cljs @@ -22,6 +22,8 @@ (t/use-fixtures :each {:before thp/reset-idmap!}) +; === Test touched ====================== + (t/deftest test-touched (t/async done (try @@ -47,26 +49,28 @@ ; [Page] ; Root Frame ; Rect 1-1 #--> Rect 1-1 - ; Rect 1* ---> Rect 1 + ; Rect 1* ---> Rect 1 (color, opacity) ; #{:fill-group} ; ; [Rect 1] ; Rect 1-1 ; Rect 1 ; - (let [instance1 (thp/get-shape new-state :instance1) - shape1 (thp/get-shape new-state :shape1) - - [[group shape1] [c-group c-shape1] component] + (let [[[group shape1] [c-group c-shape1] component] (thl/resolve-instance-and-main new-state - (:id instance1))] + (thp/id :instance1))] - (t/is (= (:touched instance1) nil)) + (t/is (= (:name group) "Rect 1-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-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)))))] @@ -108,22 +112,26 @@ ; Rect 1-1 ; Rect 1 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape1 shape2] [c-group c-shape1] component] + (let [[[group shape1 shape2] [c-group c-shape1] component] (thl/resolve-instance-and-main-allow-dangling new-state - (:id instance1))] + (thp/id :instance1))] + (t/is (= (:name group) "Rect 1-1")) (t/is (= (:touched group) #{:shapes-group})) - (t/is (nil? (:touched shape1))) (t/is (= (:name shape1) "Circle 1")) - (t/is (nil? (:shape-ref shape1))) - (t/is (nil? (:touched shape2))) + (t/is (= (:touched shape1) nil)) + (t/is (= (:shape-ref shape1) nil)) (t/is (= (:name shape2) "Rect 1")) - (t/is (some? (:shape-ref shape2))) - (t/is (nil? (:touched c-group))) - (t/is (nil? (:touched c-shape1))))))] + (t/is (= (:touched shape2) nil)) + (t/is (not= (:shape-ref shape2) nil)) + + (t/is (= (:name c-group) "Rect 1-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 @@ -160,19 +168,27 @@ ; Rect 1 ; Rect 2 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape2] [c-group c-shape2] component] + (let [[[group shape2] [c-group c-shape2 c-shape3] component] (thl/resolve-instance-and-main-allow-dangling new-state - (:id instance1))] + (thp/id :instance1))] + (t/is (= (:name group) "Component-1")) (t/is (= (:touched group) #{:shapes-group})) - (t/is (nil? (:touched shape2))) + (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape2) "Rect 2")) - (t/is (some? (:shape-ref shape2))) - (t/is (nil? (:touched c-group))) - (t/is (nil? (:touched c-shape2))))))] + (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-shape2) "Rect 1")) + (t/is (= (:touched c-shape2) nil)) + (t/is (= (:shape-ref c-shape2) nil)) + (t/is (= (:name c-shape3) "Rect 2")) + (t/is (= (:touched c-shape3) nil)) + (t/is (= (:shape-ref c-shape3) nil)))))] (ptk/emit! store @@ -216,37 +232,370 @@ ; Rect 2 ; Rect 3 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape1 shape2 shape3] + (let [[[group shape1 shape2 shape3] [c-group c-shape1 c-shape2 c-shape3] component] (thl/resolve-instance-and-main-allow-dangling new-state - (:id instance1))] + (thp/id :instance1))] + (t/is (= (:name group) "Component-1")) (t/is (= (:touched group) #{:shapes-group})) - (t/is (nil? (:touched shape1))) - (t/is (some? (:shape-ref shape1))) (t/is (= (:name shape1) "Rect 2")) - (t/is (nil? (:touched shape2))) - (t/is (some? (:shape-ref shape2))) + (t/is (= (:touched shape1) nil)) + (t/is (not= (:shape-ref shape1) nil)) (t/is (= (:name shape2) "Rect 1")) - (t/is (nil? (:touched shape3))) - (t/is (some? (:shape-ref shape3))) + (t/is (= (:touched shape2) nil)) + (t/is (not= (:shape-ref shape2) nil)) (t/is (= (:name shape3) "Rect 3")) - (t/is (nil? (:touched c-group))) - (t/is (nil? (:touched c-shape1))) + (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 (nil? (:touched c-shape2))) + (t/is (= (:touched c-shape1) nil)) + (t/is (= (:shape-ref c-shape1) nil)) (t/is (= (:name c-shape2) "Rect 2")) - (t/is (nil? (:touched c-shape3))) - (t/is (= (:name c-shape3) "Rect 3")))))] + (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 instance1) 2) :the/end))))) +(t/deftest test-touched-from-lib + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/move-to-library :lib1 "Library 1") + (thp/sample-page) + (thp/instantiate-component :instance2 + (thp/id :component-1) + (thp/id :lib1))) + + [instance2 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Rect 1-1 #--> Rect 1-1 + ; Rect 1* ---> Rect 1 (color, opacity) + ; #{:fill-group} + ; + (let [[[group shape1] [c-group c-shape1] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + (t/is (= (:name group) "Rect 1-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-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 shape2)] update-fn) + :the/end))))) + +(t/deftest test-touched-nested-upper + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1* #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1* ---> Circle 1 (color, opacity) + ; #{:fill-group} + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:touched instance1) nil)) + (t/is (= (:name shape1) "Circle 1")) + (t/is (= (:touched shape1) #{:fill-group})) + (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) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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/white)) + (t/is (= (:fill-opacity c-shape2) 1)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape1)] update-fn) + :the/end))))) + +(t/deftest test-touched-nested-lower-near + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1 #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1* ---> Rect 1 (color, opacity) + ; #{:fill-group} + ; Circle 1 ---> Circle 1 + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-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) #{:fill-group})) + (t/is (= (:fill-color shape2) clr/test)) + (t/is (= (:fill-opacity shape2) 0.5)) + + (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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/white)) + (t/is (= (:fill-opacity c-shape2) 1)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape2)] update-fn) + :the/end))))) + +(t/deftest test-touched-nested-lower-remote + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1 #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 (color, opacity) + ; Circle 1 ---> Circle 1 + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1* ---> Rect 1 (color, opacity) + ; #{:fill-group} + ; Circle 1 + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-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) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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) #{:fill-group})) + (t/is (= (:fill-color c-shape2) clr/test)) + (t/is (= (:fill-opacity c-shape2) 0.5)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape2)] update-fn) + (dwl/update-component (:id instance2)) + :the/end))))) + +; === Test reset changes ====================== + (t/deftest test-reset-changes (t/async done (try @@ -274,21 +623,26 @@ ; Root Frame ; Rect 1-1 #--> Rect 1-1 ; Rect 1 ---> Rect 1 - ; + ; ; [Rect 1] ; Rect 1-1 ; Rect 1 ; - (let [shape1 (thp/get-shape new-state :shape1) - - [[group shape1] [c-group c-shape1] component] + (let [[[group shape1] [c-group c-shape1] component] (thl/resolve-instance-and-main new-state (:id instance1))] + (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:touched group) nil)) + (t/is (= (:name shape1) "Rect 1")) (t/is (= (:fill-color shape1) clr/white)) (t/is (= (:fill-opacity shape1) 1)) (t/is (= (:touched shape1) nil)) + + (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:touched c-group) nil)) + (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:fill-color c-shape1) clr/white)) (t/is (= (:fill-opacity c-shape1) 1)) (t/is (= (:touched c-shape1) nil)))))] @@ -329,16 +683,24 @@ ; Rect 1-1 ; Rect 1 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape1] [c-group c-shape1] component] + (let [[[group shape1] [c-group c-shape1] component] (thl/resolve-instance-and-main new-state - (:id instance1))] + (thp/id :instance1))] - (t/is (nil? (:touched instance1))) + (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:touched group) nil)) + (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape1) "Rect 1")) - (t/is (some? (:shape-ref shape1))))))] + (t/is (= (:touched shape1) nil)) + (t/is (not= (:shape-ref shape1) nil)) + + (t/is (= (:name c-group) "Rect 1-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 @@ -368,23 +730,40 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Component-1 #--> Component-1 ; Rect 1 ---> Rect 1 + ; Rect 2 ---> Rect 2 ; - ; [Rect 1] - ; Rect 1-1 + ; [Component-1] + ; Component-1 ; Rect 1 + ; Rect 2 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape1] [c-group c-shape1] component] + (let [[[group shape1 shape2] + [c-group c-shape1 c-shape2] component] (thl/resolve-instance-and-main new-state - (:id instance1))] + (thp/id :instance1))] - (t/is (nil? (:touched 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 (some? (:shape-ref shape1))))))] + (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 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 @@ -428,30 +807,36 @@ ; Rect 2 ; Rect 3 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape1 shape2 shape3] [c-group c-shape1 c-shape2 c-shape3] component] + (let [[[group shape1 shape2 shape3] [c-group c-shape1 c-shape2 c-shape3] component] (thl/resolve-instance-and-main new-state - (:id instance1))] + (thp/id :instance1))] - (t/is (nil? (:touched group))) - (t/is (nil? (:touched shape1))) - (t/is (some? (:shape-ref shape1))) + (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 (nil? (:touched shape2))) - (t/is (some? (:shape-ref shape2))) + (t/is (= (:touched shape1) nil)) + (t/is (not= (:shape-ref shape1) nil)) (t/is (= (:name shape2) "Rect 2")) - (t/is (nil? (:touched shape3))) - (t/is (some? (:shape-ref shape3))) + (t/is (= (:touched shape2) nil)) + (t/is (not= (:shape-ref shape2) nil)) (t/is (= (:name shape3) "Rect 3")) - (t/is (nil? (:touched c-group))) - (t/is (nil? (:touched c-shape1))) + (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 (nil? (:touched c-shape2))) + (t/is (= (:touched c-shape1) nil)) + (t/is (= (:shape-ref c-shape1) nil)) (t/is (= (:name c-shape2) "Rect 2")) - (t/is (nil? (:touched c-shape3))) - (t/is (= (:name c-shape3) "Rect 3")))))] + (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 @@ -459,6 +844,336 @@ (dwl/reset-component (:id instance1)) :the/end))))) +(t/deftest test-reset-from-lib + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/move-to-library :lib1 "Library 1") + (thp/sample-page) + (thp/instantiate-component :instance2 + (thp/id :component-1) + (thp/id :lib1))) + + [instance2 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; + (let [[[group shape1] [c-group c-shape1] component] + (thl/resolve-instance-and-main + new-state + (:id instance2))] + + (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:touched group) nil)) + (t/is (= (:name shape1) "Rect 1")) + (t/is (= (:fill-color shape1) clr/white)) + (t/is (= (:fill-opacity shape1) 1)) + (t/is (= (:touched shape1) nil)) + + (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:touched c-group) nil)) + (t/is (= (:name c-shape1) "Rect 1")) + (t/is (= (:fill-color c-shape1) clr/white)) + (t/is (= (:fill-opacity c-shape1) 1)) + (t/is (= (:touched c-shape1) nil)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape2)] update-fn) + (dwl/reset-component (:id instance2)) + :the/end))))) + +(t/deftest test-reset-nested-upper + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1 #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 ---> Circle 1 + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-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/white)) + (t/is (= (:fill-opacity shape2) 1)) + + (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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/white)) + (t/is (= (:fill-opacity c-shape2) 1)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape1)] update-fn) + (dwl/reset-component (:id instance2)) + :the/end))))) + +(t/deftest test-reset-nested-lower-near + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1 #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 ---> Circle 1 + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 (color, opacity) + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-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/white)) + (t/is (= (:fill-opacity shape2) 1)) + + (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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/white)) + (t/is (= (:fill-opacity c-shape2) 1)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape2)] update-fn) + (dwl/update-component (:id instance1)) + (dwl/reset-component (:id instance2)) + :the/end))))) + +(t/deftest test-reset-nested-lower-remote + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1 #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 ---> Circle 1 + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 (color, opacity) + ; #{:fill-group} + ; Circle 1 + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-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/white)) + (t/is (= (:fill-opacity shape2) 1)) + + (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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) #{:fill-group})) + (t/is (= (:fill-color c-shape2) clr/test)) + (t/is (= (:fill-opacity c-shape2) 0.5)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape2)] update-fn) + (dwl/update-component (:id instance2)) + (dwl/reset-component (:id instance1)) + :the/end))))) + +; === Test update component ====================== + (t/deftest test-update-component (t/async done (try @@ -469,10 +1184,13 @@ :fill-color clr/white :fill-opacity 1}) (thp/make-component :instance1 :component-1 - [(thp/id :shape1)])) + [(thp/id :shape1)]) + (thp/instantiate-component :instance2 + (thp/id :component-1))) shape1 (thp/get-shape state :shape1) instance1 (thp/get-shape state :instance1) + instance2 (thp/get-shape state :instance2) update-fn (fn [shape] (merge shape {:fill-color clr/test @@ -485,23 +1203,48 @@ ; [Page] ; Root Frame ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 ---> Rect 1 (color, opacity) + ; Rect 1-2 ; Rect 1 ---> Rect 1 - ; + ; ; [Rect 1] ; Rect 1-1 - ; Rect 1 + ; Rect 1 (color, opacity) ; - (let [[[group shape1] [c-group c-shape1] component] + (let [[[instance1 shape1] [c-instance1 c-shape1] component1] (thl/resolve-instance-and-main new-state - (:id instance1))] + (:id instance1)) + [[instance2 shape2] [c-instance2 c-shape2] component2] + (thl/resolve-instance-and-main + new-state + (:id instance2))] + + (t/is (= (:name instance1) "Rect 1-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 instance2) "Rect 1-2")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name shape2) "Rect 1")) + (t/is (= (:fill-color shape2) clr/white)) + (t/is (= (:fill-opacity shape2) 1)) + (t/is (= (:touched shape2) nil)) + + (t/is (= (:name c-instance1) "Rect 1-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 (= (:touched c-shape1) nil)) + + (t/is (= component1 component2)) + (t/is (= c-instance2 c-instance1)) + (t/is (= c-shape2 c-shape1)))))] (ptk/emit! store @@ -527,6 +1270,7 @@ shape1 (thp/get-shape state :shape1) instance1 (thp/get-shape state :instance1) + instance2 (thp/get-shape state :instance2) update-fn (fn [shape] (merge shape {:fill-color clr/test @@ -539,27 +1283,48 @@ ; [Page] ; Root Frame ; Rect 1-1 #--> Rect 1-1 - ; Rect 1 ---> Rect 1 + ; Rect 1 ---> Rect 1 (color, opacity) ; Rect 1-2 #--> Rect 1-1 - ; Rect 1 ---> Rect 1 + ; Rect 1 ---> Rect 1 (color, opacity) ; ; [Rect 1] ; Rect 1-1 - ; Rect 1 + ; Rect 1 (color, opacity) ; - (let [instance2 (thp/get-shape state :instance2) + (let [[[instance1 shape1] [c-instance1 c-shape1] component1] + (thl/resolve-instance-and-main + new-state + (:id instance1)) - [[group shape2] [c-group c-shape2] component] + [[instance2 shape2] [c-instance2 c-shape2] component2] (thl/resolve-instance-and-main new-state (:id instance2))] + (t/is (= (:name instance1) "Rect 1-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 instance2) "Rect 1-2")) + (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)) - (t/is (= (:fill-color c-shape2) clr/test)) - (t/is (= (:fill-opacity c-shape2) 0.5)) - (t/is (= (:touched c-shape2) nil)))))] + + (t/is (= (:name c-instance1) "Rect 1-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 (= component1 component2)) + (t/is (= c-instance2 c-instance1)) + (t/is (= c-shape2 c-shape1)))))] (ptk/emit! store @@ -604,28 +1369,49 @@ ; [Page] ; Root Frame ; Rect 1-1 #--> Rect 1-1 - ; Rect 1 ---> Rect 1 + ; Rect 1 ---> Rect 1 (color, stroke) ; Rect 1-2 #--> Rect 1-1 - ; Rect 1* ---> Rect 1 + ; Rect 1* ---> Rect 1 (color, stroke2) ; #{:stroke-group} ; ; [Rect 1] ; Rect 1-1 - ; Rect 1 + ; Rect 1 (color, stroke) ; - (let [instance2 (thp/get-shape state :instance2) + (let [[[instance1 shape1] [c-instance1 c-shape1] component1] + (thl/resolve-instance-and-main + new-state + (:id instance1)) - [[group shape2] [c-group c-shape2] component] + [[instance2 shape2] [c-instance2 c-shape2] component2] (thl/resolve-instance-and-main new-state (:id instance2))] + (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:touched instance1) 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 (= (:name instance2) "Rect 1-2")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name shape2) "Rect 1")) (t/is (= (:fill-color shape2) clr/test)) (t/is (= (:stroke-width shape2) 0.2)) - (t/is (= (:touched shape2 #{:stroke-group}))) - (t/is (= (:fill-color c-shape2) clr/test)) - (t/is (= (:stroke-width c-shape2) 0.5)) - (t/is (= (:touched c-shape2) nil)))))] + (t/is (= (:touched shape2) #{:stroke-group})) + + (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:touched c-instance1) nil)) + (t/is (= (:name c-shape1) "Rect 1")) + (t/is (= (:fill-color c-shape1) clr/test)) + (t/is (= (:stroke-width c-shape1) 0.5)) + (t/is (= (:touched c-shape1) nil)) + + (t/is (= component1 component2)) + (t/is (= c-instance2 c-instance1)) + (t/is (= c-shape2 c-shape1)))))] (ptk/emit! store @@ -668,25 +1454,31 @@ ; Circle 1 ; Rect 1 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape1 shape2] [c-group c-shape1 c-shape2] component] + (let [[[group shape1 shape2] + [c-group c-shape1 c-shape2] component] (thl/resolve-instance-and-main new-state - (:id instance1))] + (thp/id :instance1))] - (t/is (nil? (:touched group))) - (t/is (nil? (:touched shape1))) + (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:touched group) nil)) + (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape1) "Circle 1")) - (t/is (some? (:shape-ref shape1))) - (t/is (nil? (:touched shape2))) + (t/is (= (:touched shape1) nil)) + (t/is (not= (:shape-ref shape1) nil)) (t/is (= (:name shape2) "Rect 1")) - (t/is (some? (:shape-ref shape2))) - (t/is (nil? (:touched c-group))) - (t/is (nil? (:touched c-shape1))) + (t/is (= (:touched shape2) nil)) + (t/is (not= (:shape-ref shape2) nil)) + + (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:touched c-group) nil)) + (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape1) "Circle 1")) - (t/is (nil? (:touched c-shape2))) - (t/is (= (:name c-shape2) "Rect 1")))))] + (t/is (= (:touched c-shape1) nil)) + (t/is (= (:shape-ref c-shape1) nil)) + (t/is (= (:name c-shape2) "Rect 1")) + (t/is (= (:touched c-shape2) nil)) + (t/is (= (:shape-ref c-shape2) nil)))))] (ptk/emit! store @@ -725,20 +1517,24 @@ ; Component-1 ; Rect 2 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape2] [c-group c-shape2] component] + (let [[[group shape2] [c-group c-shape2] component] (thl/resolve-instance-and-main new-state - (:id instance1))] + (thp/id :instance1))] - (t/is (nil? (:touched group))) - (t/is (nil? (:touched shape2))) + (t/is (= (:name group) "Component-1")) + (t/is (= (:touched group) nil)) + (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape2) "Rect 2")) - (t/is (some? (:shape-ref shape2))) - (t/is (nil? (:touched c-group))) - (t/is (nil? (:touched c-shape2))) - (t/is (= (:name c-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-shape2) "Rect 2")) + (t/is (= (:touched c-shape2) nil)) + (t/is (= (:shape-ref c-shape2) nil)))))] (ptk/emit! store @@ -784,33 +1580,366 @@ ; Rect 1 ; Rect 3 ; - (let [instance1 (thp/get-shape new-state :instance1) - - [[group shape1 shape2 shape3] [c-group c-shape1 c-shape2 c-shape3] component] + (let [[[group shape1 shape2 shape3] [c-group c-shape1 c-shape2 c-shape3] component] (thl/resolve-instance-and-main new-state - (:id instance1))] + (thp/id :instance1))] - (t/is (nil? (:touched group))) - (t/is (nil? (:touched shape1))) - (t/is (some? (:shape-ref shape1))) + (t/is (= (:name group) "Component-1")) + (t/is (= (:touched group) nil)) + (t/is (not= (:shape-ref group) nil)) + (t/is (= (:touched shape1) nil)) + (t/is (not= (:shape-ref shape1) nil)) (t/is (= (:name shape1) "Rect 2")) - (t/is (nil? (:touched shape2))) - (t/is (some? (:shape-ref shape2))) + (t/is (= (:touched shape2) nil)) + (t/is (not= (:shape-ref shape2) nil)) (t/is (= (:name shape2) "Rect 1")) - (t/is (nil? (:touched shape3))) - (t/is (some? (:shape-ref shape3))) + (t/is (= (:touched shape3) nil)) + (t/is (not= (:shape-ref shape3) nil)) (t/is (= (:name shape3) "Rect 3")) - (t/is (nil? (:touched c-group))) - (t/is (nil? (:touched c-shape1))) + + (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 2")) - (t/is (nil? (:touched c-shape2))) + (t/is (= (:touched c-shape1) nil)) + (t/is (= (:shape-ref c-shape1) nil)) (t/is (= (:name c-shape2) "Rect 1")) - (t/is (nil? (:touched c-shape3))) - (t/is (= (:name c-shape3) "Rect 3")))))] + (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 instance1) 2) (dwl/update-component-sync (:id instance1) (:id file)) :the/end))))) + +(t/deftest test-update-from-lib + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/move-to-library :lib1 "Library 1") + (thp/sample-page) + (thp/instantiate-component :instance2 + (thp/id :component-1) + (thp/id :lib1))) + + [instance2 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Rect 1-1 #--> Rect 1-1 (color, opacity) + ; Rect 1 ---> Rect 1 + ; + (let [[[group shape1] [c-group c-shape1] component] + (thl/resolve-instance-and-main + new-state + (:id instance2))] + + (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:touched group) 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-group) "Rect 1-1")) + (t/is (= (:touched c-group) 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)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape2)] update-fn) + (dwl/update-component (:id instance2)) + :the/end))))) + +(t/deftest test-update-nested-upper + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1 #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 ---> Circle 1 (color, opacity) + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 (color, opacity) + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-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) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape1)] update-fn) + (dwl/update-component (:id instance2)) + :the/end))))) + +(t/deftest test-update-nested-lower-near + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1 #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 (color, opacity) + ; Circle 1 ---> Circle 1 + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 (color, opacity) + ; Circle 1 + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-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) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape2)] update-fn) + (dwl/update-component (:id instance1)) + (dwl/update-component (:id instance2)) + :the/end))))) + +(t/deftest test-update-nested-lower-remote + (t/async done + (try + (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 :instance1 :component-1 + [(thp/id :shape1)]) + (thp/sample-shape :shape2 :circle + {:name "Circle 1" + :fill-color clr/black + :fill-opacity 0}) + (thp/group-shapes :group1 + [(thp/id :instance1) + (thp/id :shape2)]) + (thp/make-component :instance2 :component-2 + [(thp/id :group1)])) + + [instance2 instance1 shape1 shape2] + (thl/resolve-instance state (thp/id :instance2)) + + update-fn (fn [shape] + (merge shape {:fill-color clr/test + :fill-opacity 0.5})) + + store (the/prepare-store state done + (fn [new-state] + ; Expected shape tree: + ; + ; [Page] + ; Root Frame + ; Group-1 #--> Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 (color, opacity) + ; Circle 1 ---> Circle 1 + ; + ; [Rect 1] + ; Rect 1-1 + ; Rect 1 (color, opacity) + ; + ; [Group-1] + ; Group-1 + ; Rect 1-1 @--> Rect 1-1 + ; Rect 1 ---> Rect 1 + ; Circle 1 + ; + (let [[[instance2 instance1 shape1 shape2] + [c-instance2 c-instance1 c-shape1 c-shape2] component] + (thl/resolve-instance-and-main + new-state + (thp/id :instance2))] + + ; TODO: get and check the instance inside component [Group-1] + + (t/is (= (:name instance2) "Group-1")) + (t/is (= (:touched instance2) nil)) + (t/is (= (:name instance1) "Rect 1-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) "Group-1")) + (t/is (= (:touched c-instance2) nil)) + (t/is (= (:name c-instance1) "Rect 1-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/white)) + (t/is (= (:fill-opacity c-shape2) 1)))))] + + (ptk/emit! + store + (dch/update-shapes [(:id shape2)] update-fn) + (dwl/update-component (:id instance1)) + :the/end))))) + diff --git a/frontend/test/app/test_helpers/libraries.cljs b/frontend/test/app/test_helpers/libraries.cljs index 94fbfa8e0..f3644d8e3 100644 --- a/frontend/test/app/test_helpers/libraries.cljs +++ b/frontend/test/app/test_helpers/libraries.cljs @@ -63,7 +63,7 @@ shapes-inst (cph/get-children-with-self (:objects page) root-inst-id)] (is-instance-root (first shapes-inst)) - (run! is-instance-child (rest shapes-inst)) + (run! is-instance-inner (rest shapes-inst)) shapes-inst))