🔧 Refactor remove-unneeded-objects using TDD

This commit is contained in:
Andrés Moya
2026-03-26 15:13:43 +01:00
parent ff193ab4f0
commit fdcfae0bd1
4 changed files with 121 additions and 9 deletions

View File

@@ -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."

View File

@@ -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 _]

View File

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

View File

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