mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 18:48:37 -05:00
Merge pull request #501 from penpot/more-tests
🎉 Add frontend tests for creating and renaming components
This commit is contained in:
commit
b57e63d7d6
7 changed files with 409 additions and 148 deletions
|
@ -25,7 +25,7 @@
|
||||||
(= (count shapes) 1)
|
(= (count shapes) 1)
|
||||||
(= (:type (first shapes)) :group))
|
(= (:type (first shapes)) :group))
|
||||||
(:name (first shapes))
|
(:name (first shapes))
|
||||||
(name (gensym prefix)))]
|
(name (gensym prefix)))] ; TODO: we should something like in new shapes
|
||||||
(-> (cp/make-minimal-group frame-id selrect group-name)
|
(-> (cp/make-minimal-group frame-id selrect group-name)
|
||||||
(gsh/setup selrect)
|
(gsh/setup selrect)
|
||||||
(assoc :shapes (mapv :id shapes)))))
|
(assoc :shapes (mapv :id shapes)))))
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
[app.common.geom.shapes :as geom]
|
[app.common.geom.shapes :as geom]
|
||||||
[app.main.data.messages :as dm]
|
[app.main.data.messages :as dm]
|
||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.data.workspace.groups :as dwg]
|
|
||||||
[app.main.data.workspace.libraries-helpers :as dwlh]
|
[app.main.data.workspace.libraries-helpers :as dwlh]
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
|
@ -224,87 +223,22 @@
|
||||||
(rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}))))))
|
(rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}))))))
|
||||||
|
|
||||||
(def add-component
|
(def add-component
|
||||||
"Add a new component to current file library, from the currently selected shapes"
|
"Add a new component to current file library, from the currently selected shapes."
|
||||||
(ptk/reify ::add-component
|
(ptk/reify ::add-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [file-id (:current-file-id state)
|
(let [file-id (:current-file-id state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
objects (dwc/lookup-page-objects state page-id)
|
objects (dwc/lookup-page-objects state page-id)
|
||||||
selected (get-in state [:workspace-local :selected])
|
selected (get-in state [:workspace-local :selected])]
|
||||||
shapes (dwg/shapes-for-grouping objects selected)]
|
(let [[group rchanges uchanges]
|
||||||
(when-not (empty? shapes)
|
(dwlh/generate-add-component selected objects page-id file-id)]
|
||||||
(let [;; If the selected shape is a group, we can use it. If not,
|
(when-not (empty? rchanges)
|
||||||
;; we need to create a group before creating the component.
|
|
||||||
[group rchanges uchanges]
|
|
||||||
(if (and (= (count shapes) 1)
|
|
||||||
(= (:type (first shapes)) :group))
|
|
||||||
[(first shapes) [] []]
|
|
||||||
(dwg/prepare-create-group page-id shapes "Component-" true))
|
|
||||||
|
|
||||||
[new-shape new-shapes updated-shapes]
|
|
||||||
(dwlh/make-component-shape group objects file-id)
|
|
||||||
|
|
||||||
rchanges (conj rchanges
|
|
||||||
{:type :add-component
|
|
||||||
:id (:id new-shape)
|
|
||||||
:name (:name new-shape)
|
|
||||||
:shapes new-shapes})
|
|
||||||
|
|
||||||
rchanges (into rchanges
|
|
||||||
(map (fn [updated-shape]
|
|
||||||
{:type :mod-obj
|
|
||||||
:page-id page-id
|
|
||||||
:id (:id updated-shape)
|
|
||||||
:operations [{:type :set
|
|
||||||
:attr :component-id
|
|
||||||
:val (:component-id updated-shape)}
|
|
||||||
{:type :set
|
|
||||||
:attr :component-file
|
|
||||||
:val (:component-file updated-shape)}
|
|
||||||
{:type :set
|
|
||||||
:attr :component-root?
|
|
||||||
:val (:component-root? updated-shape)}
|
|
||||||
{:type :set
|
|
||||||
:attr :shape-ref
|
|
||||||
:val (:shape-ref updated-shape)}
|
|
||||||
{:type :set
|
|
||||||
:attr :touched
|
|
||||||
:val (:touched updated-shape)}]})
|
|
||||||
updated-shapes))
|
|
||||||
|
|
||||||
uchanges (conj uchanges
|
|
||||||
{:type :del-component
|
|
||||||
:id (:id new-shape)})
|
|
||||||
|
|
||||||
uchanges (into uchanges
|
|
||||||
(map (fn [updated-shape]
|
|
||||||
(let [original-shape (get objects (:id updated-shape))]
|
|
||||||
{:type :mod-obj
|
|
||||||
:page-id page-id
|
|
||||||
:id (:id updated-shape)
|
|
||||||
:operations [{:type :set
|
|
||||||
:attr :component-id
|
|
||||||
:val (:component-id original-shape)}
|
|
||||||
{:type :set
|
|
||||||
:attr :component-file
|
|
||||||
:val (:component-file original-shape)}
|
|
||||||
{:type :set
|
|
||||||
:attr :component-root?
|
|
||||||
:val (:component-root? original-shape)}
|
|
||||||
{:type :set
|
|
||||||
:attr :shape-ref
|
|
||||||
:val (:shape-ref original-shape)}
|
|
||||||
{:type :set
|
|
||||||
:attr :touched
|
|
||||||
:val (:touched original-shape)}]}))
|
|
||||||
updated-shapes))]
|
|
||||||
|
|
||||||
|
|
||||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||||
(dwc/select-shapes (d/ordered-set (:id group))))))))))
|
(dwc/select-shapes (d/ordered-set (:id group))))))))))
|
||||||
|
|
||||||
(defn rename-component
|
(defn rename-component
|
||||||
|
"Rename the component with the given id, in the current file library."
|
||||||
[id new-name]
|
[id new-name]
|
||||||
(us/assert ::us/uuid id)
|
(us/assert ::us/uuid id)
|
||||||
(us/assert ::us/string new-name)
|
(us/assert ::us/string new-name)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as geom]
|
[app.common.geom.shapes :as geom]
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
|
[app.main.data.workspace.groups :as dwg]
|
||||||
[app.util.logging :as log]
|
[app.util.logging :as log]
|
||||||
[app.util.text :as ut]))
|
[app.util.text :as ut]))
|
||||||
|
|
||||||
|
@ -122,6 +123,78 @@
|
||||||
|
|
||||||
(cp/clone-object shape nil objects update-new-shape update-original-shape)))
|
(cp/clone-object shape nil objects update-new-shape update-original-shape)))
|
||||||
|
|
||||||
|
(defn generate-add-component
|
||||||
|
"If there is exactly one id, and it's a group, use it as root. Otherwise,
|
||||||
|
create a group that contains all ids. Then, make a component with it,
|
||||||
|
and link all shapes to their corresponding one in the component."
|
||||||
|
[ids objects page-id file-id]
|
||||||
|
(let [shapes (dwg/shapes-for-grouping objects ids)
|
||||||
|
|
||||||
|
[group rchanges uchanges]
|
||||||
|
(if (and (= (count shapes) 1)
|
||||||
|
(= (:type (first shapes)) :group))
|
||||||
|
[(first shapes) [] []]
|
||||||
|
(dwg/prepare-create-group page-id shapes "Component-" true))
|
||||||
|
|
||||||
|
[new-shape new-shapes updated-shapes]
|
||||||
|
(make-component-shape group objects file-id)
|
||||||
|
|
||||||
|
rchanges (conj rchanges
|
||||||
|
{:type :add-component
|
||||||
|
:id (:id new-shape)
|
||||||
|
:name (:name new-shape)
|
||||||
|
:shapes new-shapes})
|
||||||
|
|
||||||
|
rchanges (into rchanges
|
||||||
|
(map (fn [updated-shape]
|
||||||
|
{:type :mod-obj
|
||||||
|
:page-id page-id
|
||||||
|
:id (:id updated-shape)
|
||||||
|
:operations [{:type :set
|
||||||
|
:attr :component-id
|
||||||
|
:val (:component-id updated-shape)}
|
||||||
|
{:type :set
|
||||||
|
:attr :component-file
|
||||||
|
:val (:component-file updated-shape)}
|
||||||
|
{:type :set
|
||||||
|
:attr :component-root?
|
||||||
|
:val (:component-root? updated-shape)}
|
||||||
|
{:type :set
|
||||||
|
:attr :shape-ref
|
||||||
|
:val (:shape-ref updated-shape)}
|
||||||
|
{:type :set
|
||||||
|
:attr :touched
|
||||||
|
:val (:touched updated-shape)}]})
|
||||||
|
updated-shapes))
|
||||||
|
|
||||||
|
uchanges (conj uchanges
|
||||||
|
{:type :del-component
|
||||||
|
:id (:id new-shape)})
|
||||||
|
|
||||||
|
uchanges (into uchanges
|
||||||
|
(map (fn [updated-shape]
|
||||||
|
(let [original-shape (get objects (:id updated-shape))]
|
||||||
|
{:type :mod-obj
|
||||||
|
:page-id page-id
|
||||||
|
:id (:id updated-shape)
|
||||||
|
:operations [{:type :set
|
||||||
|
:attr :component-id
|
||||||
|
:val (:component-id original-shape)}
|
||||||
|
{:type :set
|
||||||
|
:attr :component-file
|
||||||
|
:val (:component-file original-shape)}
|
||||||
|
{:type :set
|
||||||
|
:attr :component-root?
|
||||||
|
:val (:component-root? original-shape)}
|
||||||
|
{:type :set
|
||||||
|
:attr :shape-ref
|
||||||
|
:val (:shape-ref original-shape)}
|
||||||
|
{:type :set
|
||||||
|
:attr :touched
|
||||||
|
:val (:touched original-shape)}]}))
|
||||||
|
updated-shapes))]
|
||||||
|
[group rchanges uchanges]))
|
||||||
|
|
||||||
(defn duplicate-component
|
(defn duplicate-component
|
||||||
"Clone the root shape of the component and all children. Generate new
|
"Clone the root shape of the component and all children. Generate new
|
||||||
ids from all of them."
|
ids from all of them."
|
||||||
|
|
39
frontend/tests/app/test_helpers/events.cljs
Normal file
39
frontend/tests/app/test_helpers/events.cljs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
(ns app.test-helpers.events
|
||||||
|
(:require [cljs.test :as t :include-macros true]
|
||||||
|
[cljs.pprint :refer [pprint]]
|
||||||
|
[beicon.core :as rx]
|
||||||
|
[potok.core :as ptk]
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.pages :as cp]
|
||||||
|
[app.common.pages.helpers :as cph]
|
||||||
|
[app.main.data.workspace :as dw]))
|
||||||
|
|
||||||
|
;; ---- Helpers to manage global events
|
||||||
|
|
||||||
|
(defn do-update
|
||||||
|
"Execute an update event and returns the new state."
|
||||||
|
[event state]
|
||||||
|
(ptk/update event state))
|
||||||
|
|
||||||
|
(defn do-watch
|
||||||
|
"Execute a watch event and return an observable, that
|
||||||
|
emits once a list with all new events."
|
||||||
|
[event state]
|
||||||
|
(->> (ptk/watch event state nil)
|
||||||
|
(rx/reduce conj [])))
|
||||||
|
|
||||||
|
(defn do-watch-update
|
||||||
|
"Execute a watch event and return an observable, that
|
||||||
|
emits once the new state, after all new events applied
|
||||||
|
in sequence (considering they are all update events)."
|
||||||
|
[event state]
|
||||||
|
(->> (do-watch event state)
|
||||||
|
(rx/map (fn [new-events]
|
||||||
|
(reduce
|
||||||
|
(fn [new-state new-event]
|
||||||
|
(do-update new-event new-state))
|
||||||
|
state
|
||||||
|
new-events)))))
|
||||||
|
|
90
frontend/tests/app/test_helpers/libraries.cljs
Normal file
90
frontend/tests/app/test_helpers/libraries.cljs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
(ns app.test-helpers.libraries
|
||||||
|
(:require [cljs.test :as t :include-macros true]
|
||||||
|
[cljs.pprint :refer [pprint]]
|
||||||
|
[beicon.core :as rx]
|
||||||
|
[potok.core :as ptk]
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.pages :as cp]
|
||||||
|
[app.common.pages.helpers :as cph]
|
||||||
|
[app.main.data.workspace :as dw]
|
||||||
|
[app.main.data.workspace.libraries-helpers :as dwlh]
|
||||||
|
[app.test-helpers.pages :as thp]))
|
||||||
|
|
||||||
|
;; ---- Helpers to manage libraries and synchronization
|
||||||
|
|
||||||
|
(defn is-instance-root
|
||||||
|
[shape]
|
||||||
|
(t/is (some? (:shape-ref shape)))
|
||||||
|
(t/is (some? (:component-id shape)))
|
||||||
|
(t/is (= (:component-root? shape) true)))
|
||||||
|
|
||||||
|
(defn is-instance-subroot
|
||||||
|
[shape]
|
||||||
|
(t/is (some? (:shape-ref shape)))
|
||||||
|
(t/is (some? (:component-id shape)))
|
||||||
|
(t/is (nil? (:component-root? shape))))
|
||||||
|
|
||||||
|
(defn is-instance-head
|
||||||
|
[shape]
|
||||||
|
(t/is (some? (:shape-ref shape)))
|
||||||
|
(t/is (some? (:component-id shape))))
|
||||||
|
|
||||||
|
(defn is-instance-child
|
||||||
|
[shape]
|
||||||
|
(t/is (some? (:shape-ref shape)))
|
||||||
|
(t/is (nil? (:component-id shape)))
|
||||||
|
(t/is (nil? (:component-file shape)))
|
||||||
|
(t/is (nil? (:component-root? shape))))
|
||||||
|
|
||||||
|
(defn is-noninstance
|
||||||
|
[shape]
|
||||||
|
(t/is (nil? (:shape-ref shape)))
|
||||||
|
(t/is (nil? (:component-id shape)))
|
||||||
|
(t/is (nil? (:component-file shape)))
|
||||||
|
(t/is (nil? (:component-root? shape)))
|
||||||
|
(t/is (nil? (:remote-synced? shape)))
|
||||||
|
(t/is (nil? (:touched shape))))
|
||||||
|
|
||||||
|
(defn is-from-file
|
||||||
|
[shape file]
|
||||||
|
(t/is (= (:component-file shape)
|
||||||
|
(:id file))))
|
||||||
|
|
||||||
|
(defn resolve-instance-and-master
|
||||||
|
[state root-inst-id]
|
||||||
|
(let [page (thp/current-page state)
|
||||||
|
root-inst (cph/get-shape page root-inst-id)
|
||||||
|
|
||||||
|
file (dwlh/get-local-file state)
|
||||||
|
component (cph/get-component
|
||||||
|
(:component-id root-inst)
|
||||||
|
(:id file)
|
||||||
|
file
|
||||||
|
nil)
|
||||||
|
|
||||||
|
shapes-inst (cph/get-object-with-children
|
||||||
|
root-inst-id
|
||||||
|
(:objects page))
|
||||||
|
shapes-master (cph/get-object-with-children
|
||||||
|
(:shape-ref root-inst)
|
||||||
|
(:objects component))
|
||||||
|
|
||||||
|
unique-refs (into #{} (map :shape-ref shapes-inst))
|
||||||
|
|
||||||
|
master-exists? (fn [shape]
|
||||||
|
(t/is (some #(= (:id %) (:shape-ref shape))
|
||||||
|
shapes-master)))]
|
||||||
|
|
||||||
|
;; Validate that the instance tree is well constructed
|
||||||
|
(t/is (is-instance-root (first shapes-inst)))
|
||||||
|
(run! is-instance-child (rest shapes-inst))
|
||||||
|
(run! is-noninstance shapes-master)
|
||||||
|
(t/is (= (count shapes-inst)
|
||||||
|
(count shapes-master)
|
||||||
|
(count unique-refs)))
|
||||||
|
(run! master-exists? shapes-inst)
|
||||||
|
|
||||||
|
[shapes-inst shapes-master component]))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(ns app.test-helpers
|
(ns app.test-helpers.pages
|
||||||
(:require [cljs.test :as t :include-macros true]
|
(:require [cljs.test :as t :include-macros true]
|
||||||
[cljs.pprint :refer [pprint]]
|
[cljs.pprint :refer [pprint]]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
|
@ -8,36 +8,9 @@
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.main.data.workspace :as dw]))
|
[app.main.data.workspace :as dw]
|
||||||
|
[app.main.data.workspace.groups :as dwg]
|
||||||
|
[app.main.data.workspace.libraries-helpers :as dwlh]))
|
||||||
;; ---- Helpers to manage global events
|
|
||||||
|
|
||||||
(defn do-update
|
|
||||||
"Execute an update event and returns the new state."
|
|
||||||
[event state]
|
|
||||||
(ptk/update event state))
|
|
||||||
|
|
||||||
(defn do-watch
|
|
||||||
"Execute a watch event and return an observable, that
|
|
||||||
emits once a list with all new events."
|
|
||||||
[event state]
|
|
||||||
(->> (ptk/watch event state nil)
|
|
||||||
(rx/reduce conj [])))
|
|
||||||
|
|
||||||
(defn do-watch-update
|
|
||||||
"Execute a watch event and return an observable, that
|
|
||||||
emits once the new state, after all new events applied
|
|
||||||
in sequence (considering they are all update events)."
|
|
||||||
[event state]
|
|
||||||
(->> (do-watch event state)
|
|
||||||
(rx/map (fn [new-events]
|
|
||||||
(reduce
|
|
||||||
(fn [new-state new-event]
|
|
||||||
(do-update new-event new-state))
|
|
||||||
state
|
|
||||||
new-events)))))
|
|
||||||
|
|
||||||
|
|
||||||
;; ---- Helpers to manage pages and objects
|
;; ---- Helpers to manage pages and objects
|
||||||
|
|
||||||
|
@ -53,16 +26,32 @@
|
||||||
:pages-index {}}
|
:pages-index {}}
|
||||||
:workspace-libraries {}})
|
:workspace-libraries {}})
|
||||||
|
|
||||||
|
(def ^:private idmap (atom {}))
|
||||||
|
|
||||||
|
(defn reset-idmap! []
|
||||||
|
(reset! idmap {}))
|
||||||
|
|
||||||
(defn current-page
|
(defn current-page
|
||||||
[state]
|
[state]
|
||||||
(let [page-id (:current-page-id state)]
|
(let [page-id (:current-page-id state)]
|
||||||
(get-in state [:workspace-data :pages-index page-id])))
|
(get-in state [:workspace-data :pages-index page-id])))
|
||||||
|
|
||||||
|
(defn id
|
||||||
|
[label]
|
||||||
|
(get @idmap label))
|
||||||
|
|
||||||
|
(defn get-shape
|
||||||
|
[state label]
|
||||||
|
(let [page (current-page state)]
|
||||||
|
(get-in page [:objects (id label)])))
|
||||||
|
|
||||||
(defn sample-page
|
(defn sample-page
|
||||||
([state] (sample-page state {}))
|
([state] (sample-page state {}))
|
||||||
([state {:keys [id name] :as props
|
([state {:keys [id name] :as props
|
||||||
:or {id (uuid/next)
|
:or {id (uuid/next)
|
||||||
name "page1"}}]
|
name "page1"}}]
|
||||||
|
|
||||||
|
(swap! idmap assoc :page id)
|
||||||
(-> state
|
(-> state
|
||||||
(assoc :current-page-id id)
|
(assoc :current-page-id id)
|
||||||
(update :workspace-data
|
(update :workspace-data
|
||||||
|
@ -72,13 +61,14 @@
|
||||||
:name name}]))))
|
:name name}]))))
|
||||||
|
|
||||||
(defn sample-shape
|
(defn sample-shape
|
||||||
([state type] (sample-shape state type {}))
|
([state label type] (sample-shape state type {}))
|
||||||
([state type props]
|
([state label type props]
|
||||||
(let [page (current-page state)
|
(let [page (current-page state)
|
||||||
frame (cph/get-top-frame (:objects page))
|
frame (cph/get-top-frame (:objects page))
|
||||||
shape (-> (cp/make-minimal-shape type)
|
shape (-> (cp/make-minimal-shape type)
|
||||||
(gsh/setup {:x 0 :y 0 :width 1 :height 1})
|
(gsh/setup {:x 0 :y 0 :width 1 :height 1})
|
||||||
(merge props))]
|
(merge props))]
|
||||||
|
(swap! idmap assoc label (:id shape))
|
||||||
(update state :workspace-data
|
(update state :workspace-data
|
||||||
cp/process-changes
|
cp/process-changes
|
||||||
[{:type :add-obj
|
[{:type :add-obj
|
||||||
|
@ -87,3 +77,30 @@
|
||||||
:frame-id (:id frame)
|
:frame-id (:id frame)
|
||||||
:obj shape}]))))
|
:obj shape}]))))
|
||||||
|
|
||||||
|
(defn group-shapes
|
||||||
|
([state label ids] (group-shapes state label ids "Group-"))
|
||||||
|
([state label ids prefix]
|
||||||
|
(let [page (current-page state)
|
||||||
|
shapes (dwg/shapes-for-grouping (:objects page) ids)
|
||||||
|
|
||||||
|
[group rchanges uchanges]
|
||||||
|
(dwg/prepare-create-group (:id page) shapes prefix true)]
|
||||||
|
|
||||||
|
(swap! idmap assoc label (:id group))
|
||||||
|
(update state :workspace-data
|
||||||
|
cp/process-changes rchanges))))
|
||||||
|
|
||||||
|
(defn make-component
|
||||||
|
[state label ids]
|
||||||
|
(let [page (current-page state)
|
||||||
|
|
||||||
|
[group rchanges uchanges]
|
||||||
|
(dwlh/generate-add-component ids
|
||||||
|
(:objects page)
|
||||||
|
(:id page)
|
||||||
|
current-file-id)]
|
||||||
|
|
||||||
|
(swap! idmap assoc label (:id group))
|
||||||
|
(update state :workspace-data
|
||||||
|
cp/process-changes rchanges)))
|
||||||
|
|
|
@ -2,37 +2,40 @@
|
||||||
(:require [cljs.test :as t :include-macros true]
|
(:require [cljs.test :as t :include-macros true]
|
||||||
[cljs.pprint :refer [pprint]]
|
[cljs.pprint :refer [pprint]]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[app.test-helpers :as th]
|
[linked.core :as lks]
|
||||||
|
[app.test-helpers.events :as the]
|
||||||
|
[app.test-helpers.pages :as thp]
|
||||||
|
[app.test-helpers.libraries :as thl]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.uuid :as uuid]
|
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.libraries-helpers :as dwlh]))
|
[app.main.data.workspace.libraries-helpers :as dwlh]))
|
||||||
|
|
||||||
|
(t/use-fixtures :each
|
||||||
|
{:before thp/reset-idmap!})
|
||||||
|
|
||||||
(t/deftest test-create-page
|
(t/deftest test-create-page
|
||||||
(t/testing "create page"
|
(t/testing "create page"
|
||||||
(let [state (-> th/initial-state
|
(let [state (-> thp/initial-state
|
||||||
(th/sample-page))
|
(thp/sample-page))
|
||||||
page (th/current-page state)]
|
page (thp/current-page state)]
|
||||||
(t/is (= (:name page) "page1")))))
|
(t/is (= (:name page) "page1")))))
|
||||||
|
|
||||||
(t/deftest test-create-shape
|
(t/deftest test-create-shape
|
||||||
(t/testing "create shape"
|
(t/testing "create shape"
|
||||||
(let [id (uuid/next)
|
(let [state (-> thp/initial-state
|
||||||
state (-> th/initial-state
|
(thp/sample-page)
|
||||||
(th/sample-page)
|
(thp/sample-shape :shape1 :rect
|
||||||
(th/sample-shape :rect {:id id
|
{:name "Rect 1"}))
|
||||||
:name "Rect 1"}))
|
shape (thp/get-shape state :shape1)]
|
||||||
page (th/current-page state)
|
|
||||||
shape (cph/get-shape page id)]
|
|
||||||
(t/is (= (:name shape) "Rect 1")))))
|
(t/is (= (:name shape) "Rect 1")))))
|
||||||
|
|
||||||
(t/deftest synctest
|
(t/deftest synctest
|
||||||
(t/testing "synctest"
|
(t/testing "synctest"
|
||||||
(let [state {:workspace-local {:color-for-rename "something"}}
|
(let [state {:workspace-local {:color-for-rename "something"}}
|
||||||
new-state (->> state
|
new-state (->> state
|
||||||
(th/do-update
|
(the/do-update
|
||||||
dwl/clear-color-for-rename))]
|
dwl/clear-color-for-rename))]
|
||||||
(t/is (= (get-in new-state [:workspace-local :color-for-rename])
|
(t/is (= (get-in new-state [:workspace-local :color-for-rename])
|
||||||
nil)))))
|
nil)))))
|
||||||
|
@ -43,7 +46,7 @@
|
||||||
(let [state {}
|
(let [state {}
|
||||||
color {:color "#ffffff"}]
|
color {:color "#ffffff"}]
|
||||||
(->> state
|
(->> state
|
||||||
(th/do-watch-update
|
(the/do-watch-update
|
||||||
(dwl/add-recent-color color))
|
(dwl/add-recent-color color))
|
||||||
(rx/map
|
(rx/map
|
||||||
(fn [new-state]
|
(fn [new-state]
|
||||||
|
@ -56,43 +59,148 @@
|
||||||
[color]))))
|
[color]))))
|
||||||
(rx/subs done))))))
|
(rx/subs done))))))
|
||||||
|
|
||||||
(t/deftest test-add-component
|
(t/deftest test-add-component-from-single-shape
|
||||||
(t/testing "Add a component"
|
(t/testing "Add a component from a single shape"
|
||||||
(t/async done
|
(t/async done
|
||||||
(let [id1 (uuid/next)
|
(let [state (-> thp/initial-state
|
||||||
state (-> th/initial-state
|
(thp/sample-page)
|
||||||
(th/sample-page)
|
(thp/sample-shape :shape1 :rect
|
||||||
(th/sample-shape :rect
|
{:name "Rect 1"}))]
|
||||||
{:id id1
|
|
||||||
:name "Rect 1"}))]
|
|
||||||
(->> state
|
(->> state
|
||||||
(th/do-update (dw/select-shape id1))
|
(the/do-update (dw/select-shape (thp/id :shape1)))
|
||||||
(th/do-watch-update dwl/add-component)
|
(the/do-watch-update dwl/add-component)
|
||||||
(rx/map
|
(rx/map
|
||||||
(fn [new-state]
|
(fn [new-state]
|
||||||
(let [page (th/current-page new-state)
|
(let [shape1 (thp/get-shape new-state :shape1)
|
||||||
shape (cph/get-shape page id1)
|
|
||||||
group (cph/get-shape page (:parent-id shape))
|
|
||||||
|
|
||||||
component (cph/get-component
|
[[group shape1] [c-group c-shape1] component]
|
||||||
(:component-id group)
|
(thl/resolve-instance-and-master
|
||||||
(:current-file-id new-state)
|
new-state
|
||||||
(dwlh/get-local-file new-state)
|
(:parent-id shape1))
|
||||||
nil)
|
|
||||||
|
|
||||||
c-shape (cph/get-shape
|
file (dwlh/get-local-file new-state)]
|
||||||
component
|
|
||||||
(:shape-ref shape))
|
|
||||||
|
|
||||||
c-group (cph/get-shape
|
(t/is (= (:name shape1) "Rect 1"))
|
||||||
component
|
|
||||||
(:shape-ref group))]
|
|
||||||
|
|
||||||
(t/is (= (:name shape) "Rect 1"))
|
|
||||||
(t/is (= (:name group) "Component-1"))
|
(t/is (= (:name group) "Component-1"))
|
||||||
(t/is (= (:name component) "Component-1"))
|
(t/is (= (:name component) "Component-1"))
|
||||||
(t/is (= (:name c-shape) "Rect 1"))
|
(t/is (= (:name c-shape1) "Rect 1"))
|
||||||
(t/is (= (:name c-group) "Component-1")))))
|
(t/is (= (:name c-group) "Component-1"))
|
||||||
|
|
||||||
|
(thl/is-from-file group file))))
|
||||||
|
|
||||||
|
(rx/subs done))))))
|
||||||
|
|
||||||
|
(t/deftest test-add-component-from-several-shapes
|
||||||
|
(t/testing "Add a component from several shapes"
|
||||||
|
(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"}))]
|
||||||
|
|
||||||
|
(->> state
|
||||||
|
(the/do-update (dw/select-shapes (lks/set
|
||||||
|
(thp/id :shape1)
|
||||||
|
(thp/id :shape2))))
|
||||||
|
(the/do-watch-update dwl/add-component)
|
||||||
|
(rx/map
|
||||||
|
(fn [new-state]
|
||||||
|
(let [shape1 (thp/get-shape new-state :shape1)
|
||||||
|
|
||||||
|
[[group shape1 shape2]
|
||||||
|
[c-group c-shape1 c-shape2]
|
||||||
|
component]
|
||||||
|
(thl/resolve-instance-and-master
|
||||||
|
new-state
|
||||||
|
(:parent-id shape1))
|
||||||
|
|
||||||
|
file (dwlh/get-local-file new-state)]
|
||||||
|
|
||||||
|
;; NOTE: the group name depends on having executed
|
||||||
|
;; the previous test.
|
||||||
|
(t/is (= (:name group) "Component-2"))
|
||||||
|
(t/is (= (:name shape1) "Rect 1"))
|
||||||
|
(t/is (= (:name shape2) "Rect 2"))
|
||||||
|
(t/is (= (:name component) "Component-2"))
|
||||||
|
(t/is (= (:name c-group) "Component-2"))
|
||||||
|
(t/is (= (:name c-shape1) "Rect 1"))
|
||||||
|
(t/is (= (:name c-shape2) "Rect 2"))
|
||||||
|
|
||||||
|
(thl/is-from-file group file))))
|
||||||
|
|
||||||
|
(rx/subs done))))))
|
||||||
|
|
||||||
|
(t/deftest test-add-component-from-group
|
||||||
|
(t/testing "Add a component from a group"
|
||||||
|
(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/group-shapes :group1
|
||||||
|
[(thp/id :shape1)
|
||||||
|
(thp/id :shape2)]))]
|
||||||
|
|
||||||
|
(->> state
|
||||||
|
(the/do-update (dw/select-shape (thp/id :group1)))
|
||||||
|
(the/do-watch-update dwl/add-component)
|
||||||
|
(rx/map
|
||||||
|
(fn [new-state]
|
||||||
|
(let [[[group shape1 shape2]
|
||||||
|
[c-group c-shape1 c-shape2]
|
||||||
|
component]
|
||||||
|
(thl/resolve-instance-and-master
|
||||||
|
new-state
|
||||||
|
(thp/id :group1))
|
||||||
|
|
||||||
|
file (dwlh/get-local-file new-state)]
|
||||||
|
|
||||||
|
(t/is (= (:name shape1) "Rect 1"))
|
||||||
|
(t/is (= (:name shape2) "Rect 2"))
|
||||||
|
(t/is (= (:name group) "Group-3"))
|
||||||
|
(t/is (= (:name component) "Group-3"))
|
||||||
|
(t/is (= (:name c-shape1) "Rect 1"))
|
||||||
|
(t/is (= (:name c-shape2) "Rect 2"))
|
||||||
|
(t/is (= (:name c-group) "Group-3"))
|
||||||
|
|
||||||
|
(thl/is-from-file group file))))
|
||||||
|
|
||||||
|
(rx/subs done))))))
|
||||||
|
|
||||||
|
(t/deftest test-rename-component
|
||||||
|
(t/testing "Rename a component"
|
||||||
|
(t/async done
|
||||||
|
(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)]
|
||||||
|
|
||||||
|
(->> state
|
||||||
|
(the/do-watch-update (dwl/rename-component
|
||||||
|
(:component-id instance1)
|
||||||
|
"Renamed component"))
|
||||||
|
(rx/map
|
||||||
|
(fn [new-state]
|
||||||
|
(let [file (dwlh/get-local-file new-state)
|
||||||
|
component (cph/get-component
|
||||||
|
(:component-id instance1)
|
||||||
|
(:component-file instance1)
|
||||||
|
file
|
||||||
|
{})]
|
||||||
|
|
||||||
|
(t/is (= (:name component)
|
||||||
|
"Renamed component")))))
|
||||||
|
|
||||||
(rx/subs done))))))
|
(rx/subs done))))))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue