mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 22:10:34 +00:00
♻️ Pin which fragment a one-page save loads and keeps
save-loads-only-edited-page counted fragment loads only. Assert as well that the one load is the edited page's fragment, that the untouched pages keep their fragment ids, that the rewritten page is stored as an objects map, and that the file reloads equal to the edit applied to the file before the save. Under the old enable-objects-map, which wrapped every page, the test fails with three loads instead of one. Replaying 1,000 recorded saves of a 49-page file on a pointer-map copy found no other load the save path adds beyond the edited page and the components map. AI-assisted-by: claude-opus-5-5 Signed-off-by: Álvaro Tejero Cantero <alvorithm@teje.ro>
This commit is contained in:
parent
5255fa1d60
commit
87c1b640fa
@ -758,7 +758,9 @@
|
||||
;; With objects-map enabled, encoding a save must not load the
|
||||
;; fragments of pages the change does not touch: each fragment was
|
||||
;; already wrapped when it was written. A three-page file with a
|
||||
;; one-page edit loads exactly one fragment (the edited page).
|
||||
;; one-page edit loads exactly one fragment (the edited page), keeps
|
||||
;; the fragments of the other pages, and reloads equal to the edit
|
||||
;; applied to the file before the save.
|
||||
(let [profile (th/create-profile* 1)
|
||||
file (th/create-file* 1 {:profile-id (:id profile)
|
||||
:project-id (:default-project-id profile)
|
||||
@ -767,7 +769,10 @@
|
||||
f0 (bfc/get-file th/*system* file-id)
|
||||
page-1 (first (:pages (:data f0)))
|
||||
page-2 (uuid/random)
|
||||
page-3 (uuid/random)]
|
||||
page-3 (uuid/random)
|
||||
shape (uuid/random)
|
||||
realize (fn []
|
||||
(:data (bfc/get-file th/*system* file-id :realize? true)))]
|
||||
|
||||
(update-file! :profile-id (:id profile)
|
||||
:file-id file-id
|
||||
@ -776,22 +781,36 @@
|
||||
{:type :add-page :name "c" :id page-3}
|
||||
(first (add-rect-change page-2 (uuid/random)))])
|
||||
|
||||
(let [loads (atom 0)
|
||||
load fdata/load-pointer]
|
||||
(let [ids-before (page-pointer-ids file-id)
|
||||
data-before (realize)
|
||||
loaded (atom [])
|
||||
load fdata/load-pointer]
|
||||
(with-redefs [fdata/load-pointer
|
||||
(fn [cfg file-id id]
|
||||
(swap! loads inc)
|
||||
(swap! loaded conj id)
|
||||
(load cfg file-id id))]
|
||||
(update-file! :profile-id (:id profile)
|
||||
:file-id file-id
|
||||
:revn 1
|
||||
:changes (add-rect-change page-2 (uuid/random))))
|
||||
:changes (add-rect-change page-2 shape)))
|
||||
|
||||
(t/is (= 1 @loads))
|
||||
(t/is (= [(get ids-before page-2)] @loaded))
|
||||
|
||||
(let [ids (page-pointer-ids file-id)]
|
||||
(t/is (some? (get ids page-1)))
|
||||
(t/is (some? (get ids page-3)))))))
|
||||
(let [ids-after (page-pointer-ids file-id)]
|
||||
(t/is (= (get ids-before page-1) (get ids-after page-1)))
|
||||
(t/is (= (get ids-before page-3) (get ids-after page-3)))
|
||||
(t/is (not= (get ids-before page-2) (get ids-after page-2)))
|
||||
(t/is (omap/objects-map? (fragment-objects file-id (get ids-after page-2)))))
|
||||
|
||||
(let [data-after (realize)]
|
||||
(t/is (= (update data-before :pages-index dissoc page-2)
|
||||
(update data-after :pages-index dissoc page-2)))
|
||||
(t/is (= (-> (get-in data-before [:pages-index page-2 :objects])
|
||||
(keys) (set) (conj shape))
|
||||
(-> (get-in data-after [:pages-index page-2 :objects])
|
||||
(keys) (set))))
|
||||
(t/is (= (dissoc (get-in data-before [:pages-index page-2]) :objects)
|
||||
(dissoc (get-in data-after [:pages-index page-2]) :objects)))))))
|
||||
|
||||
(t/deftest restore-does-not-load-shared-pages
|
||||
;; Restoring a snapshot reuses the shared fragments; encoding the
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user