diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 9e6433f9c..519774d4b 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -319,7 +319,7 @@ (defn instantiate-component "Create a new shape in the current page, from the component with the given id - in the given file library / current file library." + in the given file library. Then selects the newly created instance." [file-id component-id position] (us/assert ::us/uuid file-id) (us/assert ::us/uuid component-id) diff --git a/frontend/tests/app/test_helpers/libraries.cljs b/frontend/tests/app/test_helpers/libraries.cljs index b4bd7aa0e..77f2259e9 100644 --- a/frontend/tests/app/test_helpers/libraries.cljs +++ b/frontend/tests/app/test_helpers/libraries.cljs @@ -57,7 +57,7 @@ (let [page (thp/current-page state) root-inst (cph/get-shape page root-inst-id) - file (dwlh/get-local-file state) + file (dwlh/get-local-file state) component (cph/get-component (:component-id root-inst) (:id file) @@ -88,3 +88,25 @@ [shapes-inst shapes-master component])) +(defn resolve-component + [state component-id] + (let [page (thp/current-page state) + + file (dwlh/get-local-file state) + component (cph/get-component + component-id + (:id file) + file + nil) + + root-master (cph/get-component-root + component) + shapes-master (cph/get-object-with-children + (:id root-master) + (:objects component))] + + ;; Validate that the component tree is well constructed + (run! is-noninstance shapes-master) + + [shapes-master component])) + diff --git a/frontend/tests/app/test_library_sync.cljs b/frontend/tests/app/test_library_sync.cljs index d98bdf57a..b1712b533 100644 --- a/frontend/tests/app/test_library_sync.cljs +++ b/frontend/tests/app/test_library_sync.cljs @@ -1,11 +1,13 @@ (ns app.test-library-sync (:require [cljs.test :as t :include-macros true] [cljs.pprint :refer [pprint]] + [clojure.stacktrace :as stk] [beicon.core :as rx] [linked.core :as lks] [app.test-helpers.events :as the] [app.test-helpers.pages :as thp] [app.test-helpers.libraries :as thl] + [app.common.geom.point :as gpt] [app.common.data :as d] [app.common.pages.helpers :as cph] [app.main.data.workspace :as dw] @@ -57,11 +59,11 @@ (t/is (= (get-in new-state [:workspace-data :recent-colors]) [color])))) - (rx/subs done)))))) + (rx/subs done done)))))) (t/deftest test-add-component-from-single-shape - (t/testing "Add a component from a single shape" - (t/async done + (t/async done + (try (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect @@ -70,7 +72,7 @@ (->> state (the/do-update (dw/select-shape (thp/id :shape1))) (the/do-watch-update dwl/add-component) - (rx/map + (rx/do (fn [new-state] (let [shape1 (thp/get-shape new-state :shape1) @@ -89,11 +91,19 @@ (thl/is-from-file group file)))) - (rx/subs done)))))) + (rx/subs + done + #(do + (println (.-stack %)) + (done))))) + + (catch :default e + (println (.-stack e)) + (done))))) (t/deftest test-add-component-from-several-shapes - (t/testing "Add a component from several shapes" - (t/async done + (t/async done + (try (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect @@ -106,7 +116,7 @@ (thp/id :shape1) (thp/id :shape2)))) (the/do-watch-update dwl/add-component) - (rx/map + (rx/do (fn [new-state] (let [shape1 (thp/get-shape new-state :shape1) @@ -131,13 +141,21 @@ (thl/is-from-file group file)))) - (rx/subs done)))))) + (rx/subs + done + #(do + (println (.-stack %)) + (done))))) + + (catch :default e + (println (.-stack e)) + (done))))) + (t/deftest test-add-component-from-group - (t/testing "Add a component from a group" - (t/async done - (let [ - state (-> thp/initial-state + (t/async done + (try + (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect {:name "Rect 1"}) @@ -150,7 +168,7 @@ (->> state (the/do-update (dw/select-shape (thp/id :group1))) (the/do-watch-update dwl/add-component) - (rx/map + (rx/do (fn [new-state] (let [[[group shape1 shape2] [c-group c-shape1 c-shape2] @@ -171,13 +189,20 @@ (thl/is-from-file group file)))) - (rx/subs done)))))) + (rx/subs + done + #(do + (println (.-stack %)) + (done))))) + + (catch :default e + (println (.-stack e)) + (done))))) (t/deftest test-rename-component - (t/testing "Rename a component" - (t/async done - (let [ - state (-> thp/initial-state + (t/async done + (try + (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect {:name "Rect 1"}) @@ -190,7 +215,7 @@ (the/do-watch-update (dwl/rename-component (:component-id instance1) "Renamed component")) - (rx/map + (rx/do (fn [new-state] (let [file (dwlh/get-local-file new-state) component (cph/get-component @@ -202,5 +227,113 @@ (t/is (= (:name component) "Renamed component"))))) - (rx/subs done)))))) + (rx/subs + done + #(do + (println (.-stack %)) + (done))))) + + (catch :default e + (println (.-stack e)) + (done))))) + +(t/deftest test-duplicate-component + (t/async done + (try + (let [state (-> thp/initial-state + (thp/sample-page) + (thp/sample-shape :shape1 :rect + {:name "Rect 1"}) + (thp/make-component :instance1 + [(thp/id :shape1)])) + + instance1 (thp/get-shape state :instance1) + component-id (:component-id instance1)] + + (->> state + (the/do-watch-update (dwl/duplicate-component + {:id component-id})) + (rx/do + (fn [new-state] + (let [new-component-id (->> (get-in new-state + [:workspace-data + :components]) + (keys) + (filter #(not= % component-id)) + (first)) + + [[instance1 shape1] + [c-instance1 c-shape1] + component1] + (thl/resolve-instance-and-master + new-state + (:id instance1)) + + [[c-component2 c-shape2] + component2] + (thl/resolve-component + new-state + new-component-id)] + + (t/is (= (:name component2) + "Component-6"))))) + + (rx/subs + done + #(do + (println (.-stack %)) + (done))))) + + (catch :default e + (println (.-stack e)) + (done))))) + +(t/deftest test-instantiate-component + (t/async done + (try + (let [state (-> thp/initial-state + (thp/sample-page) + (thp/sample-shape :shape1 :rect + {:name "Rect 1"}) + (thp/make-component :instance1 + [(thp/id :shape1)])) + + file (dwlh/get-local-file state) + instance1 (thp/get-shape state :instance1) + component-id (:component-id instance1)] + + (->> state + (the/do-watch-update (dwl/instantiate-component + (:id file) + (:component-id instance1) + (gpt/point 100 100))) + (rx/do + (fn [new-state] + (let [new-instance-id (-> (get-in new-state + [:workspace-local :selected]) + first) + + [[instance2 shape2] + [c-instance2 c-shape2] + component] + (thl/resolve-instance-and-master + new-state + new-instance-id)] + + (t/is (not= (:id instance1) (:id instance2))) + (t/is (= (:id component) component-id)) + (t/is (= (:name instance2) "Component-7")) + (t/is (= (:name shape2) "Rect 1")) + (t/is (= (:name c-instance2) "Component-6")) + (t/is (= (:name c-shape2) "Rect 1"))))) + + (rx/subs + done + #(do + (println (.-stack %)) + (done))))) + + (catch :default e + (println (.-stack e)) + (done)))))