0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-28 15:41:25 -05:00

Merge pull request #4562 from penpot/hiru-move-frontend-tests

Move more frontend tests
This commit is contained in:
Alejandro 2024-05-10 11:04:31 +02:00 committed by GitHub
commit ea20f693cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1809 additions and 2817 deletions

View file

@ -720,6 +720,7 @@
(map lookupf)
(map mk-change))
updated-shapes))))
(apply-changes-local)))))
(defn update-component

View file

@ -150,8 +150,6 @@
[new-component-shape new-component-shapes nil nil]))))
(defn generate-duplicate-component
"Create a new component copied from the one with the given id."
[changes library component-id components-v2]

View file

@ -61,6 +61,10 @@
(update container :objects update-objects parent-id)))
(defn parent-of?
[parent child]
(= (:id parent) (:parent-id child)))
(defn get-shape
"Get a shape identified by id"
[container id]

View file

@ -33,8 +33,9 @@
(let [[_new-root _new-shapes updated-shapes]
(ctn/convert-shape-in-component root (:objects page) (:id file))
updated-root (first updated-shapes)] ; Can't use new-root because it has a new id
updated-root (first updated-shapes) ; Can't use new-root because it has a new id
[path name] (cfh/parse-path-name (:name updated-root))]
(thi/set-id! label (:component-id updated-root))
(ctf/update-file-data
@ -49,14 +50,15 @@
updated-shapes)
(ctkl/add-component $ (assoc params
:id (:component-id updated-root)
:name (:name updated-root)
:name name
:path path
:main-instance-id (:id updated-root)
:main-instance-page (:id page)
:shapes updated-shapes))))))))
(defn get-component
[file label]
(ctkl/get-component (:data file) (thi/id label)))
[file label & {:keys [include-deleted?] :or {include-deleted? false}}]
(ctkl/get-component (:data file) (thi/id label) include-deleted?))
(defn get-component-by-id
[file id]
@ -129,6 +131,7 @@
(when children-labels
(dotimes [idx (count children-labels)]
(set-child-label file' copy-root-label idx (nth children-labels idx))))
file'))
(defn component-swap

View file

@ -140,8 +140,8 @@
component2-params)))
(defn add-nested-component-with-copy
[file component1-label main1-root-label main1-child-label component2-label main2-root-label nested-head-label copy2-label
& {:keys [component1-params root1-params main1-child-params component2-params main2-root-params nested-head-params copy2-params]}]
[file component1-label main1-root-label main1-child-label component2-label main2-root-label nested-head-label copy2-root-label
& {:keys [component1-params root1-params main1-child-params component2-params main2-root-params nested-head-params copy2-root-params]}]
;; Generated shape tree:
;; {:main1-root-label} [:name: Frame1] # [Component :component1-label]
;; :main1-child-label [:name: Rect1]
@ -166,4 +166,4 @@
:component2-params component2-params
:main2-root-params main2-root-params
:nested-head-params nested-head-params)
(thc/instantiate-component component2-label copy2-label copy2-params)))
(thc/instantiate-component component2-label copy2-root-label copy2-root-params)))

View file

