penpot/common/test/common_tests/logic/variants_test.cljc

689 lines
28 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 SUBSIDIARY SL
(ns common-tests.logic.variants-test
(:require
[app.common.files.changes-builder :as pcb]
[app.common.geom.point :as gpt]
[app.common.logic.libraries :as cll]
[app.common.logic.shapes :as cls]
[app.common.logic.variant-properties :as clvp]
[app.common.logic.variants :as clv]
[app.common.path-names :as cpn]
[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]
[app.common.types.component :as ctk]
[app.common.types.variant :as ctv]
[clojure.test :as t]
[cuerdas.core :as str]))
(t/use-fixtures :each thi/test-fixture)
(t/deftest test-update-property-name
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant-two-properties :v01 :c01 :m01 :c02 :m02))
v-id (-> (ths/get-shape file :v01) :id)
page (thf/current-page file)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-name v-id 0 "NewName1")
(clvp/generate-update-property-name v-id 1 "NewName2"))
file' (thf/apply-changes file changes)
;; ==== Get
comp01' (thc/get-component file' :c01)
comp02' (thc/get-component file' :c02)]
;; ==== Check
(t/is (= (-> comp01' :variant-properties first :name) "NewName1"))
(t/is (= (-> comp01' :variant-properties last :name) "NewName2"))
(t/is (= (-> comp02' :variant-properties first :name) "NewName1"))
(t/is (= (-> comp02' :variant-properties last :name) "NewName2"))))
(t/deftest test-add-new-property-without-values
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
v-id (-> (ths/get-shape file :v01) :id)
page (thf/current-page file)
comp01 (thc/get-component file :c01)
comp02 (thc/get-component file :c02)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-add-new-property v-id))
file' (thf/apply-changes file changes)
;; ==== Get
comp01' (thc/get-component file' :c01)
comp02' (thc/get-component file' :c02)]
;; ==== Check
(t/is (= (count (:variant-properties comp01)) 1))
(t/is (= (count (:variant-properties comp01')) 2))
(t/is (= (count (:variant-properties comp02)) 1))
(t/is (= (count (:variant-properties comp02')) 2))
(t/is (= (-> comp01' :variant-properties last :value) ""))))
(t/deftest test-add-new-property-with-values
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
v-id (-> (ths/get-shape file :v01) :id)
page (thf/current-page file)
comp01 (thc/get-component file :c01)
comp02 (thc/get-component file :c02)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-add-new-property v-id {:fill-values? true}))
file' (thf/apply-changes file changes)
;; ==== Get
comp01' (thc/get-component file' :c01)
comp02' (thc/get-component file' :c02)]
;; ==== Check
(t/is (= (count (:variant-properties comp01)) 1))
(t/is (= (count (:variant-properties comp01')) 2))
(t/is (= (count (:variant-properties comp02)) 1))
(t/is (= (count (:variant-properties comp02')) 2))
(t/is (= (-> comp01' :variant-properties last :value) "Value 1"))
(t/is (= (-> comp02' :variant-properties last :value) "Value 2"))))
(t/deftest test-add-new-property-with-the-same-value
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
v-id (-> (ths/get-shape file :v01) :id)
page (thf/current-page file)
comp01 (thc/get-component file :c01)
comp02 (thc/get-component file :c02)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-add-new-property v-id {:property-value "Value 1"}))
file' (thf/apply-changes file changes)
;; ==== Get
comp01' (thc/get-component file' :c01)
comp02' (thc/get-component file' :c02)]
;; ==== Check
(t/is (= (count (:variant-properties comp01)) 1))
(t/is (= (count (:variant-properties comp01')) 2))
(t/is (= (count (:variant-properties comp02)) 1))
(t/is (= (count (:variant-properties comp02')) 2))
(t/is (= (-> comp01' :variant-properties last :value) "Value 1"))
(t/is (= (-> comp02' :variant-properties last :value) "Value 1"))))
(t/deftest test-remove-property
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
v-id (-> (ths/get-shape file :v01) :id)
page (thf/current-page file)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-add-new-property v-id))
file (thf/apply-changes file changes)
page (thf/current-page file)
comp01 (thc/get-component file :c01)
comp02 (thc/get-component file :c02)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-remove-property v-id 0))
file' (thf/apply-changes file changes)
;; ==== Get
comp01' (thc/get-component file' :c01)
comp02' (thc/get-component file' :c02)]
;; ==== Check
(t/is (= (count (:variant-properties comp01)) 2))
(t/is (= (count (:variant-properties comp01')) 1))
(t/is (= (count (:variant-properties comp02)) 2))
(t/is (= (count (:variant-properties comp02')) 1))
(t/is (= (-> comp01' :variant-properties first :name) "Property 2"))))
(t/deftest test-update-property-value
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
page (thf/current-page file)
comp01 (thc/get-component file :c01)
comp02 (thc/get-component file :c02)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-value (:id comp01) 0 "NewValue1")
(clvp/generate-update-property-value (:id comp02) 0 "NewValue2"))
file' (thf/apply-changes file changes)
;; ==== Get
comp01' (thc/get-component file' :c01)
comp02' (thc/get-component file' :c02)]
;; ==== Check
(t/is (= (-> comp01' :variant-properties first :value) "NewValue1"))
(t/is (= (-> comp02' :variant-properties first :value) "NewValue2"))))
(t/deftest test-update-property-value-sanitizes
(let [file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
page (thf/current-page file)
comp01 (thc/get-component file :c01)
before (-> comp01 :variant-properties first :value)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-value (:id comp01) 0 "a=b,"))
file' (thf/apply-changes file changes)
comp01' (thc/get-component file' :c01)
main' (ths/get-shape file' :m01)
noop (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-value (:id comp01) 0 42))
file-noop (thf/apply-changes file noop)
comp-noop (thc/get-component file-noop :c01)
cleared (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-value (:id comp01) 0 "=,="))
file-cleared (thf/apply-changes file cleared)
comp-cleared (thc/get-component file-cleared :c01)
main-cleared (ths/get-shape file-cleared :m01)
nilled (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-value (:id comp01) 0 nil))
file-nilled (thf/apply-changes file nilled)
comp-nilled (thc/get-component file-nilled :c01)]
(t/is (= "ab" (-> comp01' :variant-properties first :value)))
(t/is (= "ab" (:variant-name main')))
(t/is (= before (-> comp-noop :variant-properties first :value)))
(t/is (= "" (-> comp-cleared :variant-properties first :value)))
(t/is (not (str/includes? (str (:variant-name main-cleared)) "=")))
(t/is (= "" (-> comp-nilled :variant-properties first :value)))))
(t/deftest test-update-property-name-sanitizes-and-noops
(let [file (-> (thf/sample-file :file1)
(thv/add-variant-two-properties :v01 :c01 :m01 :c02 :m02))
v-id (-> (ths/get-shape file :v01) :id)
page (thf/current-page file)
before (-> (thc/get-component file :c01) :variant-properties first :name)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-name v-id 0 "Size=Big"))
file' (thf/apply-changes file changes)
noop (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-name v-id 0 "=,="))
file-noop (thf/apply-changes file noop)]
(t/is (= "SizeBig" (-> (thc/get-component file' :c01) :variant-properties first :name)))
(t/is (= before (-> (thc/get-component file-noop :c01) :variant-properties first :name)))))
(t/deftest test-add-new-property-sanitizes
(let [file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
v-id (-> (ths/get-shape file :v01) :id)
page (thf/current-page file)
before-count (-> (thc/get-component file :c01) :variant-properties count)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-add-new-property v-id {:property-name "Size=Big"
:property-value "a=b,"}))
file' (thf/apply-changes file changes)
comp01' (thc/get-component file' :c01)
noop (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-add-new-property v-id {:property-name "=,="}))
file-noop (thf/apply-changes file noop)]
(t/is (= "SizeBig" (-> comp01' :variant-properties last :name)))
(t/is (= "ab" (-> comp01' :variant-properties last :value)))
(t/is (= before-count
(-> (thc/get-component file-noop :c01) :variant-properties count)))))
(t/deftest test-add-new-property-blank-value-does-not-trail-separator
(let [file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
v-id (-> (ths/get-shape file :v01) :id)
page (thf/current-page file)
main (ths/get-shape file :m01)
before (:variant-name main)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-add-new-property v-id {:property-name "Size"
:property-value "=,="}))
file' (thf/apply-changes file changes)
comp01' (thc/get-component file' :c01)
main' (ths/get-shape file' :m01)]
(t/is (= before (:variant-name main')))
(t/is (not (str/ends-with? (str (:variant-name main')) ", ")))
(t/is (= "" (-> comp01' :variant-properties last :value)))
(t/is (= "Size" (-> comp01' :variant-properties last :name)))))
(t/deftest test-update-property-value-from-formula-strips-equal-in-value
;; Option A / M2: formula parse may leave `=` inside a value; write path strips it.
(let [file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
page (thf/current-page file)
comp01 (thc/get-component file :c01)
parsed (ctv/properties-formula->map "border=yes color=yes")
value (-> parsed first :value)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-update-property-value (:id comp01) 0 value))
file' (thf/apply-changes file changes)
comp01' (thc/get-component file' :c01)
main' (ths/get-shape file' :m01)]
(t/is (= "yes color=yes" value))
(t/is (= "yes coloryes" (-> comp01' :variant-properties first :value)))
(t/is (= "yes coloryes" (:variant-name main')))
(t/is (not= "yes color=yes" (-> comp01' :variant-properties first :value)))))
(t/deftest test-make-shapes-variant-sanitizes-component-name-as-value
;; create-new-properties-from-variant adds (:name component) as a value when
;; moving a variant into a differently named container. Production always
;; pairs generate-make-shapes-variant with change-parent.
(let [file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02)
(thv/add-variant :v02 :c03 :m03 :c04 :m04)
(thc/update-component :c03 {:name "Big=red"}))
page (thf/current-page file)
container (ths/get-shape file :v01)
shape (ths/get-shape file :m03)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clvp/generate-make-shapes-variant [shape] container)
(pcb/change-parent (:id container) [shape] 0))
file' (thf/apply-changes file changes)
values (->> (thc/get-component file' :c03)
:variant-properties
(map :value)
set)]
(t/is (contains? values "Bigred"))))
(t/deftest test-duplicate-variant-container
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
data (:data file)
page (thf/current-page file)
objects (:objects page)
variant-container (ths/get-shape file :v01)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(cll/generate-duplicate-changes objects ;; objects
page ;; page
#{(:id variant-container)} ;; ids
(gpt/point 0 0) ;; delta
{(:id file) file} ;; libraries
(:data file) ;; library-data
(:id file))) ;; file-id
;; ==== Get
file' (thf/apply-changes file changes)
data' (:data file')
page' (thf/current-page file')
objects' (:objects page')]
;; ==== Check
(thf/validate-file! file')
(t/is (= (count (:components data)) 2))
(t/is (= (count (:components data')) 4))
(t/is (= (count objects) 4))
(t/is (= (count objects') 7))))
(t/deftest test-delete-variant
;; When a variant container becomes empty, it id automatically deleted
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant-two-properties :v01 :c01 :m01 :c02 :m02))
container (ths/get-shape file :v01)
m01-id (-> (ths/get-shape file :m01) :id)
m02-id (-> (ths/get-shape file :m02) :id)
page (thf/current-page file)
;; ==== Action
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(#(second (cls/generate-delete-shapes % #{m01-id m02-id} {}))))
file' (thf/apply-changes file changes)
;; ==== Get
container' (ths/get-shape file' :v01)]
;; ==== Check
;; The variant containew was not nil before the deletion
(t/is (not (nil? container)))
;; The variant containew is nil after the deletion
(t/is (nil? container'))))
(t/deftest test-instantiate-component-over-variant-container
;; When a component is instantiated at a position over a variant container,
;; the new copy must not become a child of the container (its children can
;; only be variant mains)
(let [;; ==== Setup
file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
container (ths/get-shape file :v01)
page (thf/current-page file)
;; ==== Action
;; Instantiate at a position inside the variant container, without
;; an explicit parent, so the destiny frame is chosen by position
[new-shape changes]
(cll/generate-instantiate-component (-> (pcb/empty-changes nil (:id page))
(pcb/with-objects (:objects page)))
(:objects page)
(:id file)
(thi/id :c01)
(gpt/point (:x container) (:y container))
page
{(:id file) file})
file' (thf/apply-changes file changes)
;; ==== Get
new-shape' (ths/get-shape-by-id file' (:id new-shape))]
;; ==== Check
(thf/validate-file! file')
(t/is (some? new-shape'))
(t/is (not= (:parent-id new-shape') (:id container)))))
(defn- two-property-file-with-other-page
[]
(-> (thf/sample-file :file1 :page-label :page1)
(thv/add-variant-two-properties :v01 :c01 :m01 :c02 :m02)
(thf/add-sample-page :page2)))
(t/deftest test-update-property-value-skips-when-main-not-in-objects
(let [file (two-property-file-with-other-page)
other (thf/current-page file)
comp01 (thc/get-component file :c01)
main (ths/get-shape file :m01 :page-label :page1)
before (:variant-properties comp01)
label (:variant-name main)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id other))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects other))
(clvp/generate-update-property-value (:id comp01) 1 "crítica"))
file' (thf/apply-changes file changes)
comp01' (thc/get-component file' :c01)
main' (ths/get-shape file' :m01 :page-label :page1)]
(thf/validate-file! file')
(t/is (empty? (:redo-changes changes)))
(t/is (= before (:variant-properties comp01')))
(t/is (= label (:variant-name main')))))
(t/deftest test-update-property-value-writes-main-page-and-chains
(let [file (two-property-file-with-other-page)
mains (thf/get-page file :page1)
comp01 (thc/get-component file :c01)
changes (-> (pcb/empty-changes nil)
(pcb/with-page-id (:id mains))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects mains))
(clvp/generate-update-property-value (:id comp01) 0 "active")
(clvp/generate-update-property-value (:id comp01) 1 "crítica"))
file' (thf/apply-changes file changes)
comp01' (thc/get-component file' :c01)
main' (ths/get-shape file' :m01 :page-label :page1)
props' (:variant-properties comp01')]
(thf/validate-file! file')
(t/is (= "active" (-> props' first :value)))
(t/is (= "crítica" (-> props' second :value)))
(t/is (= (ctv/properties-to-name props') (:variant-name main')))
(t/is (= "active, crítica" (:variant-name main')))))
(defn- post-artboard-alpha-file
"A normal frame holding one main named Alpha — before the container flag."
[]
(-> (thf/sample-file :file1)
(tho/add-frame :v01 {:name "Board"})
(tho/add-simple-component :c01 :m01 :r01
:root-params {:parent-label :v01 :name "Alpha"})))
(t/deftest test-define-variant-container-renames-component-in-same-vector
(let [file (post-artboard-alpha-file)
page (thf/current-page file)
variant-id (thi/id :v01)
main-id (thi/id :m01)
component-id (:id (thc/get-component file :c01))
changes (-> (pcb/empty-changes nil (:id page))
(pcb/with-objects (:objects page))
(pcb/with-library-data (:data file))
(clv/generate-define-variant-container
variant-id main-id component-id "Component"))
file' (thf/apply-changes file changes)
container' (ths/get-shape file' :v01)
main' (ths/get-shape file' :m01)
comp' (thc/get-component file' :c01)
restored (thf/apply-undo-changes file' changes)
container-rest (ths/get-shape restored :v01)
main-rest (ths/get-shape restored :m01)
comp-rest (thc/get-component restored :c01)]
(t/is (ctk/is-variant-container? container'))
(t/is (= "Component"
(:name container')
(:name main')
(cpn/merge-path-item (:path comp') (:name comp'))))
(t/is (= variant-id (:variant-id main') (:variant-id comp')))
(t/is (= (ctv/properties-to-name (:variant-properties comp'))
(:variant-name main')))
(t/is (not (ctk/is-variant-container? container-rest)))
(t/is (= "Alpha" (:name main-rest)))
(t/is (= "Alpha" (cpn/merge-path-item (:path comp-rest) (:name comp-rest))))
(t/is (nil? (:variant-id main-rest)))
(t/is (nil? (:variant-id comp-rest)))))
(defn- rename-variant-changes
[file name]
(let [page (thf/current-page file)]
(-> (pcb/empty-changes nil)
(pcb/with-page-id (:id page))
(pcb/with-library-data (:data file))
(pcb/with-objects (:objects page))
(clv/generate-rename-variant (thi/id :v01) name))))
(defn- redo-ids
[changes change-type]
(into #{}
(comp (filter #(= change-type (:type %)))
(map :id))
(:redo-changes changes)))
(t/deftest test-rename-variant-one-vector
(let [file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
board (ths/get-shape file :v01)
main1 (ths/get-shape file :m01)
main2 (ths/get-shape file :m02)
comp1 (thc/get-component file :c01)
comp2 (thc/get-component file :c02)
changes (rename-variant-changes file "Group / Button")
file' (thf/apply-changes file changes)
board' (ths/get-shape file' :v01)
main1' (ths/get-shape file' :m01)
main2' (ths/get-shape file' :m02)
comp1' (thc/get-component file' :c01)
comp2' (thc/get-component file' :c02)
restored (thf/apply-undo-changes file' changes)]
(t/is (= #{(thi/id :v01) (thi/id :m01) (thi/id :m02)}
(redo-ids changes :mod-obj)))
(t/is (= #{(thi/id :c01) (thi/id :c02)}
(redo-ids changes :mod-component)))
(t/is (= "Group / Button" (:name board') (:name main1') (:name main2')))
(t/is (= "Group" (:path comp1') (:path comp2')))
(t/is (= "Button" (:name comp1') (:name comp2')))
(t/is (= "Group / Button"
(cpn/merge-path-item (:path comp1') (:name comp1'))
(cpn/merge-path-item (:path comp2') (:name comp2'))))
(t/is (= (:id board) (:variant-id comp1') (:variant-id comp2')))
(t/is (= (:variant-name main1) (:variant-name main1')))
(t/is (= (:variant-name main2) (:variant-name main2')))
(t/is (= (:variant-properties comp1) (:variant-properties comp1')))
(t/is (= (:variant-properties comp2) (:variant-properties comp2')))
(t/is (= (:name board) (:name (ths/get-shape restored :v01))))
(t/is (= (:name main1) (:name (ths/get-shape restored :m01))))
(t/is (= (:name main2) (:name (ths/get-shape restored :m02))))
(t/is (= (:path comp1) (:path (thc/get-component restored :c01))))
(t/is (= (:name comp1) (:name (thc/get-component restored :c01))))
(t/is (= (:path comp2) (:path (thc/get-component restored :c02))))
(t/is (= (:name comp2) (:name (thc/get-component restored :c02))))))
(t/deftest test-rename-variant-slash-only-name
(let [file (-> (thf/sample-file :file1)
(thv/add-variant :v01 :c01 :m01 :c02 :m02))
changes (rename-variant-changes file "///")
file' (thf/apply-changes file changes)
comp1' (thc/get-component file' :c01)
comp2' (thc/get-component file' :c02)]
(t/is (= "(empty)"
(:name (ths/get-shape file' :v01))
(:name (ths/get-shape file' :m01))
(:name (ths/get-shape file' :m02))
(:name comp1')
(:name comp2')))
(t/is (= "" (:path comp1') (:path comp2')))
(t/is (= "(empty)"
(cpn/merge-path-item (:path comp1') (:name comp1'))
(cpn/merge-path-item (:path comp2') (:name comp2'))))
(t/is (some? (:variant-id comp1')))
(t/is (some? (:variant-id comp2')))))