mirror of
https://github.com/penpot/penpot.git
synced 2026-03-29 15:52:17 +02:00
🔧 Refactor remove-unneeded-objects using TDD
This commit is contained in:
@@ -11,6 +11,24 @@
|
||||
|
||||
"Repair, migration or transformation utilities for components."
|
||||
|
||||
(defn remove-unneeded-objects-in-components
|
||||
"Some components have an :objects attribute, despite not being deleted. This removes it.
|
||||
It also adds an empty :objects if it's deleted and does not have it."
|
||||
[file]
|
||||
(ctf/update-file-data
|
||||
file
|
||||
(fn [file-data]
|
||||
(ctf/update-components
|
||||
file-data
|
||||
(fn [component]
|
||||
(if (:deleted component)
|
||||
(if (nil? (:objects component))
|
||||
(assoc component :objects {})
|
||||
component)
|
||||
(if (contains? component :objects)
|
||||
(dissoc component :objects)
|
||||
component)))))))
|
||||
|
||||
(defn fix-missing-swap-slots
|
||||
"Locate shapes that have been swapped (i.e. their shape-ref does not point to the near match) but
|
||||
they don't have a swap slot. In this case, add one pointing to the near match."
|
||||
|
||||
@@ -1830,14 +1830,9 @@
|
||||
|
||||
(defmethod migrate-data "0019-remove-unneeded-objects-from-components"
|
||||
[data _]
|
||||
;; Some components have an `:objects` attribute, despite not being
|
||||
;; deleted. This migration removes it.
|
||||
(letfn [(check-component [component]
|
||||
(if (and (not (:deleted component))
|
||||
(contains? component :objects))
|
||||
(dissoc component :objects)
|
||||
component))]
|
||||
(d/update-when data :components check-component)))
|
||||
(let [file {:id (:id data) :data data}]
|
||||
(-> (cfcp/remove-unneeded-objects-in-components file)
|
||||
:data)))
|
||||
|
||||
(defmethod migrate-data "0020-fix-missing-swap-slots"
|
||||
[data _]
|
||||
|
||||
@@ -204,7 +204,8 @@
|
||||
|
||||
(defn update-file-data
|
||||
[file f]
|
||||
(update file :data f))
|
||||
(when file
|
||||
(update file :data f)))
|
||||
|
||||
(defn containers-seq
|
||||
"Generate a sequence of all pages and all components, wrapped as containers"
|
||||
|
||||
@@ -14,8 +14,106 @@
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.test-helpers.shapes :as ths]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.file :as ctf]
|
||||
[clojure.test :as t]))
|
||||
|
||||
(t/deftest test-remove-unneeded-objects-in-components
|
||||
|
||||
(t/testing "nil file should return nil"
|
||||
(let [file nil
|
||||
file' (cfcp/remove-unneeded-objects-in-components file)]
|
||||
(t/is (nil? file'))))
|
||||
|
||||
(t/testing "empty file should not need any action"
|
||||
(let [file (thf/sample-file :file1)
|
||||
file' (cfcp/remove-unneeded-objects-in-components file)]
|
||||
(t/is (empty? (d/map-diff file file')))))
|
||||
|
||||
(t/testing "file without components should not need any action"
|
||||
(let [file
|
||||
(-> (thf/sample-file :file1)
|
||||
(tho/add-frame-with-child :frame1 :shape1))
|
||||
|
||||
file' (cfcp/remove-unneeded-objects-in-components file)]
|
||||
|
||||
(t/is (empty? (d/map-diff file file')))))
|
||||
|
||||
(t/testing "file with non deleted components should not need any action"
|
||||
(let [file
|
||||
(-> (thf/sample-file :file1)
|
||||
(tho/add-simple-component :component1 :frame1 :shape1))
|
||||
|
||||
file' (cfcp/remove-unneeded-objects-in-components file)]
|
||||
|
||||
(t/is (empty? (d/map-diff file file')))))
|
||||
|
||||
(t/testing "file with deleted components should not need any action"
|
||||
(let [file
|
||||
(-> (thf/sample-file :file1)
|
||||
(tho/add-simple-component :component1 :frame1 :shape1)
|
||||
(tho/delete-shape :frame1))
|
||||
|
||||
file' (cfcp/remove-unneeded-objects-in-components file)]
|
||||
|
||||
(t/is (empty? (d/map-diff file file')))))
|
||||
|
||||
(t/testing "file with non deleted components with :objects nil should remove it"
|
||||
(let [file
|
||||
(-> (thf/sample-file :file1)
|
||||
(tho/add-simple-component :component1 :frame1 :shape1)
|
||||
(thc/update-component :component1 {:objects nil}))
|
||||
|
||||
file' (cfcp/remove-unneeded-objects-in-components file)
|
||||
|
||||
diff (d/map-diff file file')
|
||||
|
||||
expected-diff {:data
|
||||
{:components
|
||||
{(thi/id :component1)
|
||||
{}}}}]
|
||||
|
||||
(t/is (= diff expected-diff))))
|
||||
|
||||
(t/testing "file with non deleted components with :objects should remove it"
|
||||
(let [file
|
||||
(-> (thf/sample-file :file1)
|
||||
(tho/add-simple-component :component1 :frame1 :shape1)
|
||||
(thc/update-component :component1 {:objects {:sample 777}}))
|
||||
|
||||
file' (cfcp/remove-unneeded-objects-in-components file)
|
||||
|
||||
diff (d/map-diff file file')
|
||||
|
||||
expected-diff {:data
|
||||
{:components
|
||||
{(thi/id :component1)
|
||||
{:objects
|
||||
[{:sample 777} nil]}}}}]
|
||||
|
||||
(t/is (= diff expected-diff))))
|
||||
|
||||
(t/testing "file with deleted components without :objects should add an empty one"
|
||||
(let [file
|
||||
(-> (thf/sample-file :file1)
|
||||
(tho/add-simple-component :component1 :frame1 :shape1)
|
||||
(tho/delete-shape :frame1)
|
||||
(ctf/update-file-data
|
||||
(fn [file-data]
|
||||
(ctkl/update-component file-data (thi/id :component1) #(dissoc % :objects)))))
|
||||
|
||||
file' (cfcp/remove-unneeded-objects-in-components file)
|
||||
|
||||
diff (d/map-diff file file')
|
||||
|
||||
expected-diff {:data
|
||||
{:components
|
||||
{(thi/id :component1)
|
||||
{:objects
|
||||
[nil {}]}}}}]
|
||||
|
||||
(t/is (= diff expected-diff)))))
|
||||
|
||||
(t/deftest test-fix-missing-swap-slots
|
||||
|
||||
(t/testing "nil file should return nil"
|
||||
|
||||
Reference in New Issue
Block a user