@ -0,0 +1,610 @@
;; 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-creation-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-add-component-from-single-frame
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(ths/add-sample-shape :frame1 :type :frame))
page (thf/current-page file)
frame1 (ths/get-shape file :frame1)
;; ==== Action
[_ component-id changes]
(cll/generate-add-component (pcb/empty-changes)
[frame1]
(:objects page)
(:id page)
(:id file)
true
nil
nil)
file' (thf/apply-changes file changes)
;; ==== Get
component (thc/get-component-by-id file' component-id)
root (ths/get-shape-by-id file' (:main-instance-id component))
frame1' (ths/get-shape file' :frame1)]
;; ==== Check
(t/is (some? component))
(t/is (some? root))
(t/is (some? frame1'))
(t/is (= (:id root) (:id frame1')))
(t/is (ctk/main-instance? root))
(t/is (ctk/main-instance-of? (:id root) (:id page) component))))
(t/deftest test-add-component-from-single-shape
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(ths/add-sample-shape :shape1 :type :rect))
page (thf/current-page file)
shape1 (ths/get-shape file :shape1)
;; ==== Action
[_ component-id changes]
(cll/generate-add-component (pcb/empty-changes)
[shape1]
(:objects page)
(:id page)
(:id file)
true
nil
cfsh/prepare-create-artboard-from-selection)
file' (thf/apply-changes file changes)
;; ==== Get
component (thc/get-component-by-id file' component-id)
root (ths/get-shape-by-id file' (:main-instance-id component))
shape1' (ths/get-shape file' :shape1)]
;; ==== Check
(t/is (some? component))
(t/is (some? root))
(t/is (some? shape1'))
(t/is (ctst/parent-of? root shape1'))
(t/is (= (:type root) :frame))
(t/is (ctk/main-instance? root))
(t/is (ctk/main-instance-of? (:id root) (:id page) component))))
(t/deftest test-add-component-from-several-shapes
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(ths/add-sample-shape :shape1 :type :rect)
(ths/add-sample-shape :shape2 :type :rect))
page (thf/current-page file)
shape1 (ths/get-shape file :shape1)
shape2 (ths/get-shape file :shape2)
;; ==== Action
[_ component-id changes]
(cll/generate-add-component (pcb/empty-changes)
[shape1 shape2]
(:objects page)
(:id page)
(:id file)
true
nil
cfsh/prepare-create-artboard-from-selection)
file' (thf/apply-changes file changes)
;; ==== Get
component (thc/get-component-by-id file' component-id)
root (ths/get-shape-by-id file' (:main-instance-id component))
shape1' (ths/get-shape file' :shape1)
shape2' (ths/get-shape file' :shape2)]
;; ==== Check
(t/is (some? component))
(t/is (some? root))
(t/is (some? shape1'))
(t/is (some? shape2'))
(t/is (ctst/parent-of? root shape1'))
(t/is (ctst/parent-of? root shape2'))
(t/is (= (:type root) :frame))
(t/is (ctk/main-instance? root))
(t/is (ctk/main-instance-of? (:id root) (:id page) component))))
(t/deftest test-add-component-from-several-frames
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(ths/add-sample-shape :frame1 :type :frame)
(ths/add-sample-shape :frame2 :type :frame))
page (thf/current-page file)
frame1 (ths/get-shape file :frame1)
frame2 (ths/get-shape file :frame2)
;; ==== Action
[_ component-id changes]
(cll/generate-add-component (pcb/empty-changes)
[frame1 frame2]
(:objects page)
(:id page)
(:id file)
true
nil
cfsh/prepare-create-artboard-from-selection)
file' (thf/apply-changes file changes)
;; ==== Get
component (thc/get-component-by-id file' component-id)
root (ths/get-shape-by-id file' (:main-instance-id component))
frame1' (ths/get-shape file' :frame1)
frame2' (ths/get-shape file' :frame2)]
;; ==== Check
(t/is (some? component))
(t/is (some? root))
(t/is (some? frame1'))
(t/is (some? frame2'))
(t/is (ctst/parent-of? root frame1'))
(t/is (ctst/parent-of? root frame2'))
(t/is (= (:type root) :frame))
(t/is (ctk/main-instance? root))
(t/is (ctk/main-instance-of? (:id root) (:id page) component))))
(t/deftest test-add-component-from-frame-with-children
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(ths/add-sample-shape :frame1 :type :frame)
(ths/add-sample-shape :shape1 :type :rect :parent-label :frame1)
(ths/add-sample-shape :shape2 :type :rect :parent-label :frame1))
page (thf/current-page file)
frame1 (ths/get-shape file :frame1)
;; ==== Action
[_ component-id changes]
(cll/generate-add-component (pcb/empty-changes)
[frame1]
(:objects page)
(:id page)
(:id file)
true
nil
nil)
file' (thf/apply-changes file changes)
;; ==== Get
component (thc/get-component-by-id file' component-id)
root (ths/get-shape-by-id file' (:main-instance-id component))
frame1' (ths/get-shape file' :frame1)
shape1' (ths/get-shape file' :shape1)
shape2' (ths/get-shape file' :shape2)]
;; ==== Check
(t/is (some? component))
(t/is (some? root))
(t/is (some? frame1'))
(t/is (= (:id root) (:id frame1')))
(t/is (ctst/parent-of? frame1' shape1'))
(t/is (ctst/parent-of? frame1' shape2'))
(t/is (ctk/main-instance? root))
(t/is (ctk/main-instance-of? (:id root) (:id page) component))))
(t/deftest test-add-component-from-copy
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main1-root
:main1-child
:copy1-root))
page (thf/current-page file)
copy1-root (ths/get-shape file :copy1-root)
;; ==== Action
[_ component2-id changes]
(cll/generate-add-component (pcb/empty-changes)
[copy1-root]
(:objects page)
(:id page)
(:id file)
true
nil
cfsh/prepare-create-artboard-from-selection)
file' (thf/apply-changes file changes)
;; ==== Get
component2' (thc/get-component-by-id file' component2-id)
root2' (ths/get-shape-by-id file' (:main-instance-id component2'))
copy1-root' (ths/get-shape file' :copy1-root)]
;; ==== Check
(t/is (some? component2'))
(t/is (some? root2'))
(t/is (some? copy1-root'))
(t/is (ctst/parent-of? root2' copy1-root'))
(t/is (ctk/main-instance? root2'))
(t/is (ctk/main-instance-of? (:id root2') (:id page) component2'))))
(t/deftest test-rename-component
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component :component1
:main1-root
:main1-child
:name "Test component before"))
component (thc/get-component file :component1)
;; ==== Action
changes (cll/generate-rename-component (pcb/empty-changes)
(:id component)
"Test component after"
(:data file)
true)
file' (thf/apply-changes file changes)
;; ==== Get
component' (thc/get-component file' :component1)]
;; ==== Check
(t/is (= (:name component') "Test component after"))))
(t/deftest test-duplicate-component
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component :component1
:main1-root
:main1-child))
component (thc/get-component file :component1)
;; ==== Action
changes (cll/generate-duplicate-component (pcb/empty-changes)
file
(:id component)
true)
file' (thf/apply-changes file changes)
;; ==== Get
components' (ctkl/components-seq (:data file'))
component1' (d/seek #(= (:id %) (thi/id :component1)) components')
component2' (d/seek #(not= (:id %) (thi/id :component1)) components')
root1' (ths/get-shape-by-id file' (:main-instance-id component1'))
root2' (ths/get-shape-by-id file' (:main-instance-id component2'))
child1' (ths/get-shape-by-id file' (first (:shapes root1')))
child2' (ths/get-shape-by-id file' (first (:shapes root2')))]
;; ==== Check
(t/is (= 2 (count components')))
(t/is (some? component1'))
(t/is (some? component2'))
(t/is (some? root1'))
(t/is (some? root2'))
(t/is (= (thi/id :main1-root) (:id root1')))
(t/is (not= (thi/id :main1-root) (:id root2')))
(t/is (some? child1'))
(t/is (some? child2'))
(t/is (= (thi/id :main1-child) (:id child1')))
(t/is (not= (thi/id :main1-child) (:id child2')))))
(t/deftest test-delete-component
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main1-root
:main1-child
:copy1-root))
page (thf/current-page file)
root (ths/get-shape file :main1-root)
;; ==== Action
[_ changes]
(cls/generate-delete-shapes (pcb/empty-changes)
file
page
(:objects page)
#{(:id root)}
{:components-v2 true})
file' (thf/apply-changes file changes)
;; ==== Get
component1' (thc/get-component file' :component1 :include-deleted? true)
copy1-root' (ths/get-shape file' :copy1-root)
main1-root' (ths/get-shape file' :main1-root)
main1-child' (ths/get-shape file' :main1-child)
saved-objects (:objects component1')
saved-main1-root' (get saved-objects (thi/id :main1-root))
saved-main1-child' (get saved-objects (thi/id :main1-child))]
;; ==== Check
(t/is (true? (:deleted component1')))
(t/is (some? copy1-root'))
(t/is (nil? main1-root'))
(t/is (nil? main1-child'))
(t/is (some? saved-main1-root'))
(t/is (some? saved-main1-child'))))
(t/deftest test-restore-component
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main1-root
:main1-child
:copy1-root))
page (thf/current-page file)
root (ths/get-shape file :main1-root)
;; ==== Action
[_ changes]
(cls/generate-delete-shapes (pcb/empty-changes)
file
page
(:objects page)
#{(:id root)}
{:components-v2 true})
file-deleted (thf/apply-changes file changes)
page-deleted (thf/current-page file-deleted)
changes (cll/generate-restore-component (pcb/empty-changes)
(:data file-deleted)
(thi/id :component1)
(:id file-deleted)
page-deleted
(:objects page-deleted))
file' (thf/apply-changes file changes)
;; ==== Get
component1' (thc/get-component file' :component1 :include-deleted? false)
copy1-root' (ths/get-shape file' :copy1-root)
main1-root' (ths/get-shape file' :main1-root)
main1-child' (ths/get-shape file' :main1-child)
saved-objects' (:objects component1')]
;; ==== Check
(t/is (nil? (:deleted component1')))
(t/is (some? copy1-root'))
(t/is (some? main1-root'))
(t/is (some? main1-child'))
(t/is (ctk/main-instance? main1-root'))
(t/is (ctk/main-instance-of? (:id main1-root') (:id page) component1'))
(t/is (nil? saved-objects'))))
(t/deftest test-instantiate-component
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component :component1
:main1-root
:main1-child))
page (thf/current-page file)
component (thc/get-component file :component1)
;; ==== Action
[new-shape changes]
(cll/generate-instantiate-component (-> (pcb/empty-changes nil (:id page)) ;; This may not be moved to generate
(pcb/with-objects (:objects page))) ;; because in some cases the objects
(:objects page) ;; not the same as those on the page
(:id file)
(:id component)
(gpt/point 1000 1000)
page
{(:id file) file})
file' (thf/apply-changes file changes)
;; ==== Get
component' (thc/get-component file' :component1)
main1-root' (ths/get-shape file' :main1-root)
main1-child' (ths/get-shape file' :main1-child)
copy1-root' (ths/get-shape-by-id file' (:id new-shape))
copy1-child' (ths/get-shape-by-id file' (first (:shapes copy1-root')))]
;; ==== Check
(t/is (some? main1-root'))
(t/is (some? main1-child'))
(t/is (some? copy1-root'))
(t/is (some? copy1-child'))
(t/is (ctk/instance-root? copy1-root'))
(t/is (ctk/instance-of? copy1-root' (:id file') (:id component')))
(t/is (ctk/is-main-of? main1-root' copy1-root' true))
(t/is (ctk/is-main-of? main1-child' copy1-child' true))
(t/is (ctst/parent-of? copy1-root' copy1-child'))))
(t/deftest test-instantiate-component-from-lib
(let [;; ==== Setup
library (-> (thf/sample-file :library1)
(tho/add-simple-component :component1
:main1-root
:main1-child))
file (thf/sample-file :file1)
page (thf/current-page file)
component (thc/get-component library :component1)
;; ==== Action
[new-shape changes]
(cll/generate-instantiate-component (-> (pcb/empty-changes nil (:id page))
(pcb/with-objects (:objects page)))
(:objects page)
(:id library)
(:id component)
(gpt/point 1000 1000)
page
{(:id file) file
(:id library) library})
file' (thf/apply-changes file changes)
;; ==== Get
component' (thc/get-component library :component1)
main1-root' (ths/get-shape library :main1-root)
main1-child' (ths/get-shape library :main1-child)
copy1-root' (ths/get-shape-by-id file' (:id new-shape))
copy1-child' (ths/get-shape-by-id file' (first (:shapes copy1-root')))]
;; ==== Check
(t/is (some? main1-root'))
(t/is (some? main1-child'))
(t/is (some? copy1-root'))
(t/is (some? copy1-child'))
(t/is (ctk/instance-root? copy1-root'))
(t/is (ctk/instance-of? copy1-root' (:id library) (:id component')))
(t/is (ctk/is-main-of? main1-root' copy1-root' true))
(t/is (ctk/is-main-of? main1-child' copy1-child' true))
(t/is (ctst/parent-of? copy1-root' copy1-child'))))
(t/deftest test-instantiate-nested-component
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-nested-component :component1
:main1-root
:main1-child
:component2
:main2-root
:main2-nested-head))
page (thf/current-page file)
component (thc/get-component file :component1)
;; ==== Action
[new-shape changes]
(cll/generate-instantiate-component (-> (pcb/empty-changes nil (:id page))
(pcb/with-objects (:objects page)))
(:objects page)
(:id file)
(:id component)
(gpt/point 1000 1000)
page
{(:id file) file})
file' (thf/apply-changes file changes)
;; ==== Get
component' (thc/get-component file' :component1)
main1-root' (ths/get-shape file' :main1-root)
main1-child' (ths/get-shape file' :main1-child)
copy1-root' (ths/get-shape-by-id file' (:id new-shape))
copy1-child' (ths/get-shape-by-id file' (first (:shapes copy1-root')))]
;; ==== Check
(t/is (some? main1-root'))
(t/is (some? main1-child'))
(t/is (some? copy1-root'))
(t/is (some? copy1-child'))
(t/is (ctk/instance-root? copy1-root'))
(t/is (ctk/instance-of? copy1-root' (:id file') (:id component')))
(t/is (ctk/is-main-of? main1-root' copy1-root' true))
(t/is (ctk/is-main-of? main1-child' copy1-child' true))
(t/is (ctst/parent-of? copy1-root' copy1-child'))))
(t/deftest test-instantiate-nested-component-from-lib
(let [;; ==== Setup
library (-> (thf/sample-file :file1)
(tho/add-nested-component :component1
:main1-root
:main1-child
:component2
:main2-root
:main2-nested-head))
file (thf/sample-file :file1)
page (thf/current-page file)
component (thc/get-component library :component1)
;; ==== Action
[new-shape changes]
(cll/generate-instantiate-component (-> (pcb/empty-changes nil (:id page))
(pcb/with-objects (:objects page)))
(:objects page)
(:id library)
(:id component)
(gpt/point 1000 1000)
page
{(:id file) file
(:id library) library})
file' (thf/apply-changes file changes)
;; ==== Get
component' (thc/get-component library :component1)
main1-root' (ths/get-shape library :main1-root)
main1-child' (ths/get-shape library :main1-child)
copy1-root' (ths/get-shape-by-id file' (:id new-shape))
copy1-child' (ths/get-shape-by-id file' (first (:shapes copy1-root')))]
;; ==== Check
(t/is (some? main1-root'))
(t/is (some? main1-child'))
(t/is (some? copy1-root'))
(t/is (some? copy1-child'))
(t/is (ctk/instance-root? copy1-root'))
(t/is (ctk/instance-of? copy1-root' (:id library) (:id component')))
(t/is (ctk/is-main-of? main1-root' copy1-root' true))
(t/is (ctk/is-main-of? main1-child' copy1-child' true))
(t/is (ctst/parent-of? copy1-root' copy1-child'))))
(t/deftest test-detach-copy
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main1-root
:main1-child
:copy1-root))
page (thf/current-page file)
copy1-root (ths/get-shape file :copy1-root)
;; ==== Action
changes (cll/generate-detach-component (pcb/empty-changes)
(:id copy1-root)
(:data file)
(:id page)
{(:id file) file})
file' (thf/apply-changes file changes)
;; ==== Get
copy1-root' (ths/get-shape file' :copy1-root)]
;; ==== Check
(t/is (some? copy1-root'))
(t/is (not (ctk/instance-head? copy1-root')))
(t/is (not (ctk/in-component-copy? copy1-root')))))

View file

@ -0,0 +1,359 @@
;; 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-reset-test
(:require
[app.common.files.changes-builder :as pcb]
[app.common.logic.libraries :as cll]
[app.common.logic.shapes :as cls]
[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-reset-after-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)
copy-root (ths/get-shape file :copy-root)
copy-child (ths/get-shape file :copy-child)
;; ==== Action
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy-child)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(:objects page)
{})
file-mdf (thf/apply-changes file changes)
page-mdf (thf/current-page file-mdf)
changes (cll/generate-reset-component (pcb/empty-changes)
file-mdf
{(:id file-mdf) file-mdf}
page-mdf
(:id copy-root)
true)
file' (thf/apply-changes file changes)
;; ==== 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') "#abcdef"))
(t/is (= (:fill-opacity fill') 1))
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') nil))))
(t/deftest test-reset-from-library
(let [;; ==== Setup
library (-> (thf/sample-file :library :is-shared true)
(tho/add-simple-component :component1 :main-root :main-child
: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 file)
copy-root (ths/get-shape file :copy-root)
copy-child (ths/get-shape file :copy-child)
;; ==== Action
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy-child)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(:objects page)
{})
file-mdf (thf/apply-changes file changes)
page-mdf (thf/current-page file-mdf)
changes (cll/generate-reset-component (pcb/empty-changes)
file-mdf
{(:id file-mdf) file-mdf
(:id library) library}
page-mdf
(:id copy-root)
true)
file' (thf/apply-changes file changes)
;; ==== 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') "#abcdef"))
(t/is (= (:fill-opacity fill') 1))
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') nil))))
(t/deftest test-reset-after-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)
copy-root (ths/get-shape file :copy-root)
;; ==== Action
;; IMPORTANT: as modifying copies structure is now forbidden, this action
;; will not have any effect, and so the parent shape won't also be touched.
changes (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
file-mdf (thf/apply-changes file changes)
page-mdf (thf/current-page file-mdf)
changes (cll/generate-reset-component (pcb/empty-changes)
file-mdf
{(:id file-mdf) file-mdf}
page-mdf
(:id copy-root)
true)
file' (thf/apply-changes file changes)
;; ==== 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 (some? copy-child'))
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') nil))))
(t/deftest test-reset-after-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)
copy-root (ths/get-shape file :copy-root)
copy-child (ths/get-shape file :copy-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 changes]
(cls/generate-delete-shapes (pcb/empty-changes)
file
page
(:objects page)
#{(:id copy-child)}
{:components-v2 true})
file-mdf (thf/apply-changes file changes)
page-mdf (thf/current-page file-mdf)
changes (cll/generate-reset-component (pcb/empty-changes)
file-mdf
{(:id file-mdf) file-mdf}
page-mdf
(:id copy-root)
true)
file' (thf/apply-changes file changes)
;; ==== 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 (some? copy-child'))
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') nil))))
(t/deftest test-reset-after-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-child]})
(ths/add-sample-shape :free-shape))
page (thf/current-page file)
copy-root (ths/get-shape file :copy-root)
copy-child1 (ths/get-shape file :copy-child)
;; ==== Action
;; IMPORTANT: as modifying copies structure is now forbidden, this action
;; will not have any effect, and so the parent shape won't also be touched.
changes (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
file-mdf (thf/apply-changes file changes)
page-mdf (thf/current-page file-mdf)
changes (cll/generate-reset-component (pcb/empty-changes)
file-mdf
{(:id file-mdf) file-mdf}
page-mdf
(:id copy-root)
true)
file' (thf/apply-changes file changes)
;; ==== 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 (some? copy-child'))
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') nil))))
(t/deftest test-reset-after-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)
copy2-root (ths/get-shape file :copy2-root)
;; ==== Action
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy2-root)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(:objects page)
{})
file-mdf (thf/apply-changes file changes)
page-mdf (thf/current-page file-mdf)
changes (cll/generate-reset-component (pcb/empty-changes)
file-mdf
{(:id file-mdf) file-mdf}
page-mdf
(:id copy2-root)
true)
file' (thf/apply-changes file changes)
;; ==== 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') "#abcdef"))
(t/is (= (:fill-opacity fill') 1))
(t/is (= (:touched copy2-root') nil))))
(t/deftest test-reset-after-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-root (ths/get-shape file :copy2-root)
copy2-child (ths/get-shape file :copy2-child)
;; ==== Action
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy2-child)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(:objects page)
{})
file-mdf (thf/apply-changes file changes)
page-mdf (thf/current-page file-mdf)
changes (cll/generate-reset-component (pcb/empty-changes)
file-mdf
{(:id file-mdf) file-mdf}
page-mdf
(:id copy2-root)
true)
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') "#FFFFFF"))
(t/is (= (:fill-opacity fill') 1))
(t/is (= (:touched copy2-root') nil))
(t/is (= (:touched copy2-child') nil))))

View file

@ -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))))

View file

@ -0,0 +1,330 @@
;; 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-touched-test
(:require
[app.common.files.changes-builder :as pcb]
[app.common.logic.shapes :as cls]
[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-touched-when-changing-attribute
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main-root
:main-child
:copy-root
:main-child-params {:fills (ths/sample-fills-color
:fill-color "#abcdef")}
:copy-root-params {:children-labels [:copy-child]}))
page (thf/current-page file)
copy-child (ths/get-shape file :copy-child)
;; ==== Action
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy-child)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(:objects page)
{})
file' (thf/apply-changes file changes)
;; ==== 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') #{:fill-group}))))
(t/deftest test-touched-from-library
(let [;; ==== Setup
library (-> (thf/sample-file :library :is-shared true)
(tho/add-simple-component :component1 :main-root :main-child
: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 file)
copy-child (ths/get-shape file :copy-child)
;; ==== Action
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy-child)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(:objects page)
{})
file' (thf/apply-changes file changes)
;; ==== 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') #{:fill-group}))))
(t/deftest test-not-touched-when-adding-shape
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main-root
:main-child
:copy-root
:copy-root-params {:children-labels [:copy-child]})
(ths/add-sample-shape :free-shape))
page (thf/current-page file)
copy-root (ths/get-shape file :copy-root)
;; ==== Action
;; IMPORTANT: as modifying copies structure is now forbidden, this action
;; will not have any effect, and so the parent shape won't also be touched.
changes (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
file' (thf/apply-changes file changes)
;; ==== 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 (some? copy-child'))
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') nil))))
(t/deftest test-not-touched-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)
copy-child (ths/get-shape file :copy-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 changes]
(cls/generate-delete-shapes (pcb/empty-changes)
file
page
(:objects page)
#{(:id copy-child)}
{:components-v2 true})
file' (thf/apply-changes file changes)
;; ==== 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 (some? copy-child'))
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') #{:visibility-group}))))
(t/deftest test-not-touched-when-moving-shape
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-component-with-many-children-and-copy :component1
:main-root
[:main-child1 :main-child2 :main-child3]
:copy-root
:copy-root-params {:children-labels [:copy-child1
:copy-child2
:copy-child3]})
(ths/add-sample-shape :free-shape))
page (thf/current-page file)
copy-child1 (ths/get-shape file :copy-child1)
;; ==== Action
;; IMPORTANT: as modifying copies structure is now forbidden, this action
;; will not have any effect, and so the parent shape won't also be touched.
changes (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
file' (thf/apply-changes file changes)
;; ==== 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 (= (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
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)
copy2-root (ths/get-shape file :copy2-root)
;; ==== Action
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy2-root)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(:objects page)
{})
file' (thf/apply-changes file changes)
;; ==== 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') #{: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
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy2-child)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(: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}))))
(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
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
#{(:id copy2-child)}
(fn [shape]
(assoc shape :fills (ths/sample-fills-color :fill-color "#fabada")))
(: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}))))

View file

@ -1,47 +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 common-tests.logic.component-creation-test
(:require
[app.common.files.changes-builder :as pcb]
[app.common.logic.libraries :as cll]
[clojure.test :as t]
[common-tests.helpers.components :as thc]
[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-add-component-from-single-shape
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(ths/add-sample-shape :shape1 :type :frame))
page (thf/current-page file)
shape1 (ths/get-shape file :shape1)
;; ==== Action
[_ component-id changes]
(cll/generate-add-component (pcb/empty-changes)
[shape1]
(:objects page)
(:id page)
(:id file)
true
nil
nil)
file' (thf/apply-changes file changes)
;; ==== Get
component (thc/get-component-by-id file' component-id)
root (ths/get-shape-by-id file' (:main-instance-id component))]
;; ==== Check
(t/is (some? component))
(t/is (some? root))
(t/is (= (:component-id root) (:id component)))))

View file

@ -1,234 +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 common-tests.logic.components-touched-test
(:require
[app.common.files.changes-builder :as pcb]
[app.common.logic.shapes :as cls]
[clojure.test :as t]
[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-touched-when-changing-attribute
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main-root
:main-child
:copy-root
:main-child-params {:fills (ths/sample-fills-color
:fill-color "#abcdef")}))
page (thf/current-page file)
copy-root (ths/get-shape file :copy-root)
;; ==== 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))
(:shapes copy-root)
update-fn
(:objects page)
{})
file' (thf/apply-changes file changes)
;; ==== Get
copy-root' (ths/get-shape file' :copy-root)
copy-child' (ths/get-shape-by-id file' (first (:shapes copy-root')))
fills' (:fills copy-child')
fill' (first fills')]
;; ==== Check
(t/is (= (count fills') 1))
(t/is (= (:fill-color fill') "#fabada"))
(t/is (= (:fill-opacity fill') 1))
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') #{:fill-group}))))
(t/deftest test-not-touched-when-adding-shape
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main-root
:main-child
:copy-root)
(ths/add-sample-shape :free-shape))
page (thf/current-page file)
copy-root (ths/get-shape file :copy-root)
;; ==== Action
;; IMPORTANT: as modifying copies structure is now forbidden, this action
;; will not have any effect, and so the parent shape won't also be touched.
changes (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
file' (thf/apply-changes file changes)
;; ==== Get
copy-root' (ths/get-shape file' :copy-root)
copy-child' (ths/get-shape-by-id file' (first (:shapes copy-root')))]
;; ==== Check
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') nil))))
(t/deftest test-touched-when-deleting-shape
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-simple-component-with-copy :component1
:main-root
:main-child
:copy-root))
page (thf/current-page file)
copy-root (ths/get-shape file :copy-root)
;; ==== Action
;; IMPORTANT: as modifying copies structure is now forbidden, this action will not
;; delete the child shape, but hide it (thus setting the visibility group).
[_all-parents changes]
(cls/generate-delete-shapes (pcb/empty-changes)
file
page
(:objects page)
(set (:shapes copy-root))
{:components-v2 true})
file' (thf/apply-changes file changes)
;; ==== Get
copy-root' (ths/get-shape file' :copy-root)
copy-child' (ths/get-shape-by-id file' (first (:shapes copy-root')))]
;; ==== Check
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') #{:visibility-group}))))
(t/deftest test-not-touched-when-moving-shape
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(tho/add-component-with-many-children-and-copy :component1
:main-root
[:main-child1 :main-child2 :main-child3]
:copy-root)
(ths/add-sample-shape :free-shape))
page (thf/current-page file)
copy-root (ths/get-shape file :copy-root)
copy-child1 (ths/get-shape-by-id file (first (:shapes copy-root)))
;; ==== Action
;; IMPORTANT: as modifying copies structure is now forbidden, this action
;; will not have any effect, and so the parent shape won't also be touched.
changes (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
file' (thf/apply-changes file changes)
;; ==== Get
copy-root' (ths/get-shape file' :copy-root)
copy-child' (ths/get-shape-by-id file' (first (:shapes copy-root')))]
;; ==== Check
(t/is (= (:touched copy-root') nil))
(t/is (= (:touched copy-child') nil))))
(t/deftest test-touched-when-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
:root2-params {:fills (ths/sample-fills-color
:fill-color "#abcdef")}))
page (thf/current-page file)
copy2-root (ths/get-shape file :copy2-root)
;; ==== 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-root)}
update-fn
(:objects page)
{})
file' (thf/apply-changes file changes)
;; ==== Get
copy2-root' (ths/get-shape file' :copy2-root)
fills' (:fills copy2-root')
fill' (first fills')]
;; ==== Check
(t/is (= (count fills') 1))
(t/is (= (:fill-color fill') "#fabada"))
(t/is (= (:fill-opacity fill') 1))
(t/is (= (:touched copy2-root') #{: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
:nested-head-params {:fills (ths/sample-fills-color
:fill-color "#abcdef")}))
page (thf/current-page file)
copy2-root (ths/get-shape file :copy2-root)
;; ==== 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))
(:shapes copy2-root)
update-fn
(:objects page)
{})
file' (thf/apply-changes file changes)
;; ==== Get
copy2-root' (ths/get-shape file' :copy2-root)
copy2-child' (ths/get-shape-by-id file' (first (:shapes copy2-root')))
fills' (:fills copy2-child')
fill' (first fills')]
;; ==== Check
(t/is (= (count fills') 1))
(t/is (= (:fill-color fill') "#fabada"))
(t/is (= (:fill-opacity fill') 1))
(t/is (= (:touched copy2-root') nil))
(t/is (= (:touched copy2-child') #{:fill-group}))))

File diff suppressed because it is too large Load diff

View file

@ -1,860 +0,0 @@
(ns frontend-tests.state-components-test
(:require
[app.common.geom.point :as gpt]
[app.common.types.components-list :as ctkl]
[app.common.types.container :as ctn]
[app.common.types.file :as ctf]
[app.main.data.workspace :as dw]
[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]
[linked.core :as lks]
[potok.v2.core :as ptk]))
(t/use-fixtures :each
{:before thp/reset-idmap!})
(t/deftest test-add-component-from-single-shape
(t/testing "test-add-component-from-single-shape"
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"}))
store (the/prepare-store state done
(fn [new-state]
;; Uncomment to debug
;; (ctf/dump-tree (get new-state :workspace-data)
;; (get new-state :current-page-id)
;; (get new-state :workspace-libraries)
;; false true)
;; Expected shape tree:
;;
;; [Page]
;; Root Frame
;; Rect 1 #--> Rect 1
;; Rect 1 ---> Rect 1
;;
;; [Rect 1]
;; Rect 1
;; Rect 1
;;
(let [shape1 (thp/get-shape new-state :shape1)
[[group shape1] [c-group c-shape1] component]
(thl/resolve-instance-and-main
new-state
(:parent-id shape1))
file (wsh/get-local-file new-state)]
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:name component) "Rect 1"))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:name c-group) "Rect 1"))
(thl/is-from-file group file))))]
(ptk/emit!
store
(dw/select-shape (thp/id :shape1))
(dwl/add-component)
:the/end)))))
(t/deftest test-add-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"}))
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;; [Page]
;; Root Frame
;; Component 1
;; Rect 1
;; Rect-2
;;
;; [Component 1]
;; page1 / Component 1
;;
(let [shape1 (thp/get-shape new-state :shape1)
[[group shape1 shape2]
[c-group c-shape1 c-shape2]
component]
(thl/resolve-instance-and-main
new-state
(:parent-id shape1))
file (wsh/get-local-file new-state)]
(t/is (= (:name group) "Component 1"))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name shape2) "Rect-2"))
(t/is (= (:name component) "Component 1"))
(t/is (= (:name c-group) "Component 1"))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:name c-shape2) "Rect-2"))
(thl/is-from-file group file))))]
(ptk/emit!
store
(dw/select-shapes (lks/set (thp/id :shape1)
(thp/id :shape2)))
(dwl/add-component)
:the/end))))
(t/deftest test-add-component-from-frame
(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/frame-shapes :frame1
[(thp/id :shape1)
(thp/id :shape2)]))
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;
;; [Page]
;; Root Frame
;; Group
;; Rect 1
;; Rect-2
;;
;; [Group]
;; page1 / Group
;;
(let [[[group shape1 shape2]
[c-group c-shape1 c-shape2]
component]
(thl/resolve-instance-and-main
new-state
(thp/id :frame1))
file (wsh/get-local-file new-state)]
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name shape2) "Rect-2"))
(t/is (= (:name group) "Board"))
(t/is (= (:name component) "Board"))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:name c-shape2) "Rect-2"))
(t/is (= (:name c-group) "Board"))
(thl/is-from-file group file))))]
(ptk/emit!
store
(dw/select-shape (thp/id :frame1))
(dwl/add-component)
:the/end))))
(t/deftest test-add-component-from-component-instance
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)])
(thp/instantiate-component :instance1 (thp/id :component1)))
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;
;; [Page: Page]
;; Root Frame
;; 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)
true)
[[instance2 instance1' shape1']
[c-instance2 c-instance1' c-shape1']
component2]
(thl/resolve-instance-and-main
new-state
(:parent-id instance1))]
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:name component1) "Rect 1"))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:name shape1') "Rect 1"))
(t/is (= (:name instance1') "Rect 1"))
(t/is (= (:name instance2) "Rect 1"))
(t/is (= (:name component2) "Rect 1"))
(t/is (= (:name c-shape1') "Rect 1"))
(t/is (= (:name c-instance1') "Rect 1"))
(t/is (= (:name c-instance2) "Rect 1")))))]
(ptk/emit!
store
(dw/select-shape (thp/id :instance1))
(dwl/add-component)
:the/end))))
(t/deftest test-add-component-from-component-main
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)]))
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;
;; [Page]
;; Root Frame
;; Rect 1
;; Rect 1
;;
;; [Rect 1]
;; page1 / Rect 1
;;
(let [file (wsh/get-local-file new-state)
components (ctkl/components file)
page (thp/current-page new-state)
shape1 (thp/get-shape new-state :shape1)
parent1 (ctn/get-shape page (:parent-id shape1))
main1 (thp/get-shape state :main1)
[[instance1 shape1]
[c-instance1 c-shape1]
component1]
(thl/resolve-instance-and-main
new-state
(:id main1))]
;; Creating a component from a main doesn't generate a new component
(t/is (= (count components) 1))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:name component1) "Rect 1"))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:name c-instance1) "Rect 1")))))]
(ptk/emit!
store
(dw/select-shape (thp/id :main1))
(dwl/add-component)
:the/end))))
(t/deftest test-rename-component
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)]))
main1 (thp/get-shape state :main1)
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;
;; [Page]
;; Root Frame
;; Rect 1
;; Rect 1
;;
;; [Renamed component]
;; page1 / Rect 1
;;
(let [libs (wsh/get-libraries new-state)
component (ctf/get-component libs
(:component-file main1)
(:component-id main1))]
(t/is (= (:name component)
"Renamed component")))))]
(ptk/emit!
store
(dwl/rename-component (:component-id main1) "Renamed component")
:the/end))))
(t/deftest test-duplicate-component
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)]))
main1 (thp/get-shape state :main1)
component-id (:component-id main1)
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]
;; page1 / Rect 1
;;
;; [Rect 1]
;; page1 / Rect 1
;;
(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-main
new-state
(:id main1))
[[_c-component2 _c-shape2]
component2]
(thl/resolve-component
new-state
(:current-file-id new-state)
new-component-id)]
(t/is (= (:name component2) "Rect 1")))))]
(ptk/emit!
store
(dwl/duplicate-component thp/current-file-id component-id)
:the/end))))
(t/deftest test-delete-component
(t/async done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect {:name "Rect 1"})
(thp/make-component :main1 :component1 [(thp/id :shape1)])
(thp/instantiate-component :instance1 (thp/id :component1)))
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;;
;; [Page]
;; Root Frame
;; Rect 1 #--> ?
;; Rect 1 ---> ?
;;;
(let [[main1 shape1]
(thl/resolve-noninstance
new-state
(thp/id :main1))
[[instance1 shape2] [c-instance1 c-shape2] component1]
(thl/resolve-instance-and-main-allow-dangling
new-state
(thp/id :instance1))
file (wsh/get-local-file new-state)
component2 (ctkl/get-component file (thp/id :component1))
component3 (ctkl/get-deleted-component file (thp/id :component1))
saved-objects (:objects component3)
saved-main1 (get saved-objects (:shape-ref instance1))
saved-shape2 (get saved-objects (:shape-ref shape2))]
(t/is (nil? main1))
(t/is (nil? shape1))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (not= (:shape-ref instance1) nil))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:touched shape2) nil))
(t/is (not= (:shape-ref shape2) nil))
(t/is (nil? c-instance1))
(t/is (nil? c-shape2))
(t/is (nil? component1))
(t/is (nil? component2))
(t/is (= (:name component3) "Rect 1"))
(t/is (= (:deleted component3) true))
(t/is (some? (:objects component3)))
(t/is (= (:name saved-main1) "Rect 1"))
(t/is (= (:name saved-shape2) "Rect 1")))))]
(ptk/emit! store
(dwl/delete-component {:id (thp/id :component1)})
:the/end))))
(t/deftest test-restore-component
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)])
(thp/instantiate-component :instance1
(thp/id :component1)))
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]
;; page1 / Rect 1
;;
(let [[[instance1 shape2] [c-instance1 c-shape2] component1]
(thl/resolve-instance-and-main
new-state
(thp/id :instance1))
file (wsh/get-local-file new-state)
component2 (ctkl/get-component file (thp/id :component1))
saved-objects (:objects component2)]
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:name c-shape2) "Rect 1"))
(t/is (some? component1))
(t/is (some? component2))
(t/is (nil? saved-objects)))))]
(ptk/emit!
store
(dwl/delete-component {:id (thp/id :component1)})
(dwl/restore-component thp/current-file-id (thp/id :component1))
:the/end))))
(t/deftest test-instantiate-component
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)]))
file (wsh/get-local-file state)
component-id (thp/id :component1)
main1 (thp/get-shape state :main1)
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]
;; page1 / Rect 1
;;
(let [new-instance-id (-> new-state
wsh/lookup-selected
first)
[[instance1 shape2]
[c-instance1 c-shape2]
component]
(thl/resolve-instance-and-main
new-state
new-instance-id)]
(t/is (not= (:id main1) (:id instance1)))
(t/is (= (:id component) component-id))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:name c-shape2) "Rect 1"))
(t/is (= (:component-file instance1)
thp/current-file-id)))))]
(ptk/emit!
store
(dwl/instantiate-component (:id file)
component-id
(gpt/point 100 100))
:the/end))))
(t/deftest test-instantiate-component-from-lib
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)])
(thp/move-to-library :lib1 "Library 1")
(thp/sample-page))
library-id (thp/id :lib1)
component-id (thp/id :component1)
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;
;; [Page]
;; Root Frame
;; Rect 1 #--> <Library 1> Rect 1
;; Rect 1 ---> <Library 1> Rect 1
;;
(let [new-instance-id (-> new-state
wsh/lookup-selected
first)
[[instance1 shape2]
[c-instance1 c-shape2]
component]
(thl/resolve-instance-and-main
new-state
new-instance-id)]
(t/is (= (:id component) component-id))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:name c-shape2) "Rect 1"))
(t/is (= (:component-file instance1) library-id)))))]
(ptk/emit!
store
(dwl/instantiate-component library-id
component-id
(gpt/point 100 100))
:the/end))))
(t/deftest test-detach-component
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)])
(thp/instantiate-component :instance1
(thp/id :component1)))
instance1 (thp/get-shape state :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]
;; page1 / Rect 1
;;
(let [[instance2 shape1]
(thl/resolve-noninstance
new-state
(:id instance1))]
(t/is (some? instance2))
(t/is (some? shape1)))))]
(ptk/emit!
store
(dwl/detach-component (:id instance1))
:the/end))))
(t/deftest test-add-nested-component-instance
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)])
(thp/instantiate-component :instance1 (thp/id :component1)))
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;
;; [Page]
;; Root Frame
;; Rect 1
;; Rect 1
;; Board
;; Rect 1
;; Rect 1
;;
;; [Rect 1]
;; page1 / Rect 1
;;
;; [Board]
;; page1 / Board
;;
(let [instance1 (thp/get-shape new-state :instance1)
[[group shape1 shape2]
[c-group c-shape1 c-shape2]
component]
(thl/resolve-instance-and-main
new-state
(:parent-id instance1))]
(t/is (= (:name group) "Board"))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:name component) "Board"))
(t/is (= (:name c-group) "Board"))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:name c-shape2) "Rect 1")))))]
(ptk/emit!
store
(dw/select-shape (thp/id :instance1))
(dwsh/create-artboard-from-selection)
(dwl/add-component)
:the/end))))
(t/deftest test-add-nested-component-main
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"}))
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;
;; [Page]
;; Root Frame
;; Board
;; Rect 1
;; Rect 1
;;
;; [Rect 1]
;; page1 / Rect 1
;;
;;
(let [file (wsh/get-local-file new-state)
components (ctkl/components file)
page (thp/current-page new-state)
shape1 (thp/get-shape new-state :shape1)
parent1 (ctn/get-shape page (:parent-id shape1))
[[group shape1]
[c-group c-shape1]
component]
(thl/resolve-instance-and-main
new-state
(:parent-id shape1))]
;; Creating a component from something containing a main doesn't generate a new component
(t/is (= (count components) 1))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name component) "Rect 1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:name c-shape1) "Rect 1")))))]
(ptk/emit!
store
(dw/select-shape (thp/id :shape1))
(dwl/add-component)
(dwsh/create-artboard-from-selection)
(dwl/add-component)
:the/end))))
(t/deftest test-instantiate-nested-component
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 1"})
(thp/make-component :main1 :component1
[(thp/id :shape1)])
(thp/make-component :main2 :component-2
[(thp/id :main1)]))
file (wsh/get-local-file state)
main1 (thp/get-shape state :main1)
main2 (thp/get-shape state :main2)
component-id (:component-id main2)
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]
;; page1 / Rect 1
;;
;; [Rect 1]
;; page1 / Rect 1
;;
(let [new-instance-id (-> new-state
wsh/lookup-selected
first)
[[instance1 shape1 shape2]
[c-instance1 c-shape1 c-shape2]
component]
(thl/resolve-instance-and-main
new-state
new-instance-id)]
;; TODO: get and check the instance inside component [Rect-2]
(t/is (not= (:id main1) (:id instance1)))
(t/is (= (:id component) component-id))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:name c-shape2) "Rect 1")))))]
(ptk/emit!
store
(dwl/instantiate-component (:id file)
(:component-id main2)
(gpt/point 100 100))
:the/end))))
(t/deftest test-instantiate-nested-component-from-lib
(t/async
done
(let [state (-> thp/initial-state
(thp/sample-page)
(thp/sample-shape :shape1 :rect
{:name "Rect 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)))
file (wsh/get-local-file state)
library-id (thp/id :lib1)
store (the/prepare-store state done
(fn [new-state]
;; Expected shape tree:
;;
;; [Page]
;; Root Frame
;; Group
;; Rect 1 #--> <Library 1> Rect 1
;; Rect 1 ---> <Library 1> Rect 1
;;
;; [Group]
;; page1 / Group
;;
(let [instance1 (thp/get-shape new-state :instance1)
[[group1 shape1 shape2] [c-group1 c-shape1 c-shape2] _component]
(thl/resolve-instance-and-main
new-state
(:parent-id instance1))]
(t/is (= (:name group1) "Board"))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:name c-group1) "Board"))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:name c-shape2) "Rect 1"))
(t/is (= (:component-file group1) thp/current-file-id))
(t/is (= (:component-file shape1) library-id))
(t/is (= (:component-file shape2) nil))
(t/is (= (:component-file c-group1) (:id file)))
(t/is (= (:component-file c-shape1) library-id))
(t/is (= (:component-file c-shape2) nil)))))]
(ptk/emit!
store
(dw/select-shape (thp/id :instance1))
(dwsh/create-artboard-from-selection)
(dwl/add-component)
:the/end))))