mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
Enable Japanese layout per file through undoable changes, or for all files through a saved profile preference. Show the controls when the WASM renderer and either setting are active. Add writing mode, orientation, ruby, emphasis, warichu and line fitting controls with icons and English and Japanese translations. Cover the file change, profile preference and control behavior.
1188 lines
50 KiB
Clojure
1188 lines
50 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.files-changes-test
|
|
(:require
|
|
[app.common.features :as ffeat]
|
|
[app.common.files.changes :as ch]
|
|
[app.common.files.changes-builder :as pcb]
|
|
[app.common.geom.point :as gpt]
|
|
[app.common.geom.shapes :as gsh]
|
|
[app.common.schema :as sm]
|
|
[app.common.schema.generators :as sg]
|
|
[app.common.schema.test :as smt]
|
|
[app.common.time :as ct]
|
|
[app.common.types.file :as ctf]
|
|
[app.common.types.shape :as cts]
|
|
[app.common.types.tokens-lib :as ctob]
|
|
[app.common.types.tokens-status :as ctos]
|
|
[app.common.types.typography :as ctt]
|
|
[app.common.uuid :as uuid]
|
|
[clojure.datafy :refer [datafy]]
|
|
[clojure.test :as t]
|
|
[clojure.walk :as walk]
|
|
[common-tests.types.shape-decode-encode-test :refer [json-roundtrip]]))
|
|
|
|
(defn- make-file-data
|
|
[file-id page-id]
|
|
(binding [ffeat/*current* #{"components/v2"}]
|
|
(ctf/make-file-data file-id page-id)))
|
|
|
|
(defn- without-modified-at
|
|
[data]
|
|
(walk/prewalk
|
|
(fn [value]
|
|
;; Expose opaque token types so they compare by value and their nested
|
|
;; timestamps are excluded too.
|
|
(let [value (if (or (ctob/tokens-lib? value)
|
|
(ctob/token-set? value)
|
|
(ctos/tokens-status? value))
|
|
(datafy value)
|
|
value)]
|
|
(if (map? value)
|
|
(dissoc value :modified-at)
|
|
value)))
|
|
data))
|
|
|
|
(defn- assert-idempotent
|
|
[data changes]
|
|
;; Modification timestamps may differ; all other stored data must agree.
|
|
;; Exercise validation and the touched second pass at distinct times.
|
|
(let [once (with-redefs [ct/now (constantly (ct/inst 1000))]
|
|
(ch/process-changes data changes))
|
|
twice (with-redefs [ct/now (constantly (ct/inst 2000))]
|
|
(ch/process-changes once changes))]
|
|
(t/is (= (without-modified-at once)
|
|
(without-modified-at twice))
|
|
"Replaying changes must preserve file data except modification timestamps")
|
|
;; Ordered maps compare equal regardless of iteration order, but set order
|
|
;; determines which token wins when active sets contain the same name.
|
|
(when (:tokens-lib once)
|
|
(t/is (= (vec (ctob/get-set-names (:tokens-lib once)))
|
|
(vec (ctob/get-set-names (:tokens-lib twice))))
|
|
"Replaying changes must preserve token set order"))))
|
|
|
|
(t/deftest library-changes-are-idempotent
|
|
(let [file-id (uuid/custom 10 1)
|
|
page-id (uuid/custom 10 2)
|
|
shape-id (uuid/custom 10 3)
|
|
component-id (uuid/custom 10 4)
|
|
color {:id (uuid/custom 10 5) :name "Red" :color "#ff0000" :opacity 1}
|
|
typography (ctt/make-typography {:id (uuid/custom 10 6)})
|
|
component {:type :add-component
|
|
:id component-id
|
|
:name "Component"
|
|
:path ""
|
|
:main-instance-id shape-id
|
|
:main-instance-page page-id}
|
|
base (ch/process-changes
|
|
(make-file-data file-id page-id)
|
|
[{:type :add-obj
|
|
:id shape-id
|
|
:page-id page-id
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:id shape-id :type :frame :name "Main"
|
|
:frame-id uuid/zero :parent-id uuid/zero
|
|
:component-id component-id :component-file file-id
|
|
:main-instance true :component-root true})}])
|
|
populated (with-redefs [ct/now (constantly (ct/inst 0))]
|
|
(ch/process-changes base
|
|
[component
|
|
{:type :add-color :color color}
|
|
{:type :add-typography :typography typography}]))
|
|
deleted (ch/process-changes populated [{:type :del-component :id component-id}])]
|
|
(doseq [[label data change]
|
|
[["add color" base {:type :add-color :color color}]
|
|
["modify color" populated {:type :mod-color :color (assoc color :name "Renamed")}]
|
|
["delete color" populated {:type :del-color :id (:id color)}]
|
|
["add typography" base {:type :add-typography :typography typography}]
|
|
["modify typography" populated {:type :mod-typography
|
|
:typography (assoc typography :name "Renamed")}]
|
|
["delete typography" populated {:type :del-typography :id (:id typography)}]
|
|
["add component" base component]
|
|
["modify component" populated {:type :mod-component :id component-id :name "Renamed"}]
|
|
["delete component" populated {:type :del-component :id component-id}]
|
|
["delete component permanently" populated {:type :del-component :id component-id
|
|
:skip-undelete? true}]
|
|
["restore component" deleted {:type :restore-component :id component-id :page-id page-id}]
|
|
["purge component" populated {:type :purge-component :id component-id}]
|
|
["set main instance attribute" populated
|
|
{:type :mod-obj :id shape-id :page-id page-id
|
|
:operations [{:type :set :attr :name :val "Renamed"}]}]
|
|
["assign main instance attribute" populated
|
|
{:type :mod-obj :id shape-id :page-id page-id
|
|
:operations [{:type :assign :value {:name "Renamed"}}]}]]]
|
|
(t/testing label
|
|
(assert-idempotent data [change])))))
|
|
|
|
(t/deftest token-changes-are-idempotent
|
|
(let [set-id (uuid/custom 20 1)
|
|
other-id (uuid/custom 20 2)
|
|
token-id (uuid/custom 20 3)
|
|
theme-id (uuid/custom 20 4)
|
|
token-attrs {:id token-id :name "spacing" :type :spacing :value "8"
|
|
:modified-at (ct/inst 0)}
|
|
theme-attrs {:id theme-id :name "Light" :sets #{"base"}
|
|
:modified-at (ct/inst 0)}
|
|
lib (with-redefs [ct/now (constantly (ct/inst 0))]
|
|
(-> (ctob/make-tokens-lib)
|
|
(ctob/add-set (ctob/make-token-set :id set-id :name "base"))
|
|
(ctob/add-set (ctob/make-token-set :id other-id :name "group/other"))
|
|
(ctob/add-token set-id (ctob/make-token token-attrs))
|
|
(ctob/add-theme (ctob/make-token-theme theme-attrs))))
|
|
data (assoc (make-file-data (uuid/custom 20 5) (uuid/custom 20 6)) :tokens-lib lib)]
|
|
(doseq [[label change]
|
|
[["update token with serialized timestamp"
|
|
{:type :set-token :set-id set-id :token-id token-id
|
|
:attrs (assoc token-attrs :value "16")}]
|
|
["delete token"
|
|
{:type :set-token :set-id set-id :token-id token-id :attrs nil}]
|
|
["set token set without optional timestamp"
|
|
{:type :set-token-set :id set-id :attrs {:id set-id :name "base"}}]
|
|
["set token set with timestamp"
|
|
{:type :set-token-set :id set-id
|
|
:attrs {:id set-id :name "base" :modified-at (ct/inst 0)}}]
|
|
["delete token set"
|
|
{:type :set-token-set :id set-id :attrs nil}]
|
|
["update theme with serialized timestamp"
|
|
{:type :set-token-theme :id theme-id
|
|
:attrs (assoc theme-attrs :sets #{"group/other"})}]
|
|
["delete theme"
|
|
{:type :set-token-theme :id theme-id :attrs nil}]
|
|
["set tokens status"
|
|
{:type :set-tokens-status :theme-ids #{theme-id} :set-ids #{set-id}}]
|
|
["reorder token set"
|
|
{:type :move-token-set :from-path ["base"] :to-path ["base"]
|
|
:before-path nil :before-group false}]
|
|
["move token set to another group"
|
|
{:type :move-token-set :from-path ["base"] :to-path ["group" "base"]
|
|
:before-path nil :before-group false}]
|
|
["reorder token set group"
|
|
{:type :move-token-set-group :from-path ["group"] :to-path ["group"]
|
|
:before-path ["base"] :before-group false}]
|
|
["move token set group"
|
|
{:type :move-token-set-group :from-path ["group"] :to-path ["renamed"]
|
|
:before-path nil :before-group false}]
|
|
["rename token set group"
|
|
{:type :rename-token-set-group :set-group-path ["group"] :set-group-fname "renamed"}]
|
|
["rename token set group to its current name"
|
|
{:type :rename-token-set-group :set-group-path ["group"] :set-group-fname "group"}]]]
|
|
(t/testing label
|
|
(assert-idempotent data [change])))))
|
|
|
|
(t/deftest registering-nested-groups-is-idempotent
|
|
(let [file-id (uuid/custom 30 1)
|
|
page-id (uuid/custom 30 2)
|
|
outer-id (uuid/custom 30 3)
|
|
inner-id (uuid/custom 30 4)
|
|
rect-id (uuid/custom 30 5)
|
|
data (ch/process-changes
|
|
(make-file-data file-id page-id)
|
|
(mapv (fn [[id parent-id type]]
|
|
{:type :add-obj :id id :page-id page-id
|
|
:frame-id uuid/zero :parent-id parent-id
|
|
:obj (cts/setup-shape
|
|
{:id id :type type :name (name type)
|
|
:frame-id uuid/zero :parent-id parent-id
|
|
:x 0 :y 0 :width 10 :height 10})})
|
|
[[outer-id uuid/zero :group]
|
|
[inner-id outer-id :group]
|
|
[rect-id inner-id :rect]]))
|
|
moved (gsh/move (get-in data [:pages-index page-id :objects rect-id])
|
|
(gpt/point 100 0))
|
|
data (ch/process-changes
|
|
data
|
|
[{:type :mod-obj :id rect-id :page-id page-id
|
|
:operations (mapv (fn [[attr val]] {:type :set :attr attr :val val})
|
|
(select-keys moved [:x :y :selrect :points]))}])]
|
|
(t/testing "child before parent"
|
|
(assert-idempotent data [{:type :reg-objects :page-id page-id :shapes [inner-id outer-id]}]))
|
|
(t/testing "parent before child"
|
|
(let [changes [{:type :reg-objects :page-id page-id :shapes [outer-id inner-id]}]
|
|
result (ch/process-changes data changes)]
|
|
(t/is (= {:x 100.0 :y 0.0 :width 10.0 :height 10.0}
|
|
(select-keys (get-in result [:pages-index page-id :objects outer-id])
|
|
[:x :y :width :height]))
|
|
"The first application must update the outer group's bounds")
|
|
(assert-idempotent data changes)))))
|
|
|
|
(t/deftest registering-sibling-groups-is-idempotent
|
|
(let [page-id (uuid/custom 31 1)
|
|
outer-id (uuid/custom 31 2)
|
|
group-a (uuid/custom 31 3)
|
|
group-b (uuid/custom 31 4)
|
|
rect-a (uuid/custom 31 5)
|
|
rect-b (uuid/custom 31 6)
|
|
data (ch/process-changes
|
|
(make-file-data (uuid/custom 31 7) page-id)
|
|
(mapv (fn [[id parent-id type]]
|
|
{:type :add-obj :id id :page-id page-id
|
|
:frame-id uuid/zero :parent-id parent-id
|
|
:obj (cts/setup-shape
|
|
{:id id :type type :name (name type)
|
|
:frame-id uuid/zero :parent-id parent-id
|
|
:x 0 :y 0 :width 10 :height 10})})
|
|
[[outer-id uuid/zero :group]
|
|
[group-a outer-id :group]
|
|
[group-b outer-id :group]
|
|
[rect-a group-a :rect]
|
|
[rect-b group-b :rect]]))
|
|
data (ch/process-changes
|
|
data
|
|
(mapv (fn [[id dx]]
|
|
(let [shape (get-in data [:pages-index page-id :objects id])
|
|
moved (gsh/move shape (gpt/point dx 0))]
|
|
{:type :mod-obj :id id :page-id page-id
|
|
:operations (mapv (fn [[attr val]] {:type :set :attr attr :val val})
|
|
(select-keys moved [:x :y :selrect :points]))}))
|
|
[[rect-a 100] [rect-b 200]]))]
|
|
(doseq [shapes [[group-a group-b] [group-b group-a]
|
|
[outer-id group-a group-b] [group-a outer-id group-b]]]
|
|
(t/testing (str "Group order " shapes)
|
|
(let [changes [{:type :reg-objects :page-id page-id :shapes shapes}]
|
|
result (ch/process-changes data changes)]
|
|
(t/is (= {:x 100.0 :y 0.0 :width 110.0 :height 10.0}
|
|
(select-keys (get-in result [:pages-index page-id :objects outer-id])
|
|
[:x :y :width :height]))
|
|
"The parent must use the updated bounds of both children")
|
|
(assert-idempotent data changes))))))
|
|
|
|
(t/deftest set-japanese-layout-file-option
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)
|
|
enabled (ch/process-changes data [{:type :set-japanese-layout
|
|
:enabled true}])
|
|
disabled (ch/process-changes enabled [{:type :set-japanese-layout
|
|
:enabled false}])
|
|
changes (-> (pcb/empty-changes)
|
|
(pcb/with-file-data data)
|
|
(pcb/set-japanese-layout true))]
|
|
(t/is (false? (ctf/japanese-layout-enabled? data)))
|
|
(t/is (true? (ctf/japanese-layout-enabled? enabled)))
|
|
(t/is (false? (ctf/japanese-layout-enabled? disabled)))
|
|
(t/is (not (contains? (:options disabled) :japanese-layout)))
|
|
(t/is (= [{:type :set-japanese-layout :enabled true}]
|
|
(:redo-changes changes)))
|
|
(t/is (= '({:type :set-japanese-layout :enabled false})
|
|
(:undo-changes changes)))))
|
|
|
|
(t/deftest add-obj
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)
|
|
id-a (uuid/custom 2 1)
|
|
id-b (uuid/custom 2 2)
|
|
id-c (uuid/custom 2 3)]
|
|
|
|
(t/testing "Adds single object"
|
|
(let [chg {:type :add-obj
|
|
:page-id page-id
|
|
:id id-a
|
|
:parent-id uuid/zero
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:frame-id uuid/zero
|
|
:parent-id uuid/zero
|
|
:id id-a
|
|
:type :rect
|
|
:name "rect"})}
|
|
res (ch/process-changes data [chg])]
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= 2 (count objects)))
|
|
(t/is (= (:obj chg) (get objects id-a)))
|
|
|
|
(t/is (= [id-a] (get-in objects [uuid/zero :shapes]))))))
|
|
|
|
|
|
(t/testing "Adds several objects with different indexes"
|
|
(let [chg (fn [id index]
|
|
{:type :add-obj
|
|
:page-id page-id
|
|
:id id
|
|
:frame-id uuid/zero
|
|
:index index
|
|
:obj (cts/setup-shape
|
|
{:id id
|
|
:frame-id uuid/zero
|
|
:type :rect
|
|
:name (str id)})})
|
|
res (ch/process-changes data [(chg id-a 0)
|
|
(chg id-b 0)
|
|
(chg id-c 1)])]
|
|
|
|
;; (clojure.pprint/pprint data)
|
|
;; (clojure.pprint/pprint res)
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= 4 (count objects)))
|
|
(t/is (not (nil? (get objects id-a))))
|
|
(t/is (not (nil? (get objects id-b))))
|
|
(t/is (not (nil? (get objects id-c))))
|
|
(t/is (= [id-b id-c id-a] (get-in objects [uuid/zero :shapes]))))))))
|
|
|
|
(t/deftest mod-obj
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(t/testing "simple mod-obj"
|
|
(let [chg {:type :mod-obj
|
|
:page-id page-id
|
|
:id uuid/zero
|
|
:operations [{:type :set
|
|
:attr :name
|
|
:val "foobar"}]}
|
|
res (ch/process-changes data [chg])]
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= "foobar" (get-in objects [uuid/zero :name]))))))
|
|
|
|
(t/testing "mod-obj for not existing shape"
|
|
(let [chg {:type :mod-obj
|
|
:page-id page-id
|
|
:id (uuid/next)
|
|
:operations [{:type :set
|
|
:attr :name
|
|
:val "foobar"}]}
|
|
res (ch/process-changes data [chg])]
|
|
(t/is (= res data))))))
|
|
|
|
(t/deftest mod-page
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(t/testing "sets background and background-token together"
|
|
(let [chg {:type :mod-page
|
|
:id page-id
|
|
:background "#ffffff"
|
|
:background-token "brand.bg"}
|
|
res (ch/process-changes data [chg])
|
|
page (get-in res [:pages-index page-id])]
|
|
(t/is (= "#ffffff" (:background page)))
|
|
(t/is (= "brand.bg" (:background-token page)))))
|
|
|
|
(t/testing "clears background-token while leaving background untouched"
|
|
(let [data' (-> data
|
|
(assoc-in [:pages-index page-id :background] "#ffffff")
|
|
(assoc-in [:pages-index page-id :background-token] "brand.bg"))
|
|
chg {:type :mod-page
|
|
:id page-id
|
|
:background-token nil}
|
|
res (ch/process-changes data' [chg])
|
|
page (get-in res [:pages-index page-id])]
|
|
(t/is (= "#ffffff" (:background page)))
|
|
(t/is (not (contains? page :background-token)))))))
|
|
|
|
(t/deftest del-obj
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
id (uuid/custom 2 1)
|
|
data (make-file-data file-id page-id)
|
|
data (-> data
|
|
(assoc-in [:pages-index page-id :objects uuid/zero :shapes] [id])
|
|
(assoc-in [:pages-index page-id :objects id]
|
|
{:id id
|
|
:frame-id uuid/zero
|
|
:type :rect
|
|
:name "rect"}))]
|
|
(t/testing "delete"
|
|
(let [chg {:type :del-obj
|
|
:page-id page-id
|
|
:id id}
|
|
res (ch/process-changes data [chg])]
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= 1 (count objects)))
|
|
(t/is (= [] (get-in objects [uuid/zero :shapes]))))))
|
|
|
|
(t/testing "delete idempotency"
|
|
(let [chg {:type :del-obj
|
|
:page-id page-id
|
|
:id id}
|
|
res1 (ch/process-changes data [chg])
|
|
res2 (ch/process-changes res1 [chg])]
|
|
|
|
(t/is (= res1 res2))
|
|
(let [objects (get-in res1 [:pages-index page-id :objects])]
|
|
(t/is (= 1 (count objects)))
|
|
(t/is (= [] (get-in objects [uuid/zero :shapes]))))))))
|
|
|
|
|
|
(t/deftest move-objects-1
|
|
(let [frame-a-id (uuid/custom 0 1)
|
|
frame-b-id (uuid/custom 0 2)
|
|
group-a-id (uuid/custom 0 3)
|
|
group-b-id (uuid/custom 0 4)
|
|
rect-a-id (uuid/custom 0 5)
|
|
rect-b-id (uuid/custom 0 6)
|
|
rect-c-id (uuid/custom 0 7)
|
|
rect-d-id (uuid/custom 0 8)
|
|
rect-e-id (uuid/custom 0 9)
|
|
|
|
file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)
|
|
|
|
data (update-in data [:pages-index page-id :objects]
|
|
#(-> %
|
|
(assoc-in [uuid/zero :shapes] [frame-a-id frame-b-id])
|
|
(assoc-in [frame-a-id]
|
|
(cts/setup-shape
|
|
{:id frame-a-id
|
|
:parent-id uuid/zero
|
|
:frame-id uuid/zero
|
|
:name "Frame a"
|
|
:shapes [group-a-id group-b-id rect-e-id]
|
|
:type :frame}))
|
|
|
|
(assoc-in [frame-b-id]
|
|
(cts/setup-shape
|
|
{:id frame-b-id
|
|
:parent-id uuid/zero
|
|
:frame-id uuid/zero
|
|
:name "Frame b"
|
|
:shapes []
|
|
:type :frame}))
|
|
|
|
;; Groups
|
|
(assoc-in [group-a-id]
|
|
(cts/setup-shape
|
|
{:id group-a-id
|
|
:name "Group A"
|
|
:type :group
|
|
:parent-id frame-a-id
|
|
:frame-id frame-a-id
|
|
:shapes [rect-a-id rect-b-id rect-c-id]}))
|
|
(assoc-in [group-b-id]
|
|
(cts/setup-shape
|
|
{:id group-b-id
|
|
:name "Group B"
|
|
:type :group
|
|
:parent-id frame-a-id
|
|
:frame-id frame-a-id
|
|
:shapes [rect-d-id]}))
|
|
|
|
;; Shapes
|
|
(assoc-in [rect-a-id]
|
|
(cts/setup-shape
|
|
{:id rect-a-id
|
|
:name "Rect A"
|
|
:type :rect
|
|
:parent-id group-a-id
|
|
:frame-id frame-a-id}))
|
|
|
|
(assoc-in [rect-b-id]
|
|
(cts/setup-shape
|
|
{:id rect-b-id
|
|
:name "Rect B"
|
|
:type :rect
|
|
:parent-id group-a-id
|
|
:frame-id frame-a-id}))
|
|
|
|
(assoc-in [rect-c-id]
|
|
(cts/setup-shape
|
|
{:id rect-c-id
|
|
:name "Rect C"
|
|
:type :rect
|
|
:parent-id group-a-id
|
|
:frame-id frame-a-id}))
|
|
|
|
(assoc-in [rect-d-id]
|
|
(cts/setup-shape
|
|
{:id rect-d-id
|
|
:name "Rect D"
|
|
:parent-id group-b-id
|
|
:type :rect
|
|
:frame-id frame-a-id}))
|
|
|
|
(assoc-in [rect-e-id]
|
|
(cts/setup-shape
|
|
{:id rect-e-id
|
|
:name "Rect E"
|
|
:type :rect
|
|
:parent-id frame-a-id
|
|
:frame-id frame-a-id}))))]
|
|
|
|
(t/testing "Create new group an add objects from the same group"
|
|
(let [new-group-id (uuid/next)
|
|
changes [{:type :add-obj
|
|
:page-id page-id
|
|
:id new-group-id
|
|
:frame-id frame-a-id
|
|
:obj (cts/setup-shape
|
|
{:id new-group-id
|
|
:type :group
|
|
:frame-id frame-a-id
|
|
:name "Group C"})}
|
|
{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id new-group-id
|
|
:shapes [rect-b-id rect-c-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; (clojure.pprint/pprint data)
|
|
;; (println "===============")
|
|
;; (clojure.pprint/pprint res)
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= [group-a-id group-b-id rect-e-id new-group-id]
|
|
(get-in objects [frame-a-id :shapes])))
|
|
(t/is (= [rect-b-id rect-c-id]
|
|
(get-in objects [new-group-id :shapes])))
|
|
(t/is (= [rect-a-id]
|
|
(get-in objects [group-a-id :shapes]))))))
|
|
|
|
(t/testing "Move elements to an existing group at index"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-b-id
|
|
:index 0
|
|
:shapes [rect-a-id rect-c-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= [group-a-id group-b-id rect-e-id]
|
|
(get-in objects [frame-a-id :shapes])))
|
|
(t/is (= [rect-b-id]
|
|
(get-in objects [group-a-id :shapes])))
|
|
(t/is (= [rect-a-id rect-c-id rect-d-id]
|
|
(get-in objects [group-b-id :shapes]))))))
|
|
|
|
(t/testing "Move elements from group and frame to an existing group at index"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-b-id
|
|
:index 0
|
|
:shapes [rect-a-id rect-e-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= [group-a-id group-b-id]
|
|
(get-in objects [frame-a-id :shapes])))
|
|
(t/is (= [rect-b-id rect-c-id]
|
|
(get-in objects [group-a-id :shapes])))
|
|
(t/is (= [rect-a-id rect-e-id rect-d-id]
|
|
(get-in objects [group-b-id :shapes]))))))
|
|
|
|
(t/testing "Move elements from several groups"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-b-id
|
|
:index 0
|
|
:shapes [rect-a-id rect-e-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= [group-a-id group-b-id]
|
|
(get-in objects [frame-a-id :shapes])))
|
|
(t/is (= [rect-b-id rect-c-id]
|
|
(get-in objects [group-a-id :shapes])))
|
|
(t/is (= [rect-a-id rect-e-id rect-d-id]
|
|
(get-in objects [group-b-id :shapes]))))))
|
|
|
|
(t/testing "Move all elements from a group"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-a-id
|
|
:shapes [rect-d-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= [group-a-id group-b-id rect-e-id]
|
|
(get-in objects [frame-a-id :shapes])))
|
|
(t/is (empty? (get-in objects [group-b-id :shapes]))))))
|
|
|
|
(t/testing "Move elements to a group with different frame"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id frame-b-id
|
|
:shapes [group-a-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects]))
|
|
;; (println "==========")
|
|
;; (pprint (get-in res [:pages-index page-id :objects]))
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
(t/is (= [group-b-id rect-e-id] (get-in objects [frame-a-id :shapes])))
|
|
(t/is (= [group-a-id] (get-in objects [frame-b-id :shapes])))
|
|
(t/is (= frame-b-id (get-in objects [group-a-id :frame-id])))
|
|
(t/is (= frame-b-id (get-in objects [rect-a-id :frame-id])))
|
|
(t/is (= frame-b-id (get-in objects [rect-b-id :frame-id])))
|
|
(t/is (= frame-b-id (get-in objects [rect-c-id :frame-id]))))))
|
|
|
|
(t/testing "Move elements to frame zero"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id uuid/zero
|
|
:shapes [group-a-id]
|
|
:index 0}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
(let [objects (get-in res [:pages-index page-id :objects])]
|
|
;; (pprint (get-in data [:objects uuid/zero]))
|
|
;; (println "==========")
|
|
;; (pprint (get-in objects [uuid/zero]))
|
|
|
|
(t/is (= [group-a-id frame-a-id frame-b-id]
|
|
(get-in objects [uuid/zero :shapes]))))))
|
|
|
|
(t/testing "Don't allow to move inside self"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-a-id
|
|
:shapes [group-a-id]}]
|
|
res (ch/process-changes data changes)]
|
|
(t/is (= data res))))))
|
|
|
|
|
|
(t/deftest mov-objects-regression-1
|
|
(let [shape-1-id (uuid/custom 2 1)
|
|
shape-2-id (uuid/custom 2 2)
|
|
shape-3-id (uuid/custom 2 3)
|
|
frame-id (uuid/custom 1 1)
|
|
file-id (uuid/custom 4 4)
|
|
page-id (uuid/custom 0 1)
|
|
|
|
changes [{:type :add-obj
|
|
:id frame-id
|
|
:page-id page-id
|
|
:parent-id uuid/zero
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:type :frame
|
|
:name "Frame"})}
|
|
{:type :add-obj
|
|
:page-id page-id
|
|
:frame-id frame-id
|
|
:parent-id frame-id
|
|
:id shape-1-id
|
|
:obj (cts/setup-shape
|
|
{:type :rect
|
|
:name "Shape 1"})}
|
|
{:type :add-obj
|
|
:page-id page-id
|
|
:id shape-2-id
|
|
:parent-id uuid/zero
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:type :rect
|
|
:name "Shape 2"})}
|
|
|
|
{:type :add-obj
|
|
:page-id page-id
|
|
:id shape-3-id
|
|
:parent-id uuid/zero
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:type :rect
|
|
:name "Shape 3"})}]
|
|
data (make-file-data file-id page-id)
|
|
data (ch/process-changes data changes)]
|
|
|
|
(t/testing "preserve order on multiple shape mov 1"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:shapes [shape-2-id shape-3-id]
|
|
:parent-id uuid/zero
|
|
:index 0}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; (println "==> BEFORE")
|
|
;; (pprint (get-in data [:objects]))
|
|
;; (println "==> AFTER")
|
|
;; (pprint (get-in res [:objects]))
|
|
|
|
(t/is (= [frame-id shape-2-id shape-3-id]
|
|
(get-in data [:pages-index page-id :objects uuid/zero :shapes])))
|
|
(t/is (= [shape-2-id shape-3-id frame-id]
|
|
(get-in res [:pages-index page-id :objects uuid/zero :shapes])))))
|
|
|
|
(t/testing "preserve order on multiple shape mov 1"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:shapes [shape-3-id shape-2-id]
|
|
:parent-id uuid/zero
|
|
:index 0}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; (println "==> BEFORE")
|
|
;; (pprint (get-in data [:objects]))
|
|
;; (println "==> AFTER")
|
|
;; (pprint (get-in res [:objects]))
|
|
|
|
(t/is (= [frame-id shape-2-id shape-3-id]
|
|
(get-in data [:pages-index page-id :objects uuid/zero :shapes])))
|
|
(t/is (= [shape-3-id shape-2-id frame-id]
|
|
(get-in res [:pages-index page-id :objects uuid/zero :shapes])))))
|
|
|
|
(t/testing "move inside->outside-inside"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:shapes [shape-2-id]
|
|
:parent-id frame-id}
|
|
{:type :mov-objects
|
|
:page-id page-id
|
|
:shapes [shape-2-id]
|
|
:parent-id uuid/zero}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
(t/is (= (get-in res [:pages-index page-id :objects shape-1-id :frame-id])
|
|
(get-in data [:pages-index page-id :objects shape-1-id :frame-id])))
|
|
(t/is (= (get-in res [:pages-index page-id :objects shape-2-id :frame-id])
|
|
(get-in data [:pages-index page-id :objects shape-2-id :frame-id])))))))
|
|
|
|
|
|
(t/deftest move-objects-2
|
|
(let [shape-1-id (uuid/custom 1 1)
|
|
shape-2-id (uuid/custom 1 2)
|
|
shape-3-id (uuid/custom 1 3)
|
|
shape-4-id (uuid/custom 1 4)
|
|
group-1-id (uuid/custom 1 5)
|
|
file-id (uuid/custom 1 6)
|
|
page-id (uuid/custom 0 1)
|
|
|
|
changes [{:type :add-obj
|
|
:page-id page-id
|
|
:id shape-1-id
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:id shape-1-id
|
|
:type :rect
|
|
:name "Shape a"})}
|
|
{:type :add-obj
|
|
:page-id page-id
|
|
:id shape-2-id
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:id shape-2-id
|
|
:type :rect
|
|
:name "Shape b"})}
|
|
{:type :add-obj
|
|
:page-id page-id
|
|
:id shape-3-id
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:id shape-3-id
|
|
:type :rect
|
|
:name "Shape c"})}
|
|
{:type :add-obj
|
|
:page-id page-id
|
|
:id shape-4-id
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:id shape-4-id
|
|
:type :rect
|
|
:name "Shape d"})}
|
|
{:type :add-obj
|
|
:page-id page-id
|
|
:id group-1-id
|
|
:frame-id uuid/zero
|
|
:obj (cts/setup-shape
|
|
{:id group-1-id
|
|
:type :group
|
|
:name "Group"})}
|
|
{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-1-id
|
|
:shapes [shape-1-id shape-2-id]}]
|
|
|
|
data (make-file-data file-id page-id)
|
|
data (ch/process-changes data changes)]
|
|
|
|
(t/testing "case 1"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id uuid/zero
|
|
:index 2
|
|
:shapes [shape-3-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; Before
|
|
|
|
(t/is (= [shape-3-id shape-4-id group-1-id]
|
|
(get-in data [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
;; After
|
|
|
|
(t/is (= [shape-4-id shape-3-id group-1-id]
|
|
(get-in res [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects uuid/zero]))
|
|
;; (pprint (get-in res [:pages-index page-id :objects uuid/zero]))
|
|
))
|
|
|
|
(t/testing "case 2"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-1-id
|
|
:index 2
|
|
:shapes [shape-3-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; Before
|
|
|
|
(t/is (= [shape-3-id shape-4-id group-1-id]
|
|
(get-in data [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-1-id shape-2-id]
|
|
(get-in data [:pages-index page-id :objects group-1-id :shapes])))
|
|
|
|
;; After:
|
|
|
|
(t/is (= [shape-4-id group-1-id]
|
|
(get-in res [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-1-id shape-2-id shape-3-id]
|
|
(get-in res [:pages-index page-id :objects group-1-id :shapes])))
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects group-1-id]))
|
|
;; (pprint (get-in res [:pages-index page-id :objects group-1-id]))
|
|
))
|
|
|
|
(t/testing "case 3"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-1-id
|
|
:index 1
|
|
:shapes [shape-3-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; Before
|
|
|
|
(t/is (= [shape-3-id shape-4-id group-1-id]
|
|
(get-in data [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-1-id shape-2-id]
|
|
(get-in data [:pages-index page-id :objects group-1-id :shapes])))
|
|
|
|
;; After
|
|
|
|
(t/is (= [shape-4-id group-1-id]
|
|
(get-in res [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-1-id shape-3-id shape-2-id]
|
|
(get-in res [:pages-index page-id :objects group-1-id :shapes])))
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects group-1-id]))
|
|
;; (pprint (get-in res [:pages-index page-id :objects group-1-id]))
|
|
))
|
|
|
|
(t/testing "case 4"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id group-1-id
|
|
:index 0
|
|
:shapes [shape-3-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; Before
|
|
|
|
(t/is (= [shape-3-id shape-4-id group-1-id]
|
|
(get-in data [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-1-id shape-2-id]
|
|
(get-in data [:pages-index page-id :objects group-1-id :shapes])))
|
|
|
|
;; After
|
|
|
|
(t/is (= [shape-4-id group-1-id]
|
|
(get-in res [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-3-id shape-1-id shape-2-id]
|
|
(get-in res [:pages-index page-id :objects group-1-id :shapes])))
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects group-1-id]))
|
|
;; (pprint (get-in res [:pages-index page-id :objects group-1-id]))
|
|
))
|
|
|
|
(t/testing "case 5"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id uuid/zero
|
|
:index 0
|
|
:shapes [shape-2-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects uuid/zero]))
|
|
;; (pprint (get-in res [:pages-index page-id :objects uuid/zero]))
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects group-1-id]))
|
|
;; (pprint (get-in res [:pages-index page-id :objects group-1-id]))
|
|
|
|
;; Before
|
|
|
|
(t/is (= [shape-3-id shape-4-id group-1-id]
|
|
(get-in data [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-1-id shape-2-id]
|
|
(get-in data [:pages-index page-id :objects group-1-id :shapes])))
|
|
|
|
;; After
|
|
|
|
(t/is (= [shape-2-id shape-3-id shape-4-id group-1-id]
|
|
(get-in res [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-1-id]
|
|
(get-in res [:pages-index page-id :objects group-1-id :shapes])))))
|
|
|
|
(t/testing "case 6"
|
|
(let [changes [{:type :mov-objects
|
|
:page-id page-id
|
|
:parent-id uuid/zero
|
|
:index 0
|
|
:shapes [shape-2-id shape-1-id]}]
|
|
res (ch/process-changes data changes)]
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects uuid/zero]))
|
|
;; (pprint (get-in res [:pages-index page-id :objects uuid/zero]))
|
|
|
|
;; (pprint (get-in data [:pages-index page-id :objects group-1-id]))
|
|
;; (pprint (get-in res [:pages-index page-id :objects group-1-id]))
|
|
|
|
;; Before
|
|
|
|
(t/is (= [shape-3-id shape-4-id group-1-id]
|
|
(get-in data [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (= [shape-1-id shape-2-id]
|
|
(get-in data [:pages-index page-id :objects group-1-id :shapes])))
|
|
|
|
;; After
|
|
|
|
(t/is (= [shape-2-id shape-1-id shape-3-id shape-4-id group-1-id]
|
|
(get-in res [:pages-index page-id :objects uuid/zero :shapes])))
|
|
|
|
(t/is (not= nil
|
|
(get-in res [:pages-index page-id :objects group-1-id])))))))
|
|
|
|
(t/deftest set-guide-json-encode-decode
|
|
(let [schema ch/schema:set-guide-change
|
|
encode (sm/encoder schema (sm/json-transformer))
|
|
decode (sm/decoder schema (sm/json-transformer))]
|
|
(smt/check!
|
|
(smt/for [data (sg/generator schema)]
|
|
(let [data-1 (encode data)
|
|
data-2 (json-roundtrip data-1)
|
|
data-3 (decode data-2)]
|
|
;; (app.common.pprint/pprint data-2)
|
|
;; (app.common.pprint/pprint data-3)
|
|
(= data data-3)))
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-guide-1
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(smt/check!
|
|
(smt/for [change (sg/generator ch/schema:set-guide-change)]
|
|
(let [change (assoc change :page-id page-id)
|
|
result (ch/process-changes data [change])]
|
|
(= (:params change)
|
|
(get-in result [:pages-index page-id :guides (:id change)]))))
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-guide-2
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(smt/check!
|
|
(smt/for [change (->> (sg/generator ch/schema:set-guide-change)
|
|
(sg/filter :params))]
|
|
(let [change1 (assoc change :page-id page-id)
|
|
result1 (ch/process-changes data [change1])
|
|
|
|
change2 (assoc change1 :params nil)
|
|
result2 (ch/process-changes result1 [change2])]
|
|
|
|
(and (some? (:params change1))
|
|
(= (:params change1)
|
|
(get-in result1 [:pages-index page-id :guides (:id change1)]))
|
|
|
|
(nil? (:params change2))
|
|
(nil? (get-in result2 [:pages-index page-id :guides])))))
|
|
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-comment-thread-position
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
thread-id (uuid/custom 3 1)
|
|
frame-id (uuid/custom 4 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(t/testing "stores position and frame-id"
|
|
(let [change {:type :set-comment-thread-position
|
|
:page-id page-id
|
|
:comment-thread-id thread-id
|
|
:frame-id frame-id
|
|
:position (gpt/point 10 20)}
|
|
res (ch/process-changes data [change])]
|
|
(t/is (= {:frame-id frame-id :position (gpt/point 10 20)}
|
|
(get-in res [:pages-index page-id :comment-thread-positions thread-id])))))
|
|
|
|
(t/testing "removes the position when frame-id and position are nil"
|
|
(let [data (ch/process-changes data [{:type :set-comment-thread-position
|
|
:page-id page-id
|
|
:comment-thread-id thread-id
|
|
:frame-id frame-id
|
|
:position (gpt/point 10 20)}])
|
|
res (ch/process-changes data [{:type :set-comment-thread-position
|
|
:page-id page-id
|
|
:comment-thread-id thread-id
|
|
:frame-id nil
|
|
:position nil}])]
|
|
(t/is (nil? (get-in res [:pages-index page-id :comment-thread-positions thread-id])))))
|
|
|
|
(t/testing "builder round-trips the position through undo and redo"
|
|
(let [data (ch/process-changes data [{:type :set-comment-thread-position
|
|
:page-id page-id
|
|
:comment-thread-id thread-id
|
|
:frame-id frame-id
|
|
:position (gpt/point 10 20)}])
|
|
page (get-in data [:pages-index page-id])
|
|
changes (-> (pcb/empty-changes)
|
|
(pcb/with-page page)
|
|
(pcb/set-comment-thread-position {:id thread-id
|
|
:frame-id frame-id
|
|
:position (gpt/point 100 200)}))
|
|
redone (ch/process-changes data (:redo-changes changes))
|
|
undone (ch/process-changes redone (:undo-changes changes))]
|
|
(t/is (= (gpt/point 100 200)
|
|
(get-in redone [:pages-index page-id :comment-thread-positions thread-id :position])))
|
|
(t/is (= (gpt/point 10 20)
|
|
(get-in undone [:pages-index page-id :comment-thread-positions thread-id :position])))))))
|
|
|
|
(t/deftest set-plugin-data-json-encode-decode
|
|
(let [schema ch/schema:set-plugin-data-change
|
|
encode (sm/encoder schema (sm/json-transformer))
|
|
decode (sm/decoder schema (sm/json-transformer))]
|
|
(smt/check!
|
|
(smt/for [data (sg/generator schema)]
|
|
(let [data-1 (encode data)
|
|
data-2 (json-roundtrip data-1)
|
|
data-3 (decode data-2)]
|
|
(= data data-3)))
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-plugin-data-gen-and-validate
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
(smt/check!
|
|
(smt/for [change (sg/generator ch/schema:set-plugin-data-change)]
|
|
(sm/validate ch/schema:set-plugin-data-change change))
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-flow-json-encode-decode
|
|
(let [schema ch/schema:set-flow-change
|
|
encode (sm/encoder schema (sm/json-transformer))
|
|
decode (sm/decoder schema (sm/json-transformer))]
|
|
(smt/check!
|
|
(smt/for [data (sg/generator schema)]
|
|
(let [data-1 (encode data)
|
|
data-2 (json-roundtrip data-1)
|
|
data-3 (decode data-2)]
|
|
;; (app.common.pprint/pprint data-2)
|
|
;; (app.common.pprint/pprint data-3)
|
|
(= data data-3)))
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-flow-1
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(smt/check!
|
|
(smt/for [change (sg/generator ch/schema:set-flow-change)]
|
|
(let [change (assoc change :page-id page-id)
|
|
result (ch/process-changes data [change])]
|
|
(= (:params change)
|
|
(get-in result [:pages-index page-id :flows (:id change)]))))
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-flow-2
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(smt/check!
|
|
(smt/for [change (->> (sg/generator ch/schema:set-flow-change)
|
|
(sg/filter :params))]
|
|
(let [change1 (assoc change :page-id page-id)
|
|
result1 (ch/process-changes data [change1])
|
|
|
|
change2 (assoc change1 :params nil)
|
|
result2 (ch/process-changes result1 [change2])]
|
|
|
|
(and (some? (:params change1))
|
|
(= (:params change1)
|
|
(get-in result1 [:pages-index page-id :flows (:id change1)]))
|
|
|
|
(nil? (:params change2))
|
|
(nil? (get-in result2 [:pages-index page-id :flows])))))
|
|
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-default-grid-json-encode-decode
|
|
(let [schema ch/schema:set-default-grid-change
|
|
encode (sm/encoder schema (sm/json-transformer))
|
|
decode (sm/decoder schema (sm/json-transformer))]
|
|
(smt/check!
|
|
(smt/for [data (sg/generator schema)]
|
|
(let [data-1 (encode data)
|
|
data-2 (json-roundtrip data-1)
|
|
data-3 (decode data-2)]
|
|
;; (println "==========")
|
|
;; (app.common.pprint/pprint data-2)
|
|
;; (app.common.pprint/pprint data-3)
|
|
;; (println "==========")
|
|
(= data data-3)))
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-default-grid-1
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(smt/check!
|
|
(smt/for [change (sg/generator ch/schema:set-default-grid-change)]
|
|
(let [change (assoc change :page-id page-id)
|
|
result (ch/process-changes data [change])]
|
|
;; (app.common.pprint/pprint change)
|
|
(= (:params change)
|
|
(get-in result [:pages-index page-id :default-grids (:grid-type change)]))))
|
|
{:num 1000})))
|
|
|
|
(t/deftest set-default-grid-2
|
|
(let [file-id (uuid/custom 2 2)
|
|
page-id (uuid/custom 1 1)
|
|
data (make-file-data file-id page-id)]
|
|
|
|
(smt/check!
|
|
(smt/for [change (->> (sg/generator ch/schema:set-default-grid-change)
|
|
(sg/filter :params))]
|
|
(let [change1 (assoc change :page-id page-id)
|
|
result1 (ch/process-changes data [change1])
|
|
|
|
change2 (assoc change1 :params nil)
|
|
result2 (ch/process-changes result1 [change2])]
|
|
|
|
;; (app.common.pprint/pprint change1)
|
|
|
|
(and (some? (:params change1))
|
|
(= (:params change1)
|
|
(get-in result1 [:pages-index page-id :default-grids (:grid-type change1)]))
|
|
|
|
(nil? (:params change2))
|
|
(nil? (get-in result2 [:pages-index page-id :default-grids])))))
|
|
|
|
{:num 1000})))
|