mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
2725 lines
126 KiB
Clojure
2725 lines
126 KiB
Clojure
;; 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.variants-switch-test
|
|
(:require
|
|
[app.common.files.changes-builder :as pcb]
|
|
[app.common.logic.shapes :as cls]
|
|
[app.common.test-helpers.components :as thc]
|
|
[app.common.test-helpers.compositions :as tho]
|
|
[app.common.test-helpers.files :as thf]
|
|
[app.common.test-helpers.ids-map :as thi]
|
|
[app.common.test-helpers.shapes :as ths]
|
|
[app.common.test-helpers.variants :as thv]
|
|
[clojure.test :as t]))
|
|
|
|
(t/use-fixtures :each thi/test-fixture)
|
|
|
|
;; ============================================================
|
|
;; BASIC SWITCH TESTS (no overrides)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-basic-switch
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant
|
|
:v01 :c01 :m01 :c02 :m02
|
|
{:variant1-params {:width 5}
|
|
:variant2-params {:width 15}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01))
|
|
copy01 (ths/get-shape file :copy01)
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
copy01' (ths/get-shape file' :copy02)]
|
|
(thf/dump-file file :keys [:width])
|
|
;; The copy had width 5 before the switch
|
|
(t/is (= (:width copy01) 5))
|
|
;; The rect has width 15 after the switch
|
|
(t/is (= (:width copy01') 15))))
|
|
|
|
(t/deftest test-simple-switch
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 5}
|
|
:child2-params {:width 15}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
;; The rect had width 5 before the switch
|
|
(t/is (= (:width rect01) 5))
|
|
;; The rect has width 15 after the switch
|
|
(t/is (= (:width rect02') 15))))
|
|
|
|
;; ============================================================
|
|
;; SIMPLE ATTRIBUTE OVERRIDES (identical variants)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-basic-switch-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant
|
|
:v01 :c01 :m01 :c02 :m02
|
|
{:variant1-params {:width 5}
|
|
:variant2-params {:width 5}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01))
|
|
copy01 (ths/get-shape file :copy01)
|
|
|
|
;; Change width of copy
|
|
page (thf/current-page file)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id copy01)}
|
|
(fn [shape]
|
|
(assoc shape :width 25))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
copy01 (ths/get-shape file :copy01)
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
copy01' (ths/get-shape file' :copy02)]
|
|
(thf/dump-file file :keys [:width])
|
|
;; The copy had width 25 before the switch
|
|
(t/is (= (:width copy01) 25))
|
|
;; The override is keept: The copy still has width 25 after the switch
|
|
(t/is (= (:width copy01') 25))))
|
|
|
|
(t/deftest test-switch-with-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 5}
|
|
:child2-params {:width 5}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :width 25))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had width 25 before the switch
|
|
(t/is (= (:width rect01) 25))
|
|
;; The override is keept: The rect still has width 25 after the switch
|
|
(t/is (= (:width rect02') 25))))
|
|
|
|
;; ============================================================
|
|
;; SIMPLE ATTRIBUTE OVERRIDES (different variants)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-no-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 5}
|
|
:child2-params {:width 15}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :width 25))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had width 25 before the switch
|
|
(t/is (= (:width rect01) 25))
|
|
;; The override isn't keept, because the property is different in the mains
|
|
;; The rect has width 15 after the switch
|
|
(t/is (= (:width rect02') 15))))
|
|
|
|
;; ============================================================
|
|
;; TEXT OVERRIDES (identical variants)
|
|
;; ============================================================
|
|
|
|
(def font-size-path-paragraph [:content :children 0 :children 0 :font-size])
|
|
(def font-size-path-0 [:content :children 0 :children 0 :children 0 :font-size])
|
|
(def font-size-path-1 [:content :children 0 :children 0 :children 1 :font-size])
|
|
|
|
(def text-path-0 [:content :children 0 :children 0 :children 0 :text])
|
|
(def text-path-1 [:content :children 0 :children 0 :children 1 :text])
|
|
(def text-lines-path [:content :children 0 :children 0 :children])
|
|
|
|
(defn- update-attr
|
|
[file label path value]
|
|
(let [page (thf/current-page file)
|
|
shape (ths/get-shape file label)
|
|
changes (cls/generate-update-shapes
|
|
(pcb/empty-changes nil (:id page))
|
|
#{(:id shape)}
|
|
(fn [shape]
|
|
(cond-> (assoc-in shape path value)
|
|
(or (= path font-size-path-0) (= path font-size-path-1))
|
|
(assoc-in font-size-path-paragraph value)))
|
|
(:objects page)
|
|
{})]
|
|
(thf/apply-changes file changes)))
|
|
|
|
(defn- change-structure
|
|
[file label]
|
|
(let [page (thf/current-page file)
|
|
shape (ths/get-shape file label)
|
|
line1 (-> (get-in shape text-lines-path)
|
|
first
|
|
(assoc :text "new line 1"))
|
|
line2 (assoc line1 :text "new line 2")
|
|
changes (cls/generate-update-shapes
|
|
(pcb/empty-changes nil (:id page))
|
|
#{(:id shape)}
|
|
(fn [shape]
|
|
(assoc-in shape text-lines-path [line1 line2]))
|
|
(:objects page)
|
|
{})]
|
|
(thf/apply-changes file changes)))
|
|
|
|
(t/deftest test-switch-with-identical-text-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Both components are identical: have the same text and props
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "hello world")
|
|
(thc/instantiate-component :c01
|
|
:copy-clean
|
|
:children-labels [:copy-clean-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-font-size
|
|
:children-labels [:copy-font-size-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-text
|
|
:children-labels [:copy-text-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-both
|
|
:children-labels [:copy-both-t]))
|
|
|
|
|
|
;; The copy clean has no overrides
|
|
|
|
|
|
copy-clean (ths/get-shape file :copy-clean)
|
|
copy-clean-t (ths/get-shape file :copy-clean-t)
|
|
|
|
;; Override font size on copy-font-size
|
|
file (update-attr file :copy-font-size-t font-size-path-0 "25")
|
|
copy-font-size (ths/get-shape file :copy-font-size)
|
|
copy-font-size-t (ths/get-shape file :copy-font-size-t)
|
|
|
|
;; Override text on copy-text
|
|
file (update-attr file :copy-text-t text-path-0 "text overriden")
|
|
copy-text (ths/get-shape file :copy-text)
|
|
copy-text-t (ths/get-shape file :copy-text-t)
|
|
|
|
;; Override both on copy-both
|
|
file (update-attr file :copy-both-t font-size-path-0 "25")
|
|
file (update-attr file :copy-both-t text-path-0 "text overriden")
|
|
copy-both (ths/get-shape file :copy-both)
|
|
copy-both-t (ths/get-shape file :copy-both-t)
|
|
|
|
|
|
;; ==== Action: Switch all the copies
|
|
|
|
|
|
file' (-> file
|
|
(tho/swap-component copy-clean :c02 {:new-shape-label :copy-clean-2 :keep-touched? true})
|
|
(tho/swap-component copy-font-size :c02 {:new-shape-label :copy-font-size-2 :keep-touched? true})
|
|
(tho/swap-component copy-text :c02 {:new-shape-label :copy-text-2 :keep-touched? true})
|
|
(tho/swap-component copy-both :c02 {:new-shape-label :copy-both-2 :keep-touched? true}))
|
|
page' (thf/current-page file')
|
|
copy-clean' (ths/get-shape file' :copy-clean-2)
|
|
copy-clean-t' (get-in page' [:objects (-> copy-clean' :shapes first)])
|
|
|
|
copy-font-size' (ths/get-shape file' :copy-font-size-2)
|
|
copy-font-size-t' (get-in page' [:objects (-> copy-font-size' :shapes first)])
|
|
|
|
copy-text' (ths/get-shape file' :copy-text-2)
|
|
copy-text-t' (get-in page' [:objects (-> copy-text' :shapes first)])
|
|
|
|
copy-both' (ths/get-shape file' :copy-both-2)
|
|
copy-both-t' (get-in page' [:objects (-> copy-both' :shapes first)])]
|
|
|
|
(thf/dump-file file' {:keys [:name #_:content]})
|
|
|
|
|
|
;;;;;;;;;;; Clean copy
|
|
;; Before the switch:
|
|
;; * font size 14
|
|
;; * text "hello world"
|
|
|
|
|
|
(t/is (= (get-in copy-clean-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-clean-t text-path-0) "hello world"))
|
|
|
|
;; After the switch:
|
|
;; * font size 25 (value of c02, because there was no override)
|
|
;; * text "hello world" (value of c02, because there was no override)
|
|
(t/is (= (get-in copy-clean-t' font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-clean-t' text-path-0) "hello world"))
|
|
|
|
|
|
;;;;;;;;;;; Font size copy
|
|
;; Before the switch:
|
|
;; * font size 25
|
|
;; * text "hello world"
|
|
|
|
|
|
(t/is (= (get-in copy-font-size-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-font-size-t text-path-0) "hello world"))
|
|
|
|
;; After the switch:
|
|
;; * font size 25 (the override is preserved)
|
|
;; * text "hello world" (value of c02, because there was no override)
|
|
(t/is (= (get-in copy-font-size-t' font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-font-size-t' text-path-0) "hello world"))
|
|
|
|
;;;;;;;;;;; Text copy
|
|
;; Before the switch:
|
|
;; * font size 14
|
|
;; * text "text overriden"
|
|
(t/is (= (get-in copy-text-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-text-t text-path-0) "text overriden"))
|
|
|
|
;; After the switch:
|
|
;; * font size 14 (value of c02, because there was no override)
|
|
;; * text "text overriden" (the override is preserved)
|
|
(t/is (= (get-in copy-text-t' font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-text-t' text-path-0) "text overriden"))
|
|
|
|
;;;;;;;;;;; Both copy
|
|
;; Before the switch:
|
|
;; * font size 25
|
|
;; * text "text overriden"
|
|
(t/is (= (get-in copy-both-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-both-t text-path-0) "text overriden"))
|
|
|
|
;; After the switch:
|
|
;; * font size 25 (the override is preserved)
|
|
;; * text "text overriden" (the override is preserved)
|
|
(t/is (= (get-in copy-both-t' font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-both-t' text-path-0) "text overriden"))))
|
|
|
|
;; ============================================================
|
|
;; TEXT OVERRIDES (different property)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-different-prop-text-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; The second component has a different prop
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "hello world")
|
|
(update-attr :t02 font-size-path-0 "50")
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy-clean
|
|
:children-labels [:copy-clean-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-font-size
|
|
:children-labels [:copy-font-size-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-text
|
|
:children-labels [:copy-text-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-both
|
|
:children-labels [:copy-both-t]))
|
|
|
|
|
|
;; The copy clean has no overrides
|
|
|
|
|
|
copy-clean (ths/get-shape file :copy-clean)
|
|
copy-clean-t (ths/get-shape file :copy-clean-t)
|
|
|
|
;; Override font size on copy-font-size
|
|
file (update-attr file :copy-font-size-t font-size-path-0 "25")
|
|
copy-font-size (ths/get-shape file :copy-font-size)
|
|
copy-font-size-t (ths/get-shape file :copy-font-size-t)
|
|
|
|
;; Override text on copy-text
|
|
file (update-attr file :copy-text-t text-path-0 "text overriden")
|
|
copy-text (ths/get-shape file :copy-text)
|
|
copy-text-t (ths/get-shape file :copy-text-t)
|
|
|
|
;; Override both on copy-both
|
|
file (update-attr file :copy-both-t font-size-path-0 "25")
|
|
file (update-attr file :copy-both-t text-path-0 "text overriden")
|
|
copy-both (ths/get-shape file :copy-both)
|
|
copy-both-t (ths/get-shape file :copy-both-t)
|
|
|
|
|
|
;; ==== Action: Switch all the copies
|
|
|
|
|
|
file' (-> file
|
|
(tho/swap-component copy-clean :c02 {:new-shape-label :copy-clean-2 :keep-touched? true})
|
|
(tho/swap-component copy-font-size :c02 {:new-shape-label :copy-font-size-2 :keep-touched? true})
|
|
(tho/swap-component copy-text :c02 {:new-shape-label :copy-text-2 :keep-touched? true})
|
|
(tho/swap-component copy-both :c02 {:new-shape-label :copy-both-2 :keep-touched? true}))
|
|
page' (thf/current-page file')
|
|
copy-clean' (ths/get-shape file' :copy-clean-2)
|
|
copy-clean-t' (get-in page' [:objects (-> copy-clean' :shapes first)])
|
|
|
|
copy-font-size' (ths/get-shape file' :copy-font-size-2)
|
|
copy-font-size-t' (get-in page' [:objects (-> copy-font-size' :shapes first)])
|
|
|
|
copy-text' (ths/get-shape file' :copy-text-2)
|
|
copy-text-t' (get-in page' [:objects (-> copy-text' :shapes first)])
|
|
|
|
copy-both' (ths/get-shape file' :copy-both-2)
|
|
copy-both-t' (get-in page' [:objects (-> copy-both' :shapes first)])]
|
|
|
|
(thf/dump-file file' {:keys [:name #_:content]})
|
|
|
|
|
|
;;;;;;;;;;; Clean copy
|
|
;; Before the switch:
|
|
;; * font size 14
|
|
;; * text "hello world"
|
|
|
|
|
|
(t/is (= (get-in copy-clean-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-clean-t text-path-0) "hello world"))
|
|
|
|
;; After the switch:
|
|
;; * font size 50 (value of c02, because there was no override)
|
|
;; * text "hello world" (value of c02, because there was no override)
|
|
(t/is (= (get-in copy-clean-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-clean-t' text-path-0) "hello world"))
|
|
|
|
|
|
;;;;;;;;;;; Font size copy
|
|
;; Before the switch:
|
|
;; * font size 25
|
|
;; * text "hello world"
|
|
|
|
|
|
(t/is (= (get-in copy-font-size-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-font-size-t text-path-0) "hello world"))
|
|
|
|
;; After the switch:
|
|
;; * font size 50 (value of c02: the override is not preserved)
|
|
;; * text "hello world" (value of c02, because there was no override)
|
|
(t/is (= (get-in copy-font-size-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-font-size-t' text-path-0) "hello world"))
|
|
|
|
;;;;;;;;;;; Text copy
|
|
;; Before the switch:
|
|
;; * font size 14
|
|
;; * text "text overriden"
|
|
(t/is (= (get-in copy-text-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-text-t text-path-0) "text overriden"))
|
|
|
|
;; After the switch:
|
|
;; * font size 50 (value of c02, because there was no override)
|
|
;; * text "text overriden" (the override is preserved)
|
|
(t/is (= (get-in copy-text-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-text-t' text-path-0) "text overriden"))
|
|
|
|
;;;;;;;;;;; Both copy
|
|
;; Before the switch:
|
|
;; * font size 25
|
|
;; * text "text overriden"
|
|
(t/is (= (get-in copy-both-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-both-t text-path-0) "text overriden"))
|
|
|
|
;; After the switch:
|
|
;; * font size 50 (value of c02: the override is not preserved)
|
|
;; * text "text overriden" (the override is preserved)
|
|
(t/is (= (get-in copy-both-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-both-t' text-path-0) "text overriden"))))
|
|
|
|
;; ============================================================
|
|
;; TEXT OVERRIDES (different text)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-different-text-text-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Second comp has different text
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "bye")
|
|
(thc/instantiate-component :c01
|
|
:copy-clean
|
|
:children-labels [:copy-clean-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-font-size
|
|
:children-labels [:copy-font-size-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-text
|
|
:children-labels [:copy-text-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-both
|
|
:children-labels [:copy-both-t]))
|
|
|
|
|
|
;; The copy clean has no overrides
|
|
|
|
|
|
copy-clean (ths/get-shape file :copy-clean)
|
|
copy-clean-t (ths/get-shape file :copy-clean-t)
|
|
|
|
;; Override font size on copy-font-size
|
|
file (update-attr file :copy-font-size-t font-size-path-0 "25")
|
|
copy-font-size (ths/get-shape file :copy-font-size)
|
|
copy-font-size-t (ths/get-shape file :copy-font-size-t)
|
|
|
|
;; Override text on copy-text
|
|
file (update-attr file :copy-text-t text-path-0 "text overriden")
|
|
copy-text (ths/get-shape file :copy-text)
|
|
copy-text-t (ths/get-shape file :copy-text-t)
|
|
|
|
;; Override both on copy-both
|
|
file (update-attr file :copy-both-t font-size-path-0 "25")
|
|
file (update-attr file :copy-both-t text-path-0 "text overriden")
|
|
copy-both (ths/get-shape file :copy-both)
|
|
copy-both-t (ths/get-shape file :copy-both-t)
|
|
|
|
|
|
;; ==== Action: Switch all the copies
|
|
|
|
|
|
file' (-> file
|
|
(tho/swap-component copy-clean :c02 {:new-shape-label :copy-clean-2 :keep-touched? true})
|
|
(tho/swap-component copy-font-size :c02 {:new-shape-label :copy-font-size-2 :keep-touched? true})
|
|
(tho/swap-component copy-text :c02 {:new-shape-label :copy-text-2 :keep-touched? true})
|
|
(tho/swap-component copy-both :c02 {:new-shape-label :copy-both-2 :keep-touched? true}))
|
|
page' (thf/current-page file')
|
|
copy-clean' (ths/get-shape file' :copy-clean-2)
|
|
copy-clean-t' (get-in page' [:objects (-> copy-clean' :shapes first)])
|
|
|
|
copy-font-size' (ths/get-shape file' :copy-font-size-2)
|
|
copy-font-size-t' (get-in page' [:objects (-> copy-font-size' :shapes first)])
|
|
|
|
copy-text' (ths/get-shape file' :copy-text-2)
|
|
copy-text-t' (get-in page' [:objects (-> copy-text' :shapes first)])
|
|
|
|
copy-both' (ths/get-shape file' :copy-both-2)
|
|
copy-both-t' (get-in page' [:objects (-> copy-both' :shapes first)])]
|
|
|
|
(thf/dump-file file' {:keys [:name #_:content]})
|
|
|
|
|
|
;;;;;;;;;;; Clean copy
|
|
;; Before the switch:
|
|
;; * font size 14
|
|
;; * text "hello world"
|
|
|
|
|
|
(t/is (= (get-in copy-clean-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-clean-t text-path-0) "hello world"))
|
|
|
|
;; After the switch:
|
|
;; * font size 25 (value of c02, because there was no override)
|
|
;; * text "bye" (value of c02, because there was no override)
|
|
(t/is (= (get-in copy-clean-t' font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-clean-t' text-path-0) "bye"))
|
|
|
|
|
|
;;;;;;;;;;; Font size copy
|
|
;; Before the switch:
|
|
;; * font size 25
|
|
;; * text "hello world"
|
|
|
|
|
|
(t/is (= (get-in copy-font-size-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-font-size-t text-path-0) "hello world"))
|
|
|
|
;; After the switch:
|
|
;; * font size 25 (the override is preserved)
|
|
;; * text "bye" (value of c02, because there was no override)
|
|
(t/is (= (get-in copy-font-size-t' font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-font-size-t' text-path-0) "bye"))
|
|
|
|
;;;;;;;;;;; Text copy
|
|
;; Before the switch:
|
|
;; * font size 14
|
|
;; * text "text overriden"
|
|
(t/is (= (get-in copy-text-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-text-t text-path-0) "text overriden"))
|
|
|
|
;; After the switch:
|
|
;; * font size 14 (value of c02, because there was no override)
|
|
;; * text "text overriden" (value of c02: the override is not preserved)
|
|
(t/is (= (get-in copy-text-t' font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-text-t' text-path-0) "bye"))
|
|
|
|
;;;;;;;;;;; Both copy
|
|
;; Before the switch:
|
|
;; * font size 25
|
|
;; * text "text overriden"
|
|
(t/is (= (get-in copy-both-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-both-t text-path-0) "text overriden"))
|
|
|
|
;; After the switch:
|
|
;; * font size 25 (the override is preserved)
|
|
;; * text "text overriden" (value of c02: the override is not preserved)
|
|
(t/is (= (get-in copy-both-t' font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-both-t' text-path-0) "bye"))))
|
|
|
|
;; ============================================================
|
|
;; TEXT OVERRIDES (different text AND property)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-different-text-and-prop-text-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; The second component has a different text and prop
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "bye")
|
|
(update-attr :t02 font-size-path-0 "50")
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy-clean
|
|
:children-labels [:copy-clean-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-font-size
|
|
:children-labels [:copy-font-size-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-text
|
|
:children-labels [:copy-text-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-both
|
|
:children-labels [:copy-both-t]))
|
|
|
|
|
|
;; The copy clean has no overrides
|
|
|
|
|
|
copy-clean (ths/get-shape file :copy-clean)
|
|
copy-clean-t (ths/get-shape file :copy-clean-t)
|
|
|
|
;; Override font size on copy-font-size
|
|
file (update-attr file :copy-font-size-t font-size-path-0 "25")
|
|
copy-font-size (ths/get-shape file :copy-font-size)
|
|
copy-font-size-t (ths/get-shape file :copy-font-size-t)
|
|
|
|
;; Override text on copy-text
|
|
file (update-attr file :copy-text-t text-path-0 "text overriden")
|
|
copy-text (ths/get-shape file :copy-text)
|
|
copy-text-t (ths/get-shape file :copy-text-t)
|
|
|
|
;; Override both on copy-both
|
|
file (update-attr file :copy-both-t font-size-path-0 "25")
|
|
file (update-attr file :copy-both-t text-path-0 "text overriden")
|
|
copy-both (ths/get-shape file :copy-both)
|
|
copy-both-t (ths/get-shape file :copy-both-t)
|
|
|
|
|
|
;; ==== Action: Switch all the copies
|
|
|
|
|
|
file' (-> file
|
|
(tho/swap-component copy-clean :c02 {:new-shape-label :copy-clean-2 :keep-touched? true})
|
|
(tho/swap-component copy-font-size :c02 {:new-shape-label :copy-font-size-2 :keep-touched? true})
|
|
(tho/swap-component copy-text :c02 {:new-shape-label :copy-text-2 :keep-touched? true})
|
|
(tho/swap-component copy-both :c02 {:new-shape-label :copy-both-2 :keep-touched? true}))
|
|
page' (thf/current-page file')
|
|
copy-clean' (ths/get-shape file' :copy-clean-2)
|
|
copy-clean-t' (get-in page' [:objects (-> copy-clean' :shapes first)])
|
|
|
|
copy-font-size' (ths/get-shape file' :copy-font-size-2)
|
|
copy-font-size-t' (get-in page' [:objects (-> copy-font-size' :shapes first)])
|
|
|
|
copy-text' (ths/get-shape file' :copy-text-2)
|
|
copy-text-t' (get-in page' [:objects (-> copy-text' :shapes first)])
|
|
|
|
copy-both' (ths/get-shape file' :copy-both-2)
|
|
copy-both-t' (get-in page' [:objects (-> copy-both' :shapes first)])]
|
|
|
|
(thf/dump-file file' {:keys [:name #_:content]})
|
|
|
|
|
|
;;;;;;;;;;; Clean copy
|
|
;; Before the switch:
|
|
;; * font size 14
|
|
;; * text "hello world"
|
|
|
|
|
|
(t/is (= (get-in copy-clean-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-clean-t text-path-0) "hello world"))
|
|
|
|
;; After the switch:
|
|
;; * font size 50 (value of c02, because there was no override)
|
|
;; * text "bye" (value of c02, because there was no override)
|
|
(t/is (= (get-in copy-clean-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-clean-t' text-path-0) "bye"))
|
|
|
|
|
|
;;;;;;;;;;; Font size copy
|
|
;; Before the switch:
|
|
;; * font size 25
|
|
;; * text "hello world"
|
|
|
|
|
|
(t/is (= (get-in copy-font-size-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-font-size-t text-path-0) "hello world"))
|
|
|
|
;; After the switch:
|
|
;; * font size 50 (value of c02: the override is not preserved)
|
|
;; * text "bye" (value of c02, because there was no override)
|
|
(t/is (= (get-in copy-font-size-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-font-size-t' text-path-0) "bye"))
|
|
|
|
;;;;;;;;;;; Text copy
|
|
;; Before the switch:
|
|
;; * font size 14
|
|
;; * text "text overriden"
|
|
(t/is (= (get-in copy-text-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-text-t text-path-0) "text overriden"))
|
|
|
|
;; After the switch:
|
|
;; * font size 50 (value of c02, because there was no override)
|
|
;; * text "bye" (value of c02: the override is not preserved)
|
|
(t/is (= (get-in copy-text-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-text-t' text-path-0) "bye"))
|
|
|
|
;;;;;;;;;;; Both copy
|
|
;; Before the switch:
|
|
;; * font size 25
|
|
;; * text "text overriden"
|
|
(t/is (= (get-in copy-both-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-both-t text-path-0) "text overriden"))
|
|
|
|
;; After the switch:
|
|
;; * font size 50 (value of c02: the override is not preserved)
|
|
;; * text "bye" (value of c02: the override is not preserved)
|
|
(t/is (= (get-in copy-both-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-both-t' text-path-0) "bye"))))
|
|
|
|
;; ============================================================
|
|
;; TEXT STRUCTURE OVERRIDES (identical variants)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-identical-structure-text-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Both components are identical: have the same text and props
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "hello world")
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-clean
|
|
:children-labels [:copy-structure-clean-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-unif
|
|
:children-labels [:copy-structure-unif-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-mixed
|
|
:children-labels [:copy-structure-mixed-t]))
|
|
|
|
|
|
|
|
;; Duplicate a text line in copy-structure-clean
|
|
|
|
|
|
file (change-structure file :copy-structure-clean-t)
|
|
copy-structure-clean (ths/get-shape file :copy-structure-clean)
|
|
copy-structure-clean-t (ths/get-shape file :copy-structure-clean-t)
|
|
|
|
;; Duplicate a text line in copy-structure-clean, updating
|
|
;; both lines with the same attrs
|
|
file (-> (update-attr file :copy-structure-unif-t font-size-path-0 "25")
|
|
(change-structure :copy-structure-unif-t))
|
|
copy-structure-unif (ths/get-shape file :copy-structure-unif)
|
|
copy-structure-unif-t (ths/get-shape file :copy-structure-unif-t)
|
|
|
|
;; Duplicate a text line in copy-structure-clean, updating
|
|
;; each line with a different attr
|
|
file (-> (change-structure file :copy-structure-mixed-t)
|
|
(update-attr :copy-structure-mixed-t font-size-path-0 "35")
|
|
(update-attr :copy-structure-mixed-t font-size-path-1 "40"))
|
|
copy-structure-mixed (ths/get-shape file :copy-structure-mixed)
|
|
copy-structure-mixed-t (ths/get-shape file :copy-structure-mixed-t)
|
|
|
|
|
|
;; ==== Action: Switch all the copies
|
|
|
|
|
|
file' (-> file
|
|
(tho/swap-component copy-structure-clean :c02 {:new-shape-label :copy-structure-clean-2 :keep-touched? true})
|
|
(tho/swap-component copy-structure-unif :c02 {:new-shape-label :copy-structure-unif-2 :keep-touched? true})
|
|
(tho/swap-component copy-structure-mixed :c02 {:new-shape-label :copy-structure-mixed-2 :keep-touched? true}))
|
|
page' (thf/current-page file')
|
|
copy-structure-clean' (ths/get-shape file' :copy-structure-clean-2)
|
|
copy-structure-clean-t' (get-in page' [:objects (-> copy-structure-clean' :shapes first)])
|
|
|
|
copy-structure-unif' (ths/get-shape file' :copy-structure-unif-2)
|
|
copy-structure-unif-t' (get-in page' [:objects (-> copy-structure-unif' :shapes first)])
|
|
|
|
copy-structure-mixed' (ths/get-shape file' :copy-structure-mixed-2)
|
|
copy-structure-mixed-t' (get-in page' [:objects (-> copy-structure-mixed' :shapes first)])]
|
|
|
|
(thf/dump-file file' {:keys [:name #_:content]})
|
|
|
|
;;;;;;;;;;; Copy structure clean
|
|
;; Before the switch, first line:
|
|
;; * font size 14
|
|
;; * text "new line 1"
|
|
;; Second line:
|
|
;; * font size 14
|
|
;; * text "new line 2"
|
|
(t/is (= (get-in copy-structure-clean-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-clean-t font-size-path-1) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 14 (value of c02, because there was no override)
|
|
;; * text "new line 1" (the override is preserved)
|
|
;; Second line:
|
|
;; * font size 14 (value of c02, because there was no override)
|
|
;; * text "new line 2" (the override is preserved)
|
|
(t/is (= (get-in copy-structure-clean-t' font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t' text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-clean-t' font-size-path-1) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t' text-path-1) "new line 2"))
|
|
|
|
;;;;;;;;;;; Copy structure unif
|
|
;; Before the switch, first line:
|
|
;; * font size 25
|
|
;; * text "new line 1"
|
|
;; Second line:
|
|
;; * font size 25
|
|
;; * text "new line 2"
|
|
(t/is (= (get-in copy-structure-unif-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-unif-t font-size-path-1) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 25 (the override is preserved)
|
|
;; * text "new line 1" (the override is preserved)
|
|
;; Second line:
|
|
;; * font size 25 (the override is preserved)
|
|
;; * text "new line 2" (the override is preserved)
|
|
(t/is (= (get-in copy-structure-unif-t' font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t' text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-unif-t' font-size-path-1) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t' text-path-1) "new line 2"))
|
|
|
|
;;;;;;;;;;; Copy structure mixed
|
|
;; Before the switch, first line:
|
|
;; * font size 35
|
|
;; * text "new line 1"
|
|
;; Before the switch, second line:
|
|
;; * font size 40
|
|
;; * text "new line 2"
|
|
(t/is (= (get-in copy-structure-mixed-t font-size-path-0) "35"))
|
|
(t/is (= (get-in copy-structure-mixed-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-mixed-t font-size-path-1) "40"))
|
|
(t/is (= (get-in copy-structure-mixed-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 35 (the override is preserved)
|
|
;; * text "new line 1" (the override is preserved)
|
|
;; Second line:
|
|
;; * font size 40 (the override is preserved)
|
|
;; * text "new line 2" (the override is preserved)
|
|
(t/is (= (get-in copy-structure-mixed-t' font-size-path-0) "35"))
|
|
(t/is (= (get-in copy-structure-mixed-t' text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-mixed-t' font-size-path-1) "40"))
|
|
(t/is (= (get-in copy-structure-mixed-t' text-path-1) "new line 2"))))
|
|
|
|
;; ============================================================
|
|
;; TEXT STRUCTURE OVERRIDES (different property)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-different-prop-structure-text-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; The second component has a different prop
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "hello world")
|
|
(update-attr :t02 font-size-path-0 "50")
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-clean
|
|
:children-labels [:copy-structure-clean-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-unif
|
|
:children-labels [:copy-structure-unif-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-mixed
|
|
:children-labels [:copy-structure-mixed-t]))
|
|
|
|
|
|
|
|
;; Duplicate a text line in copy-structure-clean
|
|
|
|
|
|
file (change-structure file :copy-structure-clean-t)
|
|
copy-structure-clean (ths/get-shape file :copy-structure-clean)
|
|
copy-structure-clean-t (ths/get-shape file :copy-structure-clean-t)
|
|
|
|
;; Duplicate a text line in copy-structure-clean, updating
|
|
;; both lines with the same attrs
|
|
file (-> (update-attr file :copy-structure-unif-t font-size-path-0 "25")
|
|
(change-structure :copy-structure-unif-t))
|
|
copy-structure-unif (ths/get-shape file :copy-structure-unif)
|
|
copy-structure-unif-t (ths/get-shape file :copy-structure-unif-t)
|
|
|
|
;; Duplicate a text line in copy-structure-clean, updating
|
|
;; each line with a different attr
|
|
file (-> (change-structure file :copy-structure-mixed-t)
|
|
(update-attr :copy-structure-mixed-t font-size-path-0 "35")
|
|
(update-attr :copy-structure-mixed-t font-size-path-1 "40"))
|
|
copy-structure-mixed (ths/get-shape file :copy-structure-mixed)
|
|
copy-structure-mixed-t (ths/get-shape file :copy-structure-mixed-t)
|
|
|
|
|
|
;; ==== Action: Switch all the copies
|
|
|
|
|
|
file' (-> file
|
|
(tho/swap-component copy-structure-clean :c02 {:new-shape-label :copy-structure-clean-2 :keep-touched? true})
|
|
(tho/swap-component copy-structure-unif :c02 {:new-shape-label :copy-structure-unif-2 :keep-touched? true})
|
|
(tho/swap-component copy-structure-mixed :c02 {:new-shape-label :copy-structure-mixed-2 :keep-touched? true}))
|
|
page' (thf/current-page file')
|
|
copy-structure-clean' (ths/get-shape file' :copy-structure-clean-2)
|
|
copy-structure-clean-t' (get-in page' [:objects (-> copy-structure-clean' :shapes first)])
|
|
|
|
copy-structure-unif' (ths/get-shape file' :copy-structure-unif-2)
|
|
copy-structure-unif-t' (get-in page' [:objects (-> copy-structure-unif' :shapes first)])
|
|
|
|
copy-structure-mixed' (ths/get-shape file' :copy-structure-mixed-2)
|
|
copy-structure-mixed-t' (get-in page' [:objects (-> copy-structure-mixed' :shapes first)])]
|
|
|
|
(thf/dump-file file' {:keys [:name #_:content]})
|
|
|
|
;;;;;;;;;;; Copy structure clean
|
|
;; Before the switch, first line:
|
|
;; * font size 14
|
|
;; * text "new line 1"
|
|
;; Second line:
|
|
;; * font size 14
|
|
;; * text "new line 2"
|
|
(t/is (= (get-in copy-structure-clean-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-clean-t font-size-path-1) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 50 (value of c02, because there was no override)
|
|
;; * text "new line 1" (the override is preserved)
|
|
;; Second line:
|
|
;; * font size 50 (value of c02, because there was no override)
|
|
;; * text "new line 2" (the override is preserved)
|
|
(t/is (= (get-in copy-structure-clean-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-structure-clean-t' text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-clean-t' font-size-path-1) "50"))
|
|
(t/is (= (get-in copy-structure-clean-t' text-path-1) "new line 2"))
|
|
|
|
;;;;;;;;;;; Copy structure unif
|
|
;; Before the switch, first line:
|
|
;; * font size 25
|
|
;; * text "new line 1"
|
|
;; Second line:
|
|
;; * font size 25
|
|
;; * text "new line 2"
|
|
(t/is (= (get-in copy-structure-unif-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-unif-t font-size-path-1) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 50 (the override is not preserved)
|
|
;; * text "new line 1" (the override is preserved)
|
|
;; Second line:
|
|
;; * font size 50 (the override is not preserved)
|
|
;; * text "new line 2" (the override is preserved)
|
|
(t/is (= (get-in copy-structure-unif-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-structure-unif-t' text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-unif-t' font-size-path-1) "50"))
|
|
(t/is (= (get-in copy-structure-unif-t' text-path-1) "new line 2"))
|
|
|
|
;;;;;;;;;;; Copy structure mixed
|
|
;; Before the switch, first line:
|
|
;; * font size 35
|
|
;; * text "new line 1"
|
|
;; Before the switch, second line:
|
|
;; * font size 40
|
|
;; * text "new line 2"
|
|
(t/is (= (get-in copy-structure-mixed-t font-size-path-0) "35"))
|
|
(t/is (= (get-in copy-structure-mixed-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-mixed-t font-size-path-1) "40"))
|
|
(t/is (= (get-in copy-structure-mixed-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 50 (the override is not preserved)
|
|
;; * text "hello world" (the override is not preserved)
|
|
;; No second line
|
|
(t/is (= (get-in copy-structure-mixed-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-structure-mixed-t' text-path-0) "hello world"))
|
|
(t/is (nil? (get-in copy-structure-mixed-t' font-size-path-1)))))
|
|
|
|
;; ============================================================
|
|
;; TEXT STRUCTURE OVERRIDES (different text)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-different-text-structure-text-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Second comp has different text
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "bye")
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-clean
|
|
:children-labels [:copy-structure-clean-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-unif
|
|
:children-labels [:copy-structure-unif-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-mixed
|
|
:children-labels [:copy-structure-mixed-t]))
|
|
|
|
|
|
|
|
;; Duplicate a text line in copy-structure-clean
|
|
|
|
|
|
file (change-structure file :copy-structure-clean-t)
|
|
copy-structure-clean (ths/get-shape file :copy-structure-clean)
|
|
copy-structure-clean-t (ths/get-shape file :copy-structure-clean-t)
|
|
|
|
;; Duplicate a text line in copy-structure-clean, updating
|
|
;; both lines with the same attrs
|
|
file (-> (update-attr file :copy-structure-unif-t font-size-path-0 "25")
|
|
(change-structure :copy-structure-unif-t))
|
|
copy-structure-unif (ths/get-shape file :copy-structure-unif)
|
|
copy-structure-unif-t (ths/get-shape file :copy-structure-unif-t)
|
|
|
|
;; Duplicate a text line in copy-structure-clean, updating
|
|
;; each line with a different attr
|
|
file (-> (change-structure file :copy-structure-mixed-t)
|
|
(update-attr :copy-structure-mixed-t font-size-path-0 "35")
|
|
(update-attr :copy-structure-mixed-t font-size-path-1 "40"))
|
|
copy-structure-mixed (ths/get-shape file :copy-structure-mixed)
|
|
copy-structure-mixed-t (ths/get-shape file :copy-structure-mixed-t)
|
|
|
|
|
|
;; ==== Action: Switch all the copies
|
|
|
|
|
|
file' (-> file
|
|
(tho/swap-component copy-structure-clean :c02 {:new-shape-label :copy-structure-clean-2 :keep-touched? true})
|
|
(tho/swap-component copy-structure-unif :c02 {:new-shape-label :copy-structure-unif-2 :keep-touched? true})
|
|
(tho/swap-component copy-structure-mixed :c02 {:new-shape-label :copy-structure-mixed-2 :keep-touched? true}))
|
|
page' (thf/current-page file')
|
|
copy-structure-clean' (ths/get-shape file' :copy-structure-clean-2)
|
|
copy-structure-clean-t' (get-in page' [:objects (-> copy-structure-clean' :shapes first)])
|
|
|
|
copy-structure-unif' (ths/get-shape file' :copy-structure-unif-2)
|
|
copy-structure-unif-t' (get-in page' [:objects (-> copy-structure-unif' :shapes first)])
|
|
|
|
copy-structure-mixed' (ths/get-shape file' :copy-structure-mixed-2)
|
|
copy-structure-mixed-t' (get-in page' [:objects (-> copy-structure-mixed' :shapes first)])]
|
|
|
|
(thf/dump-file file' {:keys [:name #_:content]})
|
|
|
|
;;;;;;;;;;; Copy structure clean
|
|
;; Before the switch, first line:
|
|
;; * font size 14
|
|
;; * text "new line 1"
|
|
;; Second line:
|
|
;; * font size 14
|
|
;; * text "new line 2"
|
|
(t/is (= (get-in copy-structure-clean-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-clean-t font-size-path-1) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 14 (value of c02, because there was no override)
|
|
;; * text "bye" (the override is not preserved)
|
|
;; No second line
|
|
(t/is (= (get-in copy-structure-clean-t' font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t' text-path-0) "bye"))
|
|
(t/is (nil? (get-in copy-structure-clean-t' font-size-path-1)))
|
|
|
|
|
|
;;;;;;;;;;; Copy structure unif
|
|
;; Before the switch, first line:
|
|
;; * font size 25
|
|
;; * text "new line 1"
|
|
;; Second line:
|
|
;; * font size 25
|
|
;; * text "new line 2"
|
|
|
|
|
|
(t/is (= (get-in copy-structure-unif-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-unif-t font-size-path-1) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 25 (the override is preserved)
|
|
;; * text "bye" (the override is not preserved)
|
|
;; No second line
|
|
(t/is (= (get-in copy-structure-unif-t' font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t' text-path-0) "bye"))
|
|
(t/is (nil? (get-in copy-structure-unif-t' font-size-path-1)))
|
|
|
|
|
|
;;;;;;;;;;; Copy structure mixed
|
|
;; Before the switch, first line:
|
|
;; * font size 35
|
|
;; * text "new line 1"
|
|
;; Before the switch, second line:
|
|
;; * font size 40
|
|
;; * text "new line 2"
|
|
|
|
|
|
(t/is (= (get-in copy-structure-mixed-t font-size-path-0) "35"))
|
|
(t/is (= (get-in copy-structure-mixed-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-mixed-t font-size-path-1) "40"))
|
|
(t/is (= (get-in copy-structure-mixed-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 14 (the override is not preserved)
|
|
;; * text "bye" (the override is not preserved)
|
|
;; No second line
|
|
(t/is (= (get-in copy-structure-mixed-t' font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-structure-mixed-t' text-path-0) "bye"))
|
|
(t/is (nil? (get-in copy-structure-mixed-t' font-size-path-1)))))
|
|
|
|
;; ============================================================
|
|
;; TEXT STRUCTURE OVERRIDES (different text AND property)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-different-text-and-prop-structure-text-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; The second component has a different text and prop
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "bye")
|
|
(update-attr :t02 font-size-path-0 "50")
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-clean
|
|
:children-labels [:copy-structure-clean-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-unif
|
|
:children-labels [:copy-structure-unif-t])
|
|
(thc/instantiate-component :c01
|
|
:copy-structure-mixed
|
|
:children-labels [:copy-structure-mixed-t]))
|
|
|
|
|
|
|
|
;; Duplicate a text line in copy-structure-clean
|
|
|
|
|
|
file (change-structure file :copy-structure-clean-t)
|
|
copy-structure-clean (ths/get-shape file :copy-structure-clean)
|
|
copy-structure-clean-t (ths/get-shape file :copy-structure-clean-t)
|
|
|
|
;; Duplicate a text line in copy-structure-clean, updating
|
|
;; both lines with the same attrs
|
|
file (-> (update-attr file :copy-structure-unif-t font-size-path-0 "25")
|
|
(change-structure :copy-structure-unif-t))
|
|
copy-structure-unif (ths/get-shape file :copy-structure-unif)
|
|
copy-structure-unif-t (ths/get-shape file :copy-structure-unif-t)
|
|
|
|
;; Duplicate a text line in copy-structure-clean, updating
|
|
;; each line with a different attr
|
|
file (-> (change-structure file :copy-structure-mixed-t)
|
|
(update-attr :copy-structure-mixed-t font-size-path-0 "35")
|
|
(update-attr :copy-structure-mixed-t font-size-path-1 "40"))
|
|
copy-structure-mixed (ths/get-shape file :copy-structure-mixed)
|
|
copy-structure-mixed-t (ths/get-shape file :copy-structure-mixed-t)
|
|
|
|
|
|
;; ==== Action: Switch all the copies
|
|
|
|
|
|
file' (-> file
|
|
(tho/swap-component copy-structure-clean :c02 {:new-shape-label :copy-structure-clean-2 :keep-touched? true})
|
|
(tho/swap-component copy-structure-unif :c02 {:new-shape-label :copy-structure-unif-2 :keep-touched? true})
|
|
(tho/swap-component copy-structure-mixed :c02 {:new-shape-label :copy-structure-mixed-2 :keep-touched? true}))
|
|
page' (thf/current-page file')
|
|
copy-structure-clean' (ths/get-shape file' :copy-structure-clean-2)
|
|
copy-structure-clean-t' (get-in page' [:objects (-> copy-structure-clean' :shapes first)])
|
|
|
|
copy-structure-unif' (ths/get-shape file' :copy-structure-unif-2)
|
|
copy-structure-unif-t' (get-in page' [:objects (-> copy-structure-unif' :shapes first)])
|
|
|
|
copy-structure-mixed' (ths/get-shape file' :copy-structure-mixed-2)
|
|
copy-structure-mixed-t' (get-in page' [:objects (-> copy-structure-mixed' :shapes first)])]
|
|
|
|
(thf/dump-file file' {:keys [:name #_:content]})
|
|
|
|
;;;;;;;;;;; Copy structure clean
|
|
;; Before the switch, first line:
|
|
;; * font size 14
|
|
;; * text "new line 1"
|
|
;; Second line:
|
|
;; * font size 14
|
|
;; * text "new line 2"
|
|
(t/is (= (get-in copy-structure-clean-t font-size-path-0) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-clean-t font-size-path-1) "14"))
|
|
(t/is (= (get-in copy-structure-clean-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 50 (value of c02, because there was no override)
|
|
;; * text "bye" (the override is not preserved)
|
|
;; No second line
|
|
(t/is (= (get-in copy-structure-clean-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-structure-clean-t' text-path-0) "bye"))
|
|
(t/is (nil? (get-in copy-structure-clean-t' font-size-path-1)))
|
|
|
|
|
|
;;;;;;;;;;; Copy structure unif
|
|
;; Before the switch, first line:
|
|
;; * font size 25
|
|
;; * text "new line 1"
|
|
;; Second line:
|
|
;; * font size 25
|
|
;; * text "new line 2"
|
|
|
|
|
|
(t/is (= (get-in copy-structure-unif-t font-size-path-0) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-unif-t font-size-path-1) "25"))
|
|
(t/is (= (get-in copy-structure-unif-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 50 (the override is not preserved)
|
|
;; * text "bye" (the override is not preserved)
|
|
;; No second line
|
|
(t/is (= (get-in copy-structure-unif-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-structure-unif-t' text-path-0) "bye"))
|
|
(t/is (nil? (get-in copy-structure-unif-t' font-size-path-1)))
|
|
|
|
|
|
;;;;;;;;;;; Copy structure mixed
|
|
;; Before the switch, first line:
|
|
;; * font size 35
|
|
;; * text "new line 1"
|
|
;; Before the switch, second line:
|
|
;; * font size 40
|
|
;; * text "new line 2"
|
|
|
|
|
|
(t/is (= (get-in copy-structure-mixed-t font-size-path-0) "35"))
|
|
(t/is (= (get-in copy-structure-mixed-t text-path-0) "new line 1"))
|
|
(t/is (= (get-in copy-structure-mixed-t font-size-path-1) "40"))
|
|
(t/is (= (get-in copy-structure-mixed-t text-path-1) "new line 2"))
|
|
|
|
;; After the switch, first line:
|
|
;; * font size 50 (the override is not preserved)
|
|
;; * text "bye" (the override is not preserved)
|
|
;; No second line
|
|
(t/is (= (get-in copy-structure-mixed-t' font-size-path-0) "50"))
|
|
(t/is (= (get-in copy-structure-mixed-t' text-path-0) "bye"))
|
|
(t/is (nil? (get-in copy-structure-mixed-t' font-size-path-1)))))
|
|
|
|
;; ============================================================
|
|
;; NESTED COMPONENTS (with same component in both variants)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-variant-for-other-with-same-nested-component
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(tho/add-simple-component :external01 :external01-root :external01-child)
|
|
(tho/add-simple-component :external02 :external02-root :external02-child)
|
|
(thv/add-variant-with-copy
|
|
:v01 :c01 :m01 :c02 :m02 :cp01 :cp02 :external01)
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-cp01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
copy-cp01 (ths/get-shape file :copy-cp01)
|
|
copy-cp01-rect-id (-> copy-cp01 :shapes first)
|
|
|
|
|
|
;; On :copy-cp01, change the width of the rect
|
|
|
|
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{copy-cp01-rect-id}
|
|
(fn [shape]
|
|
(assoc shape :width 25))
|
|
(:objects page)
|
|
{})
|
|
file (thf/apply-changes file changes)
|
|
copy-cp01-rect (ths/get-shape-by-id file copy-cp01-rect-id)
|
|
|
|
;; ==== Action
|
|
;; Switch :c01 for :c02
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
copy02 (ths/get-shape file' :copy02)
|
|
copy-cp02' (ths/get-shape-by-id file' (-> copy02 :shapes first))
|
|
copy-cp02-rect' (ths/get-shape-by-id file' (-> copy-cp02' :shapes first))]
|
|
|
|
;; The width of copy-cp01-rect was 25
|
|
(t/is (= (:width copy-cp01-rect) 25))
|
|
|
|
;; The width of copy-cp02-rect' is 25 (change is preserved)
|
|
(t/is (= (:width copy-cp02-rect') 25))))
|
|
|
|
;; ============================================================
|
|
;; SWAPPED COPIES (switching variants that contain swapped components)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-variant-that-has-swaped-copy
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(tho/add-simple-component :external01 :external01-root :external01-child)
|
|
(tho/add-simple-component :external02 :external02-root :external02-child)
|
|
(thv/add-variant-with-copy
|
|
:v01 :c01 :m01 :c02 :m02 :cp01 :cp02 :external01)
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-cp01]))
|
|
|
|
copy01 (ths/get-shape file :copy01)
|
|
copy-cp01 (ths/get-shape file :copy-cp01)
|
|
external02 (thc/get-component file :external02)
|
|
|
|
;; On :c01, swap the copy of :external01 for a copy of :external02
|
|
file (-> file
|
|
(tho/swap-component copy-cp01 :external02 {:new-shape-label :copy-cp02 :keep-touched? false}))
|
|
copy-cp02 (ths/get-shape file :copy-cp02)
|
|
|
|
;; ==== Action
|
|
;; Switch :c01 for :c02
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
copy02' (ths/get-shape file' :copy02)
|
|
copy-cp02' (ths/get-shape file' :copy-cp02)]
|
|
(thf/dump-file file')
|
|
;;copy-cp02 is a copy of external02
|
|
(t/is (= (:component-id copy-cp02) (:id external02)))
|
|
;;copy-01 had copy-cp02 as child
|
|
(t/is (= (-> copy01 :shapes first) (:id copy-cp02)))
|
|
|
|
;;copy-cp02' is a copy of external02
|
|
(t/is (= (:component-id copy-cp02') (:id external02)))
|
|
;;copy-02' had copy-cp02' as child
|
|
(t/is (= (-> copy02' :shapes first) (:id copy-cp02')))))
|
|
|
|
(t/deftest test-switch-variant-that-has-swaped-copy-with-changed-attr
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(tho/add-simple-component :external01 :external01-root :external01-child)
|
|
(tho/add-simple-component :external02 :external02-root :external02-child)
|
|
(thv/add-variant-with-copy
|
|
:v01 :c01 :m01 :c02 :m02 :cp01 :cp02 :external01)
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-cp01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
copy-cp01 (ths/get-shape file :copy-cp01)
|
|
external02 (thc/get-component file :external02)
|
|
|
|
;; On :c01, swap the copy of :external01 for a copy of :external02
|
|
file (-> file
|
|
(tho/swap-component copy-cp01 :external02 {:new-shape-label :copy-cp02 :keep-touched? false}))
|
|
copy-cp02 (ths/get-shape file :copy-cp02)
|
|
copy-cp02-rect-id (-> copy-cp02 :shapes first)
|
|
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{copy-cp02-rect-id}
|
|
(fn [shape]
|
|
(assoc shape :width 25))
|
|
(:objects page)
|
|
{})
|
|
file (thf/apply-changes file changes)
|
|
copy-cp02-rect (ths/get-shape-by-id file copy-cp02-rect-id)
|
|
|
|
;; ==== Action
|
|
;; Switch :c01 for :c02
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
copy02' (ths/get-shape file' :copy02)
|
|
copy-cp02' (ths/get-shape file' :copy-cp02)
|
|
copy-cp02-rect' (ths/get-shape-by-id file' (-> copy-cp02' :shapes first))]
|
|
(thf/dump-file file')
|
|
;;copy-cp02 is a copy of external02
|
|
(t/is (= (:component-id copy-cp02) (:id external02)))
|
|
;;copy-01 had copy-cp02 as child
|
|
(t/is (= (-> copy01 :shapes first) (:id copy-cp02)))
|
|
;; The width of copy-cp02-rect was 25
|
|
(t/is (= (:width copy-cp02-rect) 25))
|
|
|
|
;;copy-cp02' is a copy of external02
|
|
(t/is (= (:component-id copy-cp02') (:id external02)))
|
|
;;copy-02' had copy-cp02' as child
|
|
(t/is (= (-> copy02' :shapes first) (:id copy-cp02')))
|
|
;; The width of copy-cp02-rect' is 25 (change is preserved)
|
|
(t/is (= (:width copy-cp02-rect') 25))))
|
|
|
|
;; ============================================================
|
|
;; TOUCHED PARENT (switch without touched but with touched parent)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-variant-without-touched-but-touched-parent
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 5}
|
|
:child2-params {:width 5}})
|
|
(tho/add-simple-component :external01 :external01-root :external01-child)
|
|
|
|
(thc/instantiate-component :c01
|
|
:c01-in-root
|
|
:children-labels [:r01-in-c01-in-root]
|
|
:parent-label :external01-root))
|
|
|
|
;; Make a change on r01-in-c01-in-root so it is touched
|
|
page (thf/current-page file)
|
|
r01-in-c01-in-root (ths/get-shape file :r01-in-c01-in-root)
|
|
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id r01-in-c01-in-root)}
|
|
(fn [shape]
|
|
(assoc shape :width 25))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
|
|
|
|
;; Instantiate the component :external01
|
|
|
|
|
|
file (thc/instantiate-component file
|
|
:external01
|
|
:external-copy01
|
|
:children-labels [:external-copy01-rect :c01-in-copy])
|
|
page (thf/current-page file)
|
|
c01-in-copy (ths/get-shape file :c01-in-copy)
|
|
rect01 (get-in page [:objects (-> c01-in-copy :shapes first)])
|
|
|
|
|
|
;; ==== Action
|
|
|
|
|
|
file' (tho/swap-component file c01-in-copy :c02 {:new-shape-label :c02-in-copy :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
c02-in-copy' (ths/get-shape file' :c02-in-copy)
|
|
rect02' (get-in page' [:objects (-> c02-in-copy' :shapes first)])]
|
|
|
|
(thf/dump-file file :keys [:width :touched])
|
|
;; The rect had width 25 before the switch
|
|
(t/is (= (:width rect01) 25))
|
|
;; The rect still has width 25 after the switch
|
|
(t/is (= (:width rect02') 25))))
|
|
|
|
;; ============================================================
|
|
;; LAYOUT ITEM SIZING - HORIZONTAL (fix, auto, fill, none)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-layout-item-h-sizing-fix
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create a variant with a child that has layout-item-h-sizing :fix
|
|
;; When :fix is set, the width should NOT be preserved on switch
|
|
;; but should take the new component's width
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100
|
|
:height 50
|
|
:layout-item-h-sizing :fix}
|
|
:child2-params {:width 200
|
|
:height 50
|
|
:layout-item-h-sizing :fix}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change width of the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :width 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had width 150 before the switch (with override)
|
|
(t/is (= (:width rect01) 150))
|
|
;; With layout-item-h-sizing :fix, the width should be taken from the new component
|
|
;; (not preserving the override), so it should be 200
|
|
(t/is (= (:width rect02') 200))
|
|
;; Verify layout-item-h-sizing is still :fix after switch
|
|
(t/is (= (:layout-item-h-sizing rect02') :fix))))
|
|
|
|
(t/deftest test-switch-with-layout-item-h-sizing-auto
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create a variant with a child that has layout-item-h-sizing :auto
|
|
;; When :auto is set, the width override SHOULD be preserved on switch
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100
|
|
:height 50
|
|
:layout-item-h-sizing :auto}
|
|
:child2-params {:width 200
|
|
:height 50
|
|
:layout-item-h-sizing :auto}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change width of the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :width 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had width 150 before the switch (with override)
|
|
(t/is (= (:width rect01) 150))
|
|
;; With layout-item-h-sizing :auto, since the two variants have different widths (100 vs 200),
|
|
;; the override is not preserved and the new component's width (200) is used
|
|
(t/is (= (:width rect02') 200))
|
|
;; Verify layout-item-h-sizing is still :auto after switch
|
|
(t/is (= (:layout-item-h-sizing rect02') :auto))))
|
|
|
|
(t/deftest test-switch-with-layout-item-h-sizing-fill
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create a variant with a child that has layout-item-h-sizing :fill
|
|
;; When :fill is set, the width override SHOULD be preserved on switch
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100
|
|
:height 50
|
|
:layout-item-h-sizing :fill}
|
|
:child2-params {:width 200
|
|
:height 50
|
|
:layout-item-h-sizing :fill}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change width of the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :width 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had width 150 before the switch (with override)
|
|
(t/is (= (:width rect01) 150))
|
|
;; With layout-item-h-sizing :fill, since the two variants have different widths (100 vs 200),
|
|
;; the override is not preserved and the new component's width (200) is used
|
|
(t/is (= (:width rect02') 200))
|
|
;; Verify layout-item-h-sizing is still :fill after switch
|
|
(t/is (= (:layout-item-h-sizing rect02') :fill))))
|
|
|
|
(t/deftest test-switch-without-layout-item-h-sizing
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create a variant with a child without layout-item-h-sizing
|
|
;; When not set, the width override SHOULD be preserved on switch
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100
|
|
:height 50}
|
|
:child2-params {:width 200
|
|
:height 50}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change width of the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :width 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had width 150 before the switch (with override)
|
|
(t/is (= (:width rect01) 150))
|
|
;; Without layout-item-h-sizing, since the two variants have different widths (100 vs 200),
|
|
;; the override is not preserved and the new component's width (200) is used
|
|
(t/is (= (:width rect02') 200))
|
|
;; Verify layout-item-h-sizing is still nil after switch
|
|
(t/is (nil? (:layout-item-h-sizing rect02')))))
|
|
|
|
;; ============================================================
|
|
;; LAYOUT ITEM SIZING - VERTICAL (fix, auto, fill, none)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-layout-item-v-sizing-fix
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create a variant with a child that has layout-item-v-sizing :fix
|
|
;; When :fix is set, the height should NOT be preserved on switch
|
|
;; but should take the new component's height
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 50
|
|
:height 100
|
|
:layout-item-v-sizing :fix}
|
|
:child2-params {:width 50
|
|
:height 200
|
|
:layout-item-v-sizing :fix}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change height of the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :height 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had height 150 before the switch (with override)
|
|
(t/is (= (:height rect01) 150))
|
|
;; With layout-item-v-sizing :fix, the height should be taken from the new component
|
|
;; (not preserving the override), so it should be 200
|
|
(t/is (= (:height rect02') 200))
|
|
;; Verify layout-item-v-sizing is still :fix after switch
|
|
(t/is (= (:layout-item-v-sizing rect02') :fix))))
|
|
|
|
(t/deftest test-switch-with-layout-item-v-sizing-auto
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create a variant with a child that has layout-item-v-sizing :auto
|
|
;; When :auto is set, the height override SHOULD be preserved on switch
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 50
|
|
:height 100
|
|
:layout-item-v-sizing :auto}
|
|
:child2-params {:width 50
|
|
:height 200
|
|
:layout-item-v-sizing :auto}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change height of the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :height 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had height 150 before the switch (with override)
|
|
(t/is (= (:height rect01) 150))
|
|
;; With layout-item-v-sizing :auto, since the two variants have different heights (100 vs 200),
|
|
;; the override is not preserved and the new component's height (200) is used
|
|
(t/is (= (:height rect02') 200))
|
|
;; Verify layout-item-v-sizing is still :auto after switch
|
|
(t/is (= (:layout-item-v-sizing rect02') :auto))))
|
|
|
|
(t/deftest test-switch-with-layout-item-v-sizing-fill
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create a variant with a child that has layout-item-v-sizing :fill
|
|
;; When :fill is set, the height override SHOULD be preserved on switch
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 50
|
|
:height 100
|
|
:layout-item-v-sizing :fill}
|
|
:child2-params {:width 50
|
|
:height 200
|
|
:layout-item-v-sizing :fill}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change height of the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :height 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had height 150 before the switch (with override)
|
|
(t/is (= (:height rect01) 150))
|
|
;; With layout-item-v-sizing :fill, since the two variants have different heights (100 vs 200),
|
|
;; the override is not preserved and the new component's height (200) is used
|
|
(t/is (= (:height rect02') 200))
|
|
;; Verify layout-item-v-sizing is still :fill after switch
|
|
(t/is (= (:layout-item-v-sizing rect02') :fill))))
|
|
|
|
(t/deftest test-switch-without-layout-item-v-sizing
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create a variant with a child without layout-item-v-sizing
|
|
;; When not set, the height override SHOULD be preserved on switch
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 50
|
|
:height 100}
|
|
:child2-params {:width 50
|
|
:height 200}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change height of the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :height 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had height 150 before the switch (with override)
|
|
(t/is (= (:height rect01) 150))
|
|
;; Without layout-item-v-sizing, since the two variants have different heights (100 vs 200),
|
|
;; the override is not preserved and the new component's height (200) is used
|
|
(t/is (= (:height rect02') 200))
|
|
;; Verify layout-item-v-sizing is still nil after switch
|
|
(t/is (nil? (:layout-item-v-sizing rect02')))))
|
|
|
|
;; ============================================================
|
|
;; ROTATION OVERRIDES
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-rotation-override
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100
|
|
:height 100
|
|
:rotation 0}
|
|
:child2-params {:width 100
|
|
:height 100
|
|
:rotation 0}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Apply rotation to the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :rotation 45))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had rotation 45 before the switch (with override)
|
|
(t/is (= (:rotation rect01) 45))
|
|
;; The rotation override should be preserved after switch since both variants have the same rotation
|
|
(t/is (= (:rotation rect02') 45))
|
|
;; The transform matrix should also be preserved
|
|
(t/is (some? (:transform rect02')))))
|
|
|
|
(t/deftest test-switch-with-rotation-different-variants
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100
|
|
:height 100
|
|
:rotation 0}
|
|
:child2-params {:width 100
|
|
:height 100
|
|
:rotation 90}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Apply rotation to the child rect (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :rotation 45))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had rotation 45 before the switch (with override)
|
|
(t/is (= (:rotation rect01) 45))
|
|
;; The override should NOT be preserved since the two variants have different rotations (0 vs 90)
|
|
;; The new rotation should be 90 (from c02)
|
|
(t/is (= (:rotation rect02') 90))))
|
|
|
|
;; ============================================================
|
|
;; SPECIAL CASES (auto-text, geometry, touched attributes, position data)
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-auto-text-geometry-not-copied
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create variants with auto-text (grow-type :auto-width or :auto-height)
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello" "world"))
|
|
|
|
page (thf/current-page file)
|
|
;; Modify the first text shape to have grow-type :auto-width
|
|
t01 (ths/get-shape file :t01)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id t01)}
|
|
(fn [shape]
|
|
(assoc shape :grow-type :auto-width))
|
|
(:objects page)
|
|
{})
|
|
file (thf/apply-changes file changes)
|
|
|
|
;; Also modify t02
|
|
page (thf/current-page file)
|
|
t02 (ths/get-shape file :t02)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id t02)}
|
|
(fn [shape]
|
|
(assoc shape :grow-type :auto-width))
|
|
(:objects page)
|
|
{})
|
|
file (thf/apply-changes file changes)
|
|
|
|
;; Now create a copy and modify its width
|
|
file (thc/instantiate-component file :c01
|
|
:copy01
|
|
:children-labels [:copy-t01])
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
text01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change width of the text (creating an override)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id text01)}
|
|
(fn [shape]
|
|
(assoc shape :width 200))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
text01 (get-in page [:objects (:id text01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
text02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The text had width 200 before the switch (with override)
|
|
(t/is (= (:width text01) 200))
|
|
;; For auto-text shapes, geometry attributes like width should NOT be copied on switch
|
|
;; So the width should be from the new component (t02's width)
|
|
(t/is (not= (:width text02') 200))
|
|
;; Verify grow-type is preserved
|
|
(t/is (= (:grow-type text02') :auto-width))))
|
|
|
|
(t/deftest test-switch-different-shape-types-content-not-copied
|
|
(let [;; ==== Setup - Create a variant with a rect in first component
|
|
;; This test is simplified to just test attributes, not changing shape types
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100 :height 100 :type :rect}
|
|
:child2-params {:width 100 :height 100 :type :rect}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; ==== Action - Try to switch to a component with different shape type
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
child02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; Verify the shapes are still rects
|
|
(t/is (= (:type rect01) :rect))
|
|
(t/is (= (:type child02') :rect))
|
|
;; This test demonstrates that content with different types isn't copied
|
|
;; In practice this means proper attribute filtering
|
|
(t/is (= (:width child02') 100))))
|
|
|
|
(t/deftest test-switch-with-path-shape-geometry-override
|
|
(let [;; ==== Setup - Create variants with path shapes
|
|
;; Using rect shapes as path shapes are complex - the principle is the same
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100 :height 100 :type :rect}
|
|
:child2-params {:width 200 :height 200 :type :rect}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-path01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
path01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Resize the path (creating an override by changing selrect)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id path01)}
|
|
(fn [shape]
|
|
(assoc shape :width 150))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
path01 (get-in page [:objects (:id path01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
path02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had width 150 before the switch
|
|
(t/is (= (:width path01) 150))
|
|
;; For shapes with geometry changes, the transformed geometry is applied
|
|
;; Since variants have different widths (100 vs 200), override is discarded
|
|
(t/is (= (:width path02') 200))
|
|
;; Verify it's still a rect type
|
|
(t/is (= (:type path02') :rect))))
|
|
|
|
(t/deftest test-switch-preserves-touched-attributes-only
|
|
(let [;; ==== Setup - Test that only touched attributes are copied
|
|
;; Use opacity since it's a simpler attribute than fill-color
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100
|
|
:height 100
|
|
:opacity 1}
|
|
:child2-params {:width 200
|
|
:height 200
|
|
:opacity 1}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change the opacity (creating a touched attribute)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(assoc shape :opacity 0.5))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had opacity 0.5 before the switch (touched)
|
|
(t/is (= (:opacity rect01) 0.5))
|
|
;; The rect had width 100 before the switch (not touched)
|
|
(t/is (= (:width rect01) 100))
|
|
|
|
;; After switch:
|
|
;; - opacity override SHOULD be preserved because:
|
|
;; 1. It was touched
|
|
;; 2. Both variants have same opacity (1)
|
|
(t/is (= (:opacity rect02') 0.5))
|
|
;; - width should NOT be preserved (it wasn't touched, and variants have different widths)
|
|
(t/is (= (:width rect02') 200))
|
|
;; - height should match the new variant
|
|
(t/is (= (:height rect02') 200))))
|
|
|
|
(t/deftest test-switch-with-equal-values-not-copied
|
|
(let [;; ==== Setup - Test that when previous-shape and current-shape have equal values,
|
|
;; no copy operation occurs (optimization in update-attrs-on-switch)
|
|
;; Both variants start with opacity 0.5
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100
|
|
:height 100
|
|
:opacity 0.5}
|
|
:child2-params {:width 100
|
|
:height 100
|
|
:opacity 0.5}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had opacity 0.5 before the switch
|
|
(t/is (= (:opacity rect01) 0.5))
|
|
;; After switch, opacity should still be 0.5
|
|
;; This validates that the equality check works correctly
|
|
(t/is (= (:opacity rect02') 0.5))))
|
|
|
|
(t/deftest test-switch-with-position-data-reset
|
|
(let [;; ==== Setup - Test that position-data is reset when geometry-group is touched
|
|
file (-> (thf/sample-file :file1)
|
|
;; Create variants with text shapes
|
|
(thv/add-variant-with-text
|
|
:v01 :c01 :m01 :c02 :m02 :t01 :t02 "hello world" "hello world"))
|
|
|
|
page (thf/current-page file)
|
|
;; Modify the first text shape to have specific geometry
|
|
t01 (ths/get-shape file :t01)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id t01)}
|
|
(fn [shape]
|
|
(assoc shape :width 200))
|
|
(:objects page)
|
|
{})
|
|
file (thf/apply-changes file changes)
|
|
|
|
;; Create a copy and modify its geometry (touching geometry-group)
|
|
file (thc/instantiate-component file :c01
|
|
:copy01
|
|
:children-labels [:copy-t01])
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
text01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Change width of the text (touching geometry)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id text01)}
|
|
(fn [shape]
|
|
(assoc shape :width 300))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
text01 (get-in page [:objects (:id text01)])
|
|
old-position-data (:position-data text01)
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
text02' (get-in page' [:objects (-> copy02' :shapes first)])
|
|
new-position-data (:position-data text02')]
|
|
|
|
;; position-data should be reset (nil or different) when geometry group is touched
|
|
;; This allows the system to recalculate it based on the new geometry
|
|
;; Note: old-position-data may be nil initially, which is fine
|
|
;; After switch with geometry changes, if old data existed and was different,
|
|
;; or if it needs recalculation, the test validates the behavior
|
|
(t/is (or (nil? old-position-data)
|
|
(nil? new-position-data)
|
|
(not= old-position-data new-position-data)))))
|
|
|
|
;; ============================================================
|
|
;; SELRECT CONSISTENCY TESTS
|
|
;; These tests verify that after a variant switch, the composite
|
|
;; geometry attributes (:selrect, :points) stay consistent with
|
|
;; the scalar attributes (:width, :height) that are kept.
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-selrect-consistent-no-sizing-different-widths
|
|
;; When no :fix sizing and variants have different widths,
|
|
;; :width is correctly skipped (stays at new component width),
|
|
;; but :selrect was being copied from the old shape, leaving
|
|
;; selrect.width inconsistent with :width. This test verifies the fix.
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100 :height 50}
|
|
:child2-params {:width 200 :height 50}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Override width AND selrect consistently (simulating a real resize)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(let [new-width 150
|
|
sr (:selrect shape)
|
|
new-sr (-> sr
|
|
(assoc :width new-width)
|
|
(assoc :x2 (+ (:x1 sr) new-width)))]
|
|
(-> shape
|
|
(assoc :width new-width)
|
|
(assoc :selrect new-sr))))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had the width override before the switch
|
|
(t/is (= (:width rect01) 150))
|
|
(t/is (= (get-in rect01 [:selrect :width]) 150))
|
|
;; Since the variants have different widths (100 vs 200), the override is not preserved
|
|
(t/is (= (:width rect02') 200))
|
|
;; The selrect must be consistent with :width
|
|
(t/is (= (get-in rect02' [:selrect :width]) 200))))
|
|
|
|
(t/deftest test-switch-selrect-consistent-no-sizing-different-heights
|
|
;; Same as above but for height.
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 50 :height 100}
|
|
:child2-params {:width 50 :height 200}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Override height AND selrect consistently
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(let [new-height 150
|
|
sr (:selrect shape)
|
|
new-sr (-> sr
|
|
(assoc :height new-height)
|
|
(assoc :y2 (+ (:y1 sr) new-height)))]
|
|
(-> shape
|
|
(assoc :height new-height)
|
|
(assoc :selrect new-sr))))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had the height override before the switch
|
|
(t/is (= (:height rect01) 150))
|
|
(t/is (= (get-in rect01 [:selrect :height]) 150))
|
|
;; Since the variants have different heights (100 vs 200), the override is not preserved
|
|
(t/is (= (:height rect02') 200))
|
|
;; The selrect must be consistent with :height
|
|
(t/is (= (get-in rect02' [:selrect :height]) 200))))
|
|
|
|
(t/deftest test-switch-with-v-sizing-fix-selrect-consistent-different-widths
|
|
;; mixed-sizing scenario: v-sizing=:fix but variants differ in WIDTH.
|
|
;; switch-fixed-layout-geom-change-value is triggered (because v-sizing=:fix).
|
|
;; Without the fix, the function returned prev-width for the non-:fix dimension,
|
|
;; leaving selrect.width inconsistent with :width.
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100 :height 50 :layout-item-v-sizing :fix}
|
|
:child2-params {:width 200 :height 50 :layout-item-v-sizing :fix}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Override width AND selrect consistently
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(let [new-width 150
|
|
sr (:selrect shape)
|
|
new-sr (-> sr
|
|
(assoc :width new-width)
|
|
(assoc :x2 (+ (:x1 sr) new-width)))]
|
|
(-> shape
|
|
(assoc :width new-width)
|
|
(assoc :selrect new-sr))))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had the width override before the switch
|
|
(t/is (= (:width rect01) 150))
|
|
(t/is (= (get-in rect01 [:selrect :width]) 150))
|
|
;; Since the variants have different widths (100 vs 200), the override is not preserved
|
|
;; (v-sizing=:fix does not affect the horizontal dimension)
|
|
(t/is (= (:width rect02') 200))
|
|
;; The selrect must be consistent with :width
|
|
(t/is (= (get-in rect02' [:selrect :width]) 200))
|
|
;; v-sizing is preserved
|
|
(t/is (= (:layout-item-v-sizing rect02') :fix))))
|
|
|
|
(t/deftest test-switch-with-h-sizing-fix-selrect-consistent-different-heights
|
|
;; mixed-sizing scenario: h-sizing=:fix but variants differ in HEIGHT.
|
|
;; switch-fixed-layout-geom-change-value is triggered (because h-sizing=:fix).
|
|
;; Without the fix, the function returned prev-height for the non-:fix dimension,
|
|
;; leaving selrect.height inconsistent with :height.
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 50 :height 100 :layout-item-h-sizing :fix}
|
|
:child2-params {:width 50 :height 200 :layout-item-h-sizing :fix}})
|
|
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Override height AND selrect consistently
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(let [new-height 150
|
|
sr (:selrect shape)
|
|
new-sr (-> sr
|
|
(assoc :height new-height)
|
|
(assoc :y2 (+ (:y1 sr) new-height)))]
|
|
(-> shape
|
|
(assoc :height new-height)
|
|
(assoc :selrect new-sr))))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had the height override before the switch
|
|
(t/is (= (:height rect01) 150))
|
|
(t/is (= (get-in rect01 [:selrect :height]) 150))
|
|
;; Since the variants have different heights (100 vs 200), the override is not preserved
|
|
;; (h-sizing=:fix does not affect the vertical dimension)
|
|
(t/is (= (:height rect02') 200))
|
|
;; The selrect must be consistent with :height
|
|
(t/is (= (get-in rect02' [:selrect :height]) 200))
|
|
;; h-sizing is preserved
|
|
(t/is (= (:layout-item-h-sizing rect02') :fix))))
|
|
|
|
;; ============================================================
|
|
;; FIXED-SIZING: "SAME-SIZE → PRESERVE OVERRIDE" PATH TESTS
|
|
;; These tests exercise the branch inside switch-fixed-layout-geom-change-value
|
|
;; where variants share the same value in the non-:fix dimension:
|
|
;; (if (= origin-dim current-dim) prev-dim current-dim)
|
|
;; When origin-dim == current-dim the user's override for that dimension
|
|
;; must be preserved after the switch.
|
|
;; ============================================================
|
|
|
|
(t/deftest test-switch-with-h-sizing-fix-same-height-override-preserved
|
|
;; h-sizing=:fix, variants have SAME height (non-:fix dim, same-size).
|
|
;; switch-fixed-layout-geom-change-value must return prev-height for the
|
|
;; non-:fix dimension because origin-height == current-height.
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100 :height 50 :layout-item-h-sizing :fix}
|
|
:child2-params {:width 200 :height 50 :layout-item-h-sizing :fix}})
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Override height (the non-:fix dimension) and selrect consistently
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(let [new-height 75
|
|
sr (:selrect shape)
|
|
new-sr (-> sr
|
|
(assoc :height new-height)
|
|
(assoc :y2 (+ (:y1 sr) new-height)))]
|
|
(-> shape
|
|
(assoc :height new-height)
|
|
(assoc :selrect new-sr))))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had the height override 75 before the switch
|
|
(t/is (= (:height rect01) 75))
|
|
;; h-sizing=:fix means width always takes the new component's value
|
|
(t/is (= (:width rect02') 200))
|
|
;; Height (non-:fix dim) is preserved because both variants have same height (50)
|
|
(t/is (= (:height rect02') 75))
|
|
;; selrect must be consistent with the preserved height
|
|
(t/is (= (get-in rect02' [:selrect :height]) 75))
|
|
(t/is (= (get-in rect02' [:selrect :width]) 200))
|
|
;; h-sizing is preserved
|
|
(t/is (= (:layout-item-h-sizing rect02') :fix))))
|
|
|
|
(t/deftest test-switch-with-v-sizing-fix-same-width-override-preserved
|
|
;; v-sizing=:fix, variants have SAME width (non-:fix dim, same-size).
|
|
;; switch-fixed-layout-geom-change-value must return prev-width for the
|
|
;; non-:fix dimension because origin-width == current-width.
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100 :height 50 :layout-item-v-sizing :fix}
|
|
:child2-params {:width 100 :height 100 :layout-item-v-sizing :fix}})
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Override width (the non-:fix dimension) and selrect consistently
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(let [new-width 150
|
|
sr (:selrect shape)
|
|
new-sr (-> sr
|
|
(assoc :width new-width)
|
|
(assoc :x2 (+ (:x1 sr) new-width)))]
|
|
(-> shape
|
|
(assoc :width new-width)
|
|
(assoc :selrect new-sr))))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had the width override 150 before the switch
|
|
(t/is (= (:width rect01) 150))
|
|
;; Width (non-:fix dim) is preserved because both variants have same width (100)
|
|
(t/is (= (:width rect02') 150))
|
|
;; selrect must be consistent with the preserved width
|
|
(t/is (= (get-in rect02' [:selrect :width]) 150))
|
|
;; v-sizing=:fix means height always takes the new component's value
|
|
(t/is (= (:height rect02') 100))
|
|
(t/is (= (get-in rect02' [:selrect :height]) 100))
|
|
;; v-sizing is preserved
|
|
(t/is (= (:layout-item-v-sizing rect02') :fix))))
|
|
|
|
(t/deftest test-switch-with-both-sizing-fix-overrides-discarded
|
|
;; When both h-sizing=:fix and v-sizing=:fix, switch-fixed-layout-geom-change-value
|
|
;; always uses current-width and current-height (the new component's values).
|
|
;; Both width and height overrides are discarded because :fix always
|
|
;; defers to the new component's dimension regardless of same-size or not.
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100 :height 50
|
|
:layout-item-h-sizing :fix
|
|
:layout-item-v-sizing :fix}
|
|
:child2-params {:width 200 :height 100
|
|
:layout-item-h-sizing :fix
|
|
:layout-item-v-sizing :fix}})
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Override both width and height (and selrect) consistently
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(let [new-width 150
|
|
new-height 75
|
|
sr (:selrect shape)
|
|
new-sr (-> sr
|
|
(assoc :width new-width)
|
|
(assoc :height new-height)
|
|
(assoc :x2 (+ (:x1 sr) new-width))
|
|
(assoc :y2 (+ (:y1 sr) new-height)))]
|
|
(-> shape
|
|
(assoc :width new-width)
|
|
(assoc :height new-height)
|
|
(assoc :selrect new-sr))))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had both overrides before the switch
|
|
(t/is (= (:width rect01) 150))
|
|
(t/is (= (:height rect01) 75))
|
|
;; With both sizing :fix, both dimensions take the new component's values
|
|
(t/is (= (:width rect02') 200))
|
|
(t/is (= (:height rect02') 100))
|
|
;; selrect must be consistent
|
|
(t/is (= (get-in rect02' [:selrect :width]) 200))
|
|
(t/is (= (get-in rect02' [:selrect :height]) 100))
|
|
(t/is (= (:layout-item-h-sizing rect02') :fix))
|
|
(t/is (= (:layout-item-v-sizing rect02') :fix))))
|
|
|
|
(t/deftest test-switch-same-size-variants-geometry-override-preserved
|
|
;; When both variants have IDENTICAL dimensions (width=100, height=50),
|
|
;; the guard that skips :selrect/:points must NOT fire
|
|
;; (its condition `(or (not= origin.width current.width) ...)` is false).
|
|
;; A geometry override should therefore be carried through correctly.
|
|
(let [;; ==== Setup
|
|
file (-> (thf/sample-file :file1)
|
|
(thv/add-variant-with-child
|
|
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
|
{:child1-params {:width 100 :height 50}
|
|
:child2-params {:width 100 :height 50}}) ; same size!
|
|
(thc/instantiate-component :c01
|
|
:copy01
|
|
:children-labels [:copy-r01]))
|
|
|
|
page (thf/current-page file)
|
|
copy01 (ths/get-shape file :copy01)
|
|
rect01 (get-in page [:objects (-> copy01 :shapes first)])
|
|
|
|
;; Override width AND selrect consistently (simulating a real resize)
|
|
changes (cls/generate-update-shapes (pcb/empty-changes nil (:id page))
|
|
#{(:id rect01)}
|
|
(fn [shape]
|
|
(let [new-width 150
|
|
sr (:selrect shape)
|
|
new-sr (-> sr
|
|
(assoc :width new-width)
|
|
(assoc :x2 (+ (:x1 sr) new-width)))]
|
|
(-> shape
|
|
(assoc :width new-width)
|
|
(assoc :selrect new-sr))))
|
|
(:objects page)
|
|
{})
|
|
|
|
file (thf/apply-changes file changes)
|
|
page (thf/current-page file)
|
|
rect01 (get-in page [:objects (:id rect01)])
|
|
|
|
;; ==== Action
|
|
file' (tho/swap-component file copy01 :c02 {:new-shape-label :copy02 :keep-touched? true})
|
|
|
|
page' (thf/current-page file')
|
|
copy02' (ths/get-shape file' :copy02)
|
|
rect02' (get-in page' [:objects (-> copy02' :shapes first)])]
|
|
|
|
;; The rect had the width override 150 before the switch
|
|
(t/is (= (:width rect01) 150))
|
|
(t/is (= (get-in rect01 [:selrect :width]) 150))
|
|
;; Both variants are identical in size (100x50), so the override IS preserved
|
|
(t/is (= (:width rect02') 150))
|
|
;; The guard must not have suppressed :selrect — it should be consistent
|
|
(t/is (= (get-in rect02' [:selrect :width]) 150)))) |