0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-21 14:12:36 -05:00

Merge pull request #283 from tokens-studio/refactor-types-2

Refactor types 2
This commit is contained in:
Florian Schrödl 2024-09-17 09:44:00 +02:00 committed by GitHub
commit 0697e69888
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 1332 additions and 280 deletions

View file

@ -57,6 +57,54 @@
#?(:cljs (instance? lkm/LinkedMap o)
:clj (instance? LinkedMap o)))
(defn oassoc
[o & kvs]
(apply assoc (or o (ordered-map)) kvs))
(defn oassoc-in
[o [k & ks] v]
(if ks
(oassoc o k (oassoc-in (get o k) ks v))
(oassoc o k v)))
(defn oupdate-in
[m ks f & args]
(let [up (fn up [m ks f args]
(let [[k & ks] ks]
(if ks
(oassoc m k (up (get m k) ks f args))
(oassoc m k (apply f (get m k) args)))))]
(up m ks f args)))
(declare index-of)
(defn oassoc-before
"Assoc a k v pair, in the order position just before the other key"
[o before-k k v]
(if-let [index (index-of (keys o) before-k)]
(-> (ordered-map)
(into (take index o))
(assoc k v)
(into (drop index o)))
(oassoc o k v)))
(defn oassoc-in-before
[o [before-k & before-ks] [k & ks] v]
(if-let [index (index-of (keys o) before-k)]
(let [new-v (if ks
(oassoc-in-before (get o k) before-ks ks v)
v)]
(if (= k before-k)
(-> (ordered-map)
(into (take index o))
(assoc k new-v)
(into (drop (inc index) o)))
(-> (ordered-map)
(into (take index o))
(assoc k new-v)
(into (drop index o)))))
(oassoc-in o (cons k ks) v)))
(defn vec2
"Creates a optimized vector compatible type of length 2 backed
internally with MapEntry impl because it has faster access method
@ -564,6 +612,7 @@
new-elems
(remove p? after))))
;; TODO: remove this
(defn addm-at-index
"Insert an element in an ordered map at an arbitrary index"
[coll index key element]

View file

@ -263,7 +263,8 @@
[:delete-temporary-token-theme
[:map {:title "DeleteTemporaryTokenThemeChange"}
[:type [:= :delete-temporary-token-theme]]
[:id ::sm/uuid]]]
[:id ::sm/uuid]
[:name :string]]]
[:add-token-theme
[:map {:title "AddTokenThemeChange"}
@ -274,12 +275,14 @@
[:map {:title "ModTokenThemeChange"}
[:type [:= :mod-token-theme]]
[:id ::sm/uuid]
[:name :string]
[:token-theme ::ctot/token-theme]]]
[:del-token-theme
[:map {:title "DelTokenThemeChange"}
[:type [:= :del-token-theme]]
[:id ::sm/uuid]]]
[:id ::sm/uuid]
[:name :string]]]
[:add-token-set
[:map {:title "AddTokenSetChange"}
@ -822,29 +825,70 @@
set-name
name)))))
(defn- set-ids->names
[data sets]
(let [lib-sets (:token-sets-index data)
set-id->name
(fn [set-id]
(dm/get-in lib-sets [set-id :name]))]
(map set-id->name sets)))
(defmethod process-change :add-temporary-token-theme
[data {:keys [token-theme]}]
(ctotl/add-temporary-token-theme data token-theme))
(-> data
(ctotl/add-temporary-token-theme token-theme)
(update :tokens-lib
#(-> %
(ctob/ensure-tokens-lib)
(ctob/add-theme (-> token-theme
(update :sets (partial set-ids->names data))
(ctob/make-token-theme)))))))
(defmethod process-change :update-active-token-themes
[data {:keys [theme-ids]}]
(ctotl/assoc-active-token-themes data theme-ids))
(defmethod process-change :delete-temporary-token-theme
[data {:keys [id]}]
(ctotl/delete-temporary-token-theme data id))
[data {:keys [id group name]}]
(-> data
(ctotl/delete-temporary-token-theme id)
(update :tokens-lib
#(-> %
(ctob/ensure-tokens-lib)
(ctob/delete-theme group name)))))
(defmethod process-change :add-token-theme
[data {:keys [token-theme]}]
(ctotl/add-token-theme data token-theme))
(-> data
(ctotl/add-token-theme token-theme)
(update :tokens-lib
#(-> %
(ctob/ensure-tokens-lib)
(ctob/add-theme (-> token-theme
(update :sets (partial set-ids->names data))
(ctob/make-token-theme)))))))
(defmethod process-change :mod-token-theme
[data {:keys [id token-theme]}]
(ctotl/update-token-theme data id merge token-theme))
[data {:keys [id name group token-theme]}]
(-> data
(ctotl/update-token-theme id merge token-theme)
(update :tokens-lib
#(-> %
(ctob/ensure-tokens-lib)
(ctob/update-theme name group
(fn [prev-theme]
(merge prev-theme
(-> token-theme
(update :sets (partial set-ids->names data))))))))))
(defmethod process-change :del-token-theme
[data {:keys [id]}]
(ctotl/delete-token-theme data id))
[data {:keys [id group name]}]
(-> data
(ctotl/delete-token-theme id)
(update :tokens-lib
#(-> %
(ctob/ensure-tokens-lib)
(ctob/delete-theme group name)))))
(defmethod process-change :add-token-set
[data {:keys [token-set]}]

View file

@ -699,7 +699,7 @@
[changes token-theme]
(-> changes
(update :redo-changes conj {:type :add-temporary-token-theme :token-theme token-theme})
(update :undo-changes conj {:type :delete-temporary-token-theme :id (:id token-theme)})
(update :undo-changes conj {:type :delete-temporary-token-theme :id (:id token-theme) :name (:name token-theme)})
(apply-changes-local)))
(defn update-active-token-themes
@ -713,14 +713,14 @@
[changes token-theme]
(-> changes
(update :redo-changes conj {:type :add-token-theme :token-theme token-theme})
(update :undo-changes conj {:type :del-token-theme :id (:id token-theme)})
(update :undo-changes conj {:type :del-token-theme :id (:id token-theme) :name (:name token-theme)})
(apply-changes-local)))
(defn update-token-theme
[changes token-theme prev-token-theme]
(-> changes
(update :redo-changes conj {:type :mod-token-theme :id (:id token-theme) :token-theme token-theme})
(update :undo-changes conj {:type :mod-token-theme :id (:id token-theme) :token-theme (or prev-token-theme token-theme)})
(update :redo-changes conj {:type :mod-token-theme :id (:id token-theme) :name (:name prev-token-theme) :token-theme token-theme})
(update :undo-changes conj {:type :mod-token-theme :id (:id token-theme) :name (:name token-theme) :token-theme (or prev-token-theme token-theme)})
(apply-changes-local)))
(defn delete-token-theme
@ -729,7 +729,7 @@
(let [library-data (::library-data (meta changes))
prev-token-theme (get-in library-data [:token-themes-index token-theme-id])]
(-> changes
(update :redo-changes conj {:type :del-token-theme :id token-theme-id})
(update :redo-changes conj {:type :del-token-theme :id token-theme-id :name (:name prev-token-theme)})
(update :undo-changes conj {:type :add-token-theme :token-theme prev-token-theme})
(apply-changes-local))))

View file

@ -16,6 +16,7 @@
java.time.OffsetDateTime
java.util.List
linked.map.LinkedMap
linked.set.LinkedSet
org.fressian.Reader
org.fressian.StreamingWriter
org.fressian.Writer
@ -275,7 +276,12 @@
{:name "clj/seq"
:class clojure.lang.ISeq
:wfn write-list-like
:rfn (comp sequence read-object!)})
:rfn (comp sequence read-object!)}
{:name "linked/set"
:class LinkedSet
:wfn write-list-like
:rfn (comp #(into (d/ordered-set) %) read-object!)})
;; --- PUBLIC API

View file

@ -12,9 +12,88 @@
[app.common.time :as dt]
[app.common.transit :as t]
[app.common.types.token :as cto]
[cuerdas.core :as str]
#?(:clj [app.common.fressian :as fres])))
;; #?(:clj (set! *warn-on-reflection* true))
;; === Groups handling
(def schema:groupable-item
[:map {:title "Groupable item"}
[:name :string]])
(def valid-groupable-item?
(sm/validator schema:groupable-item))
(defn split-path
"Decompose a string in the form 'one.two.three' into a vector of strings, removing spaces."
[path separator]
(let [xf (comp (map str/trim)
(remove str/empty?))]
(->> (str/split path separator)
(into [] xf))))
(defn join-path
"Regenerate a path as a string, from a vector."
[path separator]
(str/join separator path))
(defn group-item
"Add a group to the item name, in the form group.name."
[item group-name separator]
(dm/assert!
"expected groupable item"
(valid-groupable-item? item))
(update item :name #(str group-name separator %)))
(defn ungroup-item
"Remove the first group from the item name."
[item separator]
(dm/assert!
"expected groupable item"
(valid-groupable-item? item))
(update item :name #(-> %
(split-path separator)
(rest)
(join-path separator))))
(defn get-path
"Get the groups part of the name as a vector. E.g. group.subgroup.name -> ['group' 'subrgoup']"
[item separator]
(dm/assert!
"expected groupable item"
(valid-groupable-item? item))
(split-path (:name item) separator))
(defn get-groups-str
"Get the groups part of the name. E.g. group.subgroup.name -> group.subrgoup"
[item separator]
(-> (get-path item separator)
(butlast)
(join-path separator)))
(defn get-final-name
"Get the final part of the name. E.g. group.subgroup.name -> name"
[item separator]
(dm/assert!
"expected groupable item"
(valid-groupable-item? item))
(-> (:name item)
(split-path separator)
(last)))
(defn group?
"Check if a node of the grouping tree is a group or a final item."
[item]
(d/ordered-map? item))
(defn get-children
"Get all children of a group of a grouping tree. Each child is
a tuple [name item], where item "
[group]
(dm/assert!
"expected group node"
(group? group))
(seq group))
;; === Token
@ -56,7 +135,8 @@
(defprotocol ITokenSet
(add-token [_ token] "add a token at the end of the list")
(update-token [_ token-name f] "update a token in the list")
(delete-token [_ token-name] "delete a token from the list"))
(delete-token [_ token-name] "delete a token from the list")
(get-tokens [_] "return an ordered sequence of all tokens in the set"))
(defrecord TokenSet [name description modified-at tokens]
ITokenSet
@ -77,24 +157,27 @@
(dt/now)
(if (= (:name token) (:name token'))
(assoc tokens (:name token') token')
(let [index (d/index-of (keys tokens) (:name token))]
(-> tokens
(dissoc (:name token))
(d/addm-at-index index (:name token') token'))))))
(d/oassoc-before (:name token) (:name token') token')
(dissoc (:name token))))))
this))
(delete-token [_ token-name]
(TokenSet. name
description
(dt/now)
(dissoc tokens token-name))))
(dissoc tokens token-name)))
(get-tokens [_]
(vals tokens)))
(def schema:token-set
[:and [:map {:title "TokenSet"}
[:name :string]
[:description [:maybe :string]]
[:modified-at ::sm/inst]
[:tokens [:map-of {:gen/max 5} :string ::token]]]
[:tokens [:and [:map-of {:gen/max 5} :string ::token]
[:fn d/ordered-map?]]]]
[:fn (partial instance? TokenSet)]])
(sm/register! ::token-set schema:token-set)
@ -119,6 +202,16 @@
token-set))
;; === TokenSetGroup
(defrecord TokenSetGroup [attr1 attr2])
;; TODO schema, validators, etc.
(defn make-token-set-group
[]
(TokenSetGroup. "one" "two"))
;; === TokenSets (collection)
(defprotocol ITokenSets
@ -126,14 +219,24 @@
(update-set [_ set-name f] "modify a set in the ilbrary")
(delete-set [_ set-name] "delete a set in the library")
(set-count [_] "get the total number if sets in the library")
(get-set-tree [_] "get a nested tree of all sets in the library")
(get-sets [_] "get an ordered sequence of all sets in the library")
(get-set [_ set-name] "get one set looking for name")
(validate [_]))
(get-set-group [_ set-group-path] "get the attributes of a set group"))
(def schema:token-set-node
[:schema {:registry {::node [:or ::token-set
[:and
[:map-of {:gen/max 5} :string [:ref ::node]]
[:fn d/ordered-map?]]]}}
[:ref ::node]])
(sm/register! ::token-set-node schema:token-set-node)
(def schema:token-sets
[:and
[:map-of {:title "TokenSets"}
:string ::token-set]
:string ::token-set-node]
[:fn d/ordered-map?]])
(sm/register! ::token-sets schema:token-sets)
@ -144,10 +247,83 @@
(def check-token-sets!
(sm/check-fn ::token-sets))
;; === TokenTheme
(defprotocol ITokenTheme
(toggle-set [_ set-name] "togle a set used / not used in the theme"))
(defrecord TokenTheme [name group description is-source modified-at sets]
ITokenTheme
(toggle-set [_ set-name]
(TokenTheme. name
group
description
is-source
(dt/now)
(if (sets set-name)
(disj sets set-name)
(conj sets set-name)))))
(def schema:token-theme
[:and [:map {:title "TokenTheme"}
[:name :string]
[:group :string]
[:description [:maybe :string]]
[:is-source :boolean]
[:modified-at ::sm/inst]
[:sets [:and [:set {:gen/max 5} :string]
[:fn d/ordered-set?]]]]
[:fn (partial instance? TokenTheme)]])
(sm/register! ::token-theme schema:token-theme)
(def valid-token-theme?
(sm/validator schema:token-theme))
(def check-token-theme!
(sm/check-fn ::token-theme))
(defn make-token-theme
[& {:keys [] :as params}]
(let [params (-> params
(dissoc :id)
(update :group #(or % ""))
(update :is-source #(or % false))
(update :modified-at #(or % (dt/now)))
(update :sets #(into (d/ordered-set) %)))
token-theme (map->TokenTheme params)]
(dm/assert!
"expected valid token theme"
(check-token-theme! token-theme))
token-theme))
;; === TokenThemes (collection)
(defprotocol ITokenThemes
(add-theme [_ token-theme] "add a theme to the library, at the end")
(update-theme [_ group name f] "modify a theme in the ilbrary")
(delete-theme [_ group name] "delete a theme in the library")
(theme-count [_] "get the total number if themes in the library")
(get-theme-tree [_] "get a nested tree of all themes in the library")
(get-themes [_] "get an ordered sequence of all themes in the library")
(get-theme [_ group name] "get one theme looking for name"))
(def schema:token-themes
[:and
[:map-of {:title "TokenThemes"}
:string [:and [:map-of :string ::token-theme]
[:fn d/ordered-map?]]]
[:fn d/ordered-map?]])
(sm/register! ::token-themes schema:token-themes)
(def valid-token-themes?
(constantly true))
(sm/validator schema:token-themes))
(def check-token-themes!
(sm/check-fn ::token-themes))
;; === Tokens Lib
@ -155,62 +331,122 @@
"A library of tokens, sets and themes."
(add-token-in-set [_ set-name token] "add token to a set")
(update-token-in-set [_ set-name token-name f] "update a token in a set")
(delete-token-from-set [_ set-name token-name] "delete a token from a set"))
(delete-token-from-set [_ set-name token-name] "delete a token from a set")
(toggle-set-in-theme [_ group-name theme-name set-name] "toggle a set used / not used in a theme")
(validate [_]))
(deftype TokensLib [sets themes]
(deftype TokensLib [sets set-groups themes]
;; NOTE: This is only for debug purposes, pending to properly
;; implement the toString and alternative printing.
#?@(:clj [clojure.lang.IDeref
(deref [_] {:sets sets :themes themes})]
(deref [_] {:sets sets :set-groups set-groups :themes themes})]
:cljs [cljs.core/IDeref
(-deref [_] {:sets sets :themes themes})])
(-deref [_] {:sets sets :set-groups set-groups :themes themes})])
#?@(:cljs [cljs.core/IEncodeJS
(-clj->js [_] (js-obj "sets" (clj->js sets)
"set-groups" (clj->js set-groups)
"themes" (clj->js themes)))])
ITokenSets
(add-set [_ token-set]
(dm/assert! "expected valid token set" (check-token-set! token-set))
(TokensLib. (assoc sets (:name token-set) token-set)
themes))
(let [path (get-path token-set "/")
groups-str (get-groups-str token-set "/")]
(TokensLib. (d/oassoc-in sets path token-set)
(cond-> set-groups
(not (str/empty? groups-str))
(assoc groups-str (make-token-set-group)))
themes)))
(update-set [this set-name f]
(if-let [set (get sets set-name)]
(let [path (split-path set-name "/")
set (get-in sets path)]
(if set
(let [set' (-> (make-token-set (f set))
(assoc :modified-at (dt/now)))]
(assoc :modified-at (dt/now)))
path' (get-path set' "/")]
(check-token-set! set')
(TokensLib. (if (= (:name set) (:name set'))
(assoc sets (:name set') set')
(let [index (d/index-of (keys sets) (:name set))]
(d/oassoc-in sets path set')
(-> sets
(dissoc (:name set))
(d/addm-at-index index (:name set') set'))))
(d/oassoc-in-before path path' set')
(d/dissoc-in path)))
set-groups ;; TODO update set-groups as needed
themes))
this))
this)))
(delete-set [_ set-name]
(TokensLib. (dissoc sets set-name)
themes))
(let [path (split-path set-name "/")]
(TokensLib. (d/dissoc-in sets path)
set-groups ;; TODO remove set-group if needed
themes)))
(validate [_]
(and (valid-token-sets? sets)
(valid-token-themes? themes)))
(set-count [_]
(count sets))
(get-set-tree [_]
sets)
(get-sets [_]
(vals sets))
(->> (tree-seq d/ordered-map? vals sets)
(filter (partial instance? TokenSet))))
(set-count [this]
(count (get-sets this)))
(get-set [_ set-name]
(get sets set-name))
(let [path (split-path set-name "/")]
(get-in sets path)))
(get-set-group [_ set-group-path]
(get set-groups set-group-path))
ITokenThemes
(add-theme [_ token-theme]
(dm/assert! "expected valid token theme" (check-token-theme! token-theme))
(TokensLib. sets
set-groups
(update themes (:group token-theme) d/oassoc (:name token-theme) token-theme)))
(update-theme [this group name f]
(let [theme (dm/get-in themes [group name])]
(if theme
(let [theme' (-> (make-token-theme (f theme))
(assoc :modified-at (dt/now)))
group' (:group theme')
name' (:name theme')]
(check-token-theme! theme')
(TokensLib. sets
set-groups
(if (and (= group group') (= name name'))
(update themes group' assoc name' theme')
(-> themes
(d/oassoc-in-before [group name] [group' name'] theme')
(d/dissoc-in [group name])))))
this)))
(delete-theme [_ group name]
(TokensLib. sets
set-groups
(d/dissoc-in themes [group name])))
(get-theme-tree [_]
themes)
(get-themes [_]
(->> (tree-seq d/ordered-map? vals themes)
(filter (partial instance? TokenTheme))))
(theme-count [this]
(count (get-themes this)))
(get-theme [_ group name]
(dm/get-in themes [group name]))
ITokensLib
(add-token-in-set [this set-name token]
(dm/assert! "expected valid token instance" (check-token! token))
(if (contains? sets set-name)
(TokensLib. (update sets set-name add-token token)
set-groups
themes)
this))
@ -218,6 +454,7 @@
(if (contains? sets set-name)
(TokensLib. (update sets set-name
#(update-token % token-name f))
set-groups
themes)
this))
@ -225,8 +462,21 @@
(if (contains? sets set-name)
(TokensLib. (update sets set-name
#(delete-token % token-name))
set-groups
themes)
this)))
this))
(toggle-set-in-theme [this theme-group theme-name set-name]
(if-let [_theme (get-in themes theme-group theme-name)]
(TokensLib. sets
set-groups
(d/oupdate-in themes [theme-group theme-name]
#(toggle-set % set-name)))
this))
(validate [_]
(and (valid-token-sets? sets) ;; TODO: validate set-groups
(valid-token-themes? themes))))
(defn valid-tokens-lib?
[o]
@ -248,10 +498,11 @@
;; structure the data and the order separately as we already do
;; with pages and pages-index.
(make-tokens-lib :sets (d/ordered-map)
:set-groups {}
:themes (d/ordered-map)))
([& {:keys [sets themes]}]
(let [tokens-lib (TokensLib. sets themes)]
([& {:keys [sets set-groups themes]}]
(let [tokens-lib (TokensLib. sets set-groups themes)]
(dm/assert!
"expected valid tokens lib"
@ -269,7 +520,7 @@
(sm/register! ::tokens-lib type:tokens-lib)
;; === Serialization handlers for RPC API and database
;; === Serialization handlers for RPC API (transit) and database (fressian)
(t/add-handlers!
{:id "penpot/tokens-lib"
@ -282,6 +533,11 @@
:wfn #(into {} %)
:rfn #(make-token-set %)}
{:id "penpot/token-theme"
:class TokenTheme
:wfn #(into {} %)
:rfn #(make-token-theme %)}
{:id "penpot/token"
:class Token
:wfn #(into {} %)
@ -307,13 +563,24 @@
(let [obj (fres/read-object! r)]
(map->TokenSet obj)))}
{:name "penpot/token-theme/v1"
:class TokenTheme
:wfn (fn [n w o]
(fres/write-tag! w n 1)
(fres/write-object! w (into {} o)))
:rfn (fn [r]
(let [obj (fres/read-object! r)]
(map->TokenTheme obj)))}
{:name "penpot/tokens-lib/v1"
:class TokensLib
:wfn (fn [n w o]
(fres/write-tag! w n 2)
(fres/write-tag! w n 3)
(fres/write-object! w (.-sets o))
(fres/write-object! w (.-set-groups o))
(fres/write-object! w (.-themes o)))
:rfn (fn [r]
(let [sets (fres/read-object! r)
set-groups (fres/read-object! r)
themes (fres/read-object! r)]
(->TokensLib sets themes)))}))
(->TokensLib sets set-groups themes)))}))

View file

@ -19,16 +19,17 @@
(assoc file-data :token-active-themes theme-ids))
(defn add-temporary-token-theme
[file-data {:keys [id] :as token-theme}]
[file-data {:keys [id name] :as token-theme}]
(-> file-data
(d/dissoc-in [:token-themes-index (:token-theme-temporary-id file-data)])
(assoc :token-theme-temporary-id id)
(assoc :token-theme-temporary-name name)
(update :token-themes-index assoc id token-theme)))
(defn delete-temporary-token-theme
[file-data token-theme-id]
(cond-> file-data
(= (:token-theme-temporary-id file-data) token-theme-id) (dissoc :token-theme-temporary-id)
(= (:token-theme-temporary-id file-data) token-theme-id) (dissoc :token-theme-temporary-id :token-theme-temporary-name)
:always (d/dissoc-in [:token-themes-index (:token-theme-temporary-id file-data)])))
(defn add-token-theme

View file

@ -13,7 +13,8 @@
[app.common.types.tokens-lib :as ctob]
[clojure.test :as t]))
(t/deftest make-token
(t/testing "token"
(t/deftest make-token
(let [now (dt/now)
token1 (ctob/make-token :name "test-token-1"
:type :boolean
@ -38,14 +39,16 @@
(t/is (= (:modified-at token2) now))
(t/is (ctob/valid-token? token2))))
(t/deftest invalid-tokens
(t/deftest invalid-tokens
(let [args {:name 777
:type :invalid}]
(t/is (thrown-with-msg? Exception #"expected valid token"
(apply ctob/make-token args)))
(t/is (false? (ctob/valid-token? {})))))
(t/is (false? (ctob/valid-token? {}))))))
(t/deftest make-token-set
(t/testing "token-set"
(t/deftest make-token-set
(let [now (dt/now)
token-set1 (ctob/make-token-set :name "test-token-set-1")
token-set2 (ctob/make-token-set :name "test-token-set-2"
@ -63,17 +66,61 @@
(t/is (= (:modified-at token-set2) now))
(t/is (empty? (:tokens token-set2)))))
(t/deftest invalid-token-set
(t/deftest invalid-token-set
(let [args {:name 777
:description 999}]
(t/is (thrown-with-msg? Exception #"expected valid token set"
(apply ctob/make-token-set args)))))
(apply ctob/make-token-set args))))))
(t/deftest make-tokens-lib
(t/testing "token-theme"
(t/deftest make-token-theme
(let [now (dt/now)
token-theme1 (ctob/make-token-theme :name "test-token-theme-1")
token-theme2 (ctob/make-token-theme :name "test-token-theme-2"
:group "group-1"
:description "test description"
:is-source true
:modified-at now
:sets #{})]
(t/is (= (:name token-theme1) "test-token-theme-1"))
(t/is (= (:group token-theme1) ""))
(t/is (nil? (:description token-theme1)))
(t/is (false? (:is-source token-theme1)))
(t/is (some? (:modified-at token-theme1)))
(t/is (empty? (:sets token-theme1)))
(t/is (= (:name token-theme2) "test-token-theme-2"))
(t/is (= (:group token-theme2) "group-1"))
(t/is (= (:description token-theme2) "test description"))
(t/is (true? (:is-source token-theme2)))
(t/is (= (:modified-at token-theme2) now))
(t/is (empty? (:sets token-theme2)))))
(t/deftest invalid-token-theme
(let [args {:name 777
:group nil
:description 999
:is-source 42}]
(t/is (thrown-with-msg? Exception #"expected valid token theme"
(apply ctob/make-token-theme args))))))
(t/testing "tokens-lib"
(t/deftest make-tokens-lib
(let [tokens-lib (ctob/make-tokens-lib)]
(t/is (= (ctob/set-count tokens-lib) 0))))
(t/deftest add-token-set
(t/deftest invalid-tokens-lib
(let [args {:sets nil
:themes nil}]
(t/is (thrown-with-msg? Exception #"expected valid tokens lib"
(apply ctob/make-tokens-lib args))))))
(t/testing "token-set in a lib"
(t/deftest add-token-set
(let [tokens-lib (ctob/make-tokens-lib)
token-set (ctob/make-token-set :name "test-token-set")
tokens-lib' (ctob/add-set tokens-lib token-set)
@ -85,7 +132,17 @@
(t/is (= (first token-sets') token-set))
(t/is (= token-set' token-set))))
(t/deftest update-token-set
(t/deftest add-token-set-with-group
(let [tokens-lib (ctob/make-tokens-lib)
token-set (ctob/make-token-set :name "test-group/test-token-set")
tokens-lib' (ctob/add-set tokens-lib token-set)
set-group (ctob/get-set-group tokens-lib' "test-group")]
(t/is (= (:attr1 set-group) "one"))
(t/is (= (:attr2 set-group) "two"))))
(t/deftest update-token-set
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
@ -93,22 +150,38 @@
(ctob/update-set "test-token-set"
(fn [token-set]
(assoc token-set
:name "updated-name"
:description "some description")))
(ctob/update-set "not-existing-set"
(fn [token-set]
(assoc token-set
:name "no-effect"))))
:description "no-effect"))))
token-set (ctob/get-set tokens-lib "test-token-set")
token-set' (ctob/get-set tokens-lib' "test-token-set")]
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (:name token-set') "test-token-set"))
(t/is (= (:description token-set') "some description"))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
(t/deftest rename-token-set
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
tokens-lib' (-> tokens-lib
(ctob/update-set "test-token-set"
(fn [token-set]
(assoc token-set
:name "updated-name"))))
token-set (ctob/get-set tokens-lib "test-token-set")
token-set' (ctob/get-set tokens-lib' "updated-name")]
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (:name token-set') "updated-name"))
(t/is (= (:description token-set') "some description"))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
(t/deftest delete-token-set
(t/deftest delete-token-set
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
@ -119,9 +192,11 @@
token-set' (ctob/get-set tokens-lib' "updated-name")]
(t/is (= (ctob/set-count tokens-lib') 0))
(t/is (nil? token-set'))))
(t/is (nil? token-set')))))
(t/deftest add-token
(t/testing "token in a lib"
(t/deftest add-token
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
token (ctob/make-token :name "test-token"
@ -140,7 +215,7 @@
(t/is (= (:name token') "test-token"))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
(t/deftest update-token
(t/deftest update-token
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set"
@ -181,7 +256,7 @@
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/deftest rename-token
(t/deftest rename-token
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set"
@ -213,7 +288,7 @@
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/deftest delete-token
(t/deftest delete-token
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set"
@ -232,28 +307,639 @@
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (count (:tokens token-set')) 0))
(t/is (nil? token'))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))))
(t/deftest transit-serialization
(t/testing "token-theme in a lib"
(t/deftest add-token-theme
(let [tokens-lib (ctob/make-tokens-lib)
token-theme (ctob/make-token-theme :name "test-token-theme")
tokens-lib' (ctob/add-theme tokens-lib token-theme)
token-themes' (ctob/get-themes tokens-lib')
token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")]
(t/is (= (ctob/theme-count tokens-lib') 1))
(t/is (= (first token-themes') token-theme))
(t/is (= token-theme' token-theme))))
(t/deftest update-token-theme
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme")))
tokens-lib' (-> tokens-lib
(ctob/update-theme "" "test-token-theme"
(fn [token-theme]
(assoc token-theme
:description "some description")))
(ctob/update-theme "" "not-existing-theme"
(fn [token-theme]
(assoc token-theme
:description "no-effect"))))
token-theme (ctob/get-theme tokens-lib "" "test-token-theme")
token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")]
(t/is (= (ctob/theme-count tokens-lib') 1))
(t/is (= (:name token-theme') "test-token-theme"))
(t/is (= (:description token-theme') "some description"))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/deftest rename-token-theme
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme")))
tokens-lib' (-> tokens-lib
(ctob/update-theme "" "test-token-theme"
(fn [token-theme]
(assoc token-theme
:name "updated-name"))))
token-theme (ctob/get-theme tokens-lib "" "test-token-theme")
token-theme' (ctob/get-theme tokens-lib' "" "updated-name")]
(t/is (= (ctob/theme-count tokens-lib') 1))
(t/is (= (:name token-theme') "updated-name"))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/deftest delete-token-theme
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme")))
tokens-lib' (-> tokens-lib
(ctob/delete-theme "" "test-token-theme")
(ctob/delete-theme "" "not-existing-theme"))
token-theme' (ctob/get-theme tokens-lib' "" "updated-name")]
(t/is (= (ctob/theme-count tokens-lib') 0))
(t/is (nil? token-theme'))))
(t/deftest toggle-set-in-theme
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "token-set-1"))
(ctob/add-set (ctob/make-token-set :name "token-set-2"))
(ctob/add-set (ctob/make-token-set :name "token-set-3"))
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme")))
tokens-lib' (-> tokens-lib
(ctob/toggle-set-in-theme "" "test-token-theme" "token-set-1")
(ctob/toggle-set-in-theme "" "test-token-theme" "token-set-2")
(ctob/toggle-set-in-theme "" "test-token-theme" "token-set-2"))
token-theme (ctob/get-theme tokens-lib "" "test-token-theme")
token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")]
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))))
(t/testing "serialization"
(t/deftest transit-serialization
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token"
:type :boolean
:value true)))
:value true))
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))
(ctob/toggle-set-in-theme "" "test-token-theme" "test-token-set"))
encoded-str (tr/encode-str tokens-lib)
tokens-lib' (tr/decode-str encoded-str)]
(t/is (ctob/valid-tokens-lib? tokens-lib'))
(t/is (= (ctob/set-count tokens-lib') 1))))
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (ctob/theme-count tokens-lib') 1))))
(t/deftest fressian-serialization
(t/deftest fressian-serialization
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token"
:type :boolean
:value true)))
:value true))
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))
(ctob/toggle-set-in-theme "" "test-token-theme" "test-token-set"))
encoded-blob (fres/encode tokens-lib)
tokens-lib' (fres/decode encoded-blob)]
(t/is (ctob/valid-tokens-lib? tokens-lib'))
(t/is (= (ctob/set-count tokens-lib') 1))))
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (ctob/theme-count tokens-lib') 1)))))
(t/testing "grouping"
(t/deftest split-and-join
(let [name "group/subgroup/name"
path (ctob/split-path name "/")
name' (ctob/join-path path "/")]
(t/is (= (first path) "group"))
(t/is (= (second path) "subgroup"))
(t/is (= (nth path 2) "name"))
(t/is (= name' name))))
(t/deftest remove-spaces
(let [name "group / subgroup / name"
path (ctob/split-path name "/")]
(t/is (= (first path) "group"))
(t/is (= (second path) "subgroup"))
(t/is (= (nth path 2) "name"))))
(t/deftest group-and-ungroup
(let [token-set1 (ctob/make-token-set :name "token-set1")
token-set2 (ctob/make-token-set :name "some group/token-set2")
token-set1' (ctob/group-item token-set1 "big group" "/")
token-set2' (ctob/group-item token-set2 "big group" "/")
token-set1'' (ctob/ungroup-item token-set1' "/")
token-set2'' (ctob/ungroup-item token-set2' "/")]
(t/is (= (:name token-set1') "big group/token-set1"))
(t/is (= (:name token-set2') "big group/some group/token-set2"))
(t/is (= (:name token-set1'') "token-set1"))
(t/is (= (:name token-set2'') "some group/token-set2"))))
(t/deftest get-groups-str
(let [token-set1 (ctob/make-token-set :name "token-set1")
token-set2 (ctob/make-token-set :name "some-group/token-set2")
token-set3 (ctob/make-token-set :name "some-group/some-subgroup/token-set3")]
(t/is (= (ctob/get-groups-str token-set1 "/") ""))
(t/is (= (ctob/get-groups-str token-set2 "/") "some-group"))
(t/is (= (ctob/get-groups-str token-set3 "/") "some-group/some-subgroup"))))
(t/deftest get-final-name
(let [token-set1 (ctob/make-token-set :name "token-set1")
token-set2 (ctob/make-token-set :name "some-group/token-set2")
token-set3 (ctob/make-token-set :name "some-group/some-subgroup/token-set3")]
(t/is (= (ctob/get-final-name token-set1 "/") "token-set1"))
(t/is (= (ctob/get-final-name token-set2 "/") "token-set2"))
(t/is (= (ctob/get-final-name token-set3 "/") "token-set3"))))
(t/testing "grouped tokens"
(t/deftest grouped-tokens
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "token1"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.token2"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.token3"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.subgroup11.token4"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group2.token5"
:type :boolean
:value true)))
set (ctob/get-set tokens-lib "test-token-set")
tokens-list (vals (:tokens set))]
(t/is (= (count tokens-list) 5))
(t/is (= (:name (nth tokens-list 0)) "token1"))
(t/is (= (:name (nth tokens-list 1)) "group1.token2"))
(t/is (= (:name (nth tokens-list 2)) "group1.token3"))
(t/is (= (:name (nth tokens-list 3)) "group1.subgroup11.token4"))
(t/is (= (:name (nth tokens-list 4)) "group2.token5"))))
(t/deftest update-token-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "test-token-1"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.test-token-2"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.test-token-3"
:type :boolean
:value true)))
tokens-lib' (-> tokens-lib
(ctob/update-token-in-set "test-token-set" "group1.test-token-2"
(fn [token]
(assoc token
:description "some description"
:value false))))
token-set (ctob/get-set tokens-lib "test-token-set")
token-set' (ctob/get-set tokens-lib' "test-token-set")
token (get-in token-set [:tokens "group1.test-token-2"])
token' (get-in token-set' [:tokens "group1.test-token-2"])]
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (:name token') "group1.test-token-2"))
(t/is (= (:description token') "some description"))
(t/is (= (:value token') false))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/deftest rename-token-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "test-token-1"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.test-token-2"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.test-token-3"
:type :boolean
:value true)))
tokens-lib' (-> tokens-lib
(ctob/update-token-in-set "test-token-set" "group1.test-token-2"
(fn [token]
(assoc token
:name "group1.updated-name"))))
token-set (ctob/get-set tokens-lib "test-token-set")
token-set' (ctob/get-set tokens-lib' "test-token-set")
token (get-in token-set [:tokens "group1.test-token-2"])
token' (get-in token-set' [:tokens "group1.updated-name"])]
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (:name token') "group1.updated-name"))
(t/is (= (:description token') nil))
(t/is (= (:value token') true))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/deftest move-token-of-group
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "test-token-1"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.test-token-2"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.test-token-3"
:type :boolean
:value true)))
tokens-lib' (-> tokens-lib
(ctob/update-token-in-set "test-token-set" "group1.test-token-2"
(fn [token]
(assoc token
:name "group2.updated-name"))))
token-set (ctob/get-set tokens-lib "test-token-set")
token-set' (ctob/get-set tokens-lib' "test-token-set")
token (get-in token-set [:tokens "group1.test-token-2"])
token' (get-in token-set' [:tokens "group2.updated-name"])]
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (d/index-of (keys (:tokens token-set')) "group2.updated-name") 1))
(t/is (= (:name token') "group2.updated-name"))
(t/is (= (:description token') nil))
(t/is (= (:value token') true))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/deftest delete-token-in-group
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "test-token-1"
:type :boolean
:value true))
(ctob/add-token-in-set "test-token-set"
(ctob/make-token :name "group1.test-token-2"
:type :boolean
:value true)))
tokens-lib' (-> tokens-lib
(ctob/delete-token-from-set "test-token-set" "group1.test-token-2"))
token-set (ctob/get-set tokens-lib "test-token-set")
token-set' (ctob/get-set tokens-lib' "test-token-set")
token' (get-in token-set' [:tokens "group1.test-token-2"])]
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (count (:tokens token-set')) 1))
(t/is (nil? token'))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))))
(t/testing "grouped sets"
(t/deftest grouped-sets
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "token-set-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-3"))
(ctob/add-set (ctob/make-token-set :name "group1/subgroup11/token-set-4"))
(ctob/add-set (ctob/make-token-set :name "group2/token-set-5")))
sets-list (ctob/get-sets tokens-lib)
sets-tree (ctob/get-set-tree tokens-lib)
[node-set1 node-group1 node-group2]
(ctob/get-children sets-tree)
[node-set2 node-set3 node-subgroup11]
(ctob/get-children (second node-group1))
[node-set4]
(ctob/get-children (second node-subgroup11))
[node-set5]
(ctob/get-children (second node-group2))]
(t/is (= (count sets-list) 5))
(t/is (= (:name (nth sets-list 0)) "token-set-1"))
(t/is (= (:name (nth sets-list 1)) "group1/token-set-2"))
(t/is (= (:name (nth sets-list 2)) "group1/token-set-3"))
(t/is (= (:name (nth sets-list 3)) "group1/subgroup11/token-set-4"))
(t/is (= (:name (nth sets-list 4)) "group2/token-set-5"))
(t/is (= (first node-set1) "token-set-1"))
(t/is (= (ctob/group? (second node-set1)) false))
(t/is (= (:name (second node-set1)) "token-set-1"))
(t/is (= (first node-group1) "group1"))
(t/is (= (ctob/group? (second node-group1)) true))
(t/is (= (count (second node-group1)) 3))
(t/is (= (first node-set2) "token-set-2"))
(t/is (= (ctob/group? (second node-set2)) false))
(t/is (= (:name (second node-set2)) "group1/token-set-2"))
(t/is (= (first node-set3) "token-set-3"))
(t/is (= (ctob/group? (second node-set3)) false))
(t/is (= (:name (second node-set3)) "group1/token-set-3"))
(t/is (= (first node-subgroup11) "subgroup11"))
(t/is (= (ctob/group? (second node-subgroup11)) true))
(t/is (= (count (second node-subgroup11)) 1))
(t/is (= (first node-set4) "token-set-4"))
(t/is (= (ctob/group? (second node-set4)) false))
(t/is (= (:name (second node-set4)) "group1/subgroup11/token-set-4"))
(t/is (= (first node-set5) "token-set-5"))
(t/is (= (ctob/group? (second node-set5)) false))
(t/is (= (:name (second node-set5)) "group2/token-set-5"))))
(t/deftest update-set-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "token-set-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-3"))
(ctob/add-set (ctob/make-token-set :name "group1/subgroup11/token-set-4"))
(ctob/add-set (ctob/make-token-set :name "group2/token-set-5")))
tokens-lib' (-> tokens-lib
(ctob/update-set "group1/token-set-2"
(fn [token-set]
(assoc token-set :description "some description"))))
sets-tree (ctob/get-set-tree tokens-lib)
sets-tree' (ctob/get-set-tree tokens-lib')
group1' (get sets-tree' "group1")
token-set (get-in sets-tree ["group1" "token-set-2"])
token-set' (get-in sets-tree' ["group1" "token-set-2"])]
(t/is (= (ctob/set-count tokens-lib') 5))
(t/is (= (count group1') 3))
(t/is (= (d/index-of (keys group1') "token-set-2") 0))
(t/is (= (:name token-set') "group1/token-set-2"))
(t/is (= (:description token-set') "some description"))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
(t/deftest rename-set-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "token-set-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-3"))
(ctob/add-set (ctob/make-token-set :name "group1/subgroup11/token-set-4"))
(ctob/add-set (ctob/make-token-set :name "group2/token-set-5")))
tokens-lib' (-> tokens-lib
(ctob/update-set "group1/token-set-2"
(fn [token-set]
(assoc token-set
:name "group1/updated-name"))))
sets-tree (ctob/get-set-tree tokens-lib)
sets-tree' (ctob/get-set-tree tokens-lib')
group1' (get sets-tree' "group1")
token-set (get-in sets-tree ["group1" "token-set-2"])
token-set' (get-in sets-tree' ["group1" "updated-name"])]
(t/is (= (ctob/set-count tokens-lib') 5))
(t/is (= (count group1') 3))
(t/is (= (d/index-of (keys group1') "updated-name") 0))
(t/is (= (:name token-set') "group1/updated-name"))
(t/is (= (:description token-set') nil))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
(t/deftest move-set-of-group
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "token-set-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-3"))
(ctob/add-set (ctob/make-token-set :name "group1/subgroup11/token-set-4"))
#_(ctob/add-set (ctob/make-token-set :name "group2/token-set-5")))
tokens-lib' (-> tokens-lib
(ctob/update-set "group1/token-set-2"
(fn [token-set]
(assoc token-set
:name "group2/updated-name"))))
sets-tree (ctob/get-set-tree tokens-lib)
sets-tree' (ctob/get-set-tree tokens-lib')
group1' (get sets-tree' "group1")
group2' (get sets-tree' "group2")
token-set (get-in sets-tree ["group1" "token-set-2"])
token-set' (get-in sets-tree' ["group2" "updated-name"])]
(t/is (= (ctob/set-count tokens-lib') 4))
(t/is (= (count group1') 2))
(t/is (= (count group2') 1))
(t/is (= (d/index-of (keys group2') "updated-name") 0))
(t/is (= (:name token-set') "group2/updated-name"))
(t/is (= (:description token-set') nil))
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
(t/deftest delete-set-in-group
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "token-set-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2")))
tokens-lib' (-> tokens-lib
(ctob/delete-set "group1/token-set-2"))
sets-tree' (ctob/get-set-tree tokens-lib')
token-set' (get-in sets-tree' ["group1" "token-set-2"])]
(t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (count sets-tree') 1))
(t/is (nil? token-set')))))
(t/testing "grouped themes"
(t/deftest grouped-themes
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-3"))
(ctob/add-theme (ctob/make-token-theme :group "group2" :name "token-theme-4")))
themes-list (ctob/get-themes tokens-lib)
themes-tree (ctob/get-theme-tree tokens-lib)
[node-group0 node-group1 node-group2]
(ctob/get-children themes-tree)
[node-theme1]
(ctob/get-children (second node-group0))
[node-theme2 node-theme3]
(ctob/get-children (second node-group1))
[node-theme4]
(ctob/get-children (second node-group2))]
(t/is (= (count themes-list) 4))
(t/is (= (:name (nth themes-list 0)) "token-theme-1"))
(t/is (= (:name (nth themes-list 1)) "token-theme-2"))
(t/is (= (:name (nth themes-list 2)) "token-theme-3"))
(t/is (= (:name (nth themes-list 3)) "token-theme-4"))
(t/is (= (:group (nth themes-list 0)) ""))
(t/is (= (:group (nth themes-list 1)) "group1"))
(t/is (= (:group (nth themes-list 2)) "group1"))
(t/is (= (:group (nth themes-list 3)) "group2"))
(t/is (= (first node-group0) ""))
(t/is (= (ctob/group? (second node-group0)) true))
(t/is (= (count (second node-group0)) 1))
(t/is (= (first node-theme1) "token-theme-1"))
(t/is (= (ctob/group? (second node-theme1)) false))
(t/is (= (:name (second node-theme1)) "token-theme-1"))
(t/is (= (first node-group1) "group1"))
(t/is (= (ctob/group? (second node-group1)) true))
(t/is (= (count (second node-group1)) 2))
(t/is (= (first node-theme2) "token-theme-2"))
(t/is (= (ctob/group? (second node-theme2)) false))
(t/is (= (:name (second node-theme2)) "token-theme-2"))
(t/is (= (first node-theme3) "token-theme-3"))
(t/is (= (ctob/group? (second node-theme3)) false))
(t/is (= (:name (second node-theme3)) "token-theme-3"))
(t/is (= (first node-theme4) "token-theme-4"))
(t/is (= (ctob/group? (second node-theme4)) false))
(t/is (= (:name (second node-theme4)) "token-theme-4"))))
(t/deftest update-theme-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-3"))
(ctob/add-theme (ctob/make-token-theme :group "group2" :name "token-theme-4")))
tokens-lib' (-> tokens-lib
(ctob/update-theme "group1" "token-theme-2"
(fn [token-theme]
(assoc token-theme :description "some description"))))
themes-tree (ctob/get-theme-tree tokens-lib)
themes-tree' (ctob/get-theme-tree tokens-lib')
group1' (get themes-tree' "group1")
token-theme (get-in themes-tree ["group1" "token-theme-2"])
token-theme' (get-in themes-tree' ["group1" "token-theme-2"])]
(t/is (= (ctob/theme-count tokens-lib') 4))
(t/is (= (count group1') 2))
(t/is (= (d/index-of (keys group1') "token-theme-2") 0))
(t/is (= (:name token-theme') "token-theme-2"))
(t/is (= (:group token-theme') "group1"))
(t/is (= (:description token-theme') "some description"))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/deftest rename-theme-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-3"))
(ctob/add-theme (ctob/make-token-theme :group "group2" :name "token-theme-4")))
tokens-lib' (-> tokens-lib
(ctob/update-theme "group1" "token-theme-2"
(fn [token-theme]
(assoc token-theme
:name "updated-name"))))
themes-tree (ctob/get-theme-tree tokens-lib)
themes-tree' (ctob/get-theme-tree tokens-lib')
group1' (get themes-tree' "group1")
token-theme (get-in themes-tree ["group1" "token-theme-2"])
token-theme' (get-in themes-tree' ["group1" "updated-name"])]
(t/is (= (ctob/theme-count tokens-lib') 4))
(t/is (= (count group1') 2))
(t/is (= (d/index-of (keys group1') "updated-name") 0))
(t/is (= (:name token-theme') "updated-name"))
(t/is (= (:group token-theme') "group1"))
(t/is (= (:description token-theme') nil))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/deftest move-theme-of-group
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-3"))
#_(ctob/add-theme (ctob/make-token-theme :group "group2" :name "token-theme-4")))
tokens-lib' (-> tokens-lib
(ctob/update-theme "group1" "token-theme-2"
(fn [token-theme]
(assoc token-theme
:name "updated-name"
:group "group2"))))
themes-tree (ctob/get-theme-tree tokens-lib)
themes-tree' (ctob/get-theme-tree tokens-lib')
group1' (get themes-tree' "group1")
group2' (get themes-tree' "group2")
token-theme (get-in themes-tree ["group1" "token-theme-2"])
token-theme' (get-in themes-tree' ["group2" "updated-name"])]
(t/is (= (ctob/theme-count tokens-lib') 3))
(t/is (= (count group1') 1))
(t/is (= (count group2') 1))
(t/is (= (d/index-of (keys group2') "updated-name") 0))
(t/is (= (:name token-theme') "updated-name"))
(t/is (= (:group token-theme') "group2"))
(t/is (= (:description token-theme') nil))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/deftest delete-theme-in-group
(let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :group "" :name "token-theme-1"))
(ctob/add-theme (ctob/make-token-theme :group "group1" :name "token-theme-2")))
tokens-lib' (-> tokens-lib
(ctob/delete-theme "group1" "token-theme-2"))
themes-tree' (ctob/get-theme-tree tokens-lib')
token-theme' (get-in themes-tree' ["group1" "token-theme-2"])]
(t/is (= (ctob/theme-count tokens-lib') 1))
(t/is (= (count themes-tree') 1))
(t/is (nil? token-theme'))))))

View file

@ -115,10 +115,9 @@
(ptk/reify ::update-token-theme
ptk/WatchEvent
(watch [it state _]
(let [prev-token-theme (wtts/get-workspace-token-theme state (:id token-theme))
(let [prev-token-theme (wtts/get-workspace-token-theme (:id token-theme) state)
changes (-> (pcb/empty-changes it)
(pcb/update-token-theme token-theme prev-token-theme))]
(js/console.log "changes" changes)
(rx/of
(dch/commit-changes changes))))))

View file

@ -69,11 +69,11 @@
(defn group-assets
"Convert a list of assets in a nested structure like this:
{'': [{assetA} {assetB}]
'group1': {'': [{asset1A} {asset1B}]
'subgroup11': {'': [{asset11A} {asset11B} {asset11C}]}
'subgroup12': {'': [{asset12A}]}}
'group2': {'subgroup21': {'': [{asset21A}}}}
{'': [assetA assetB]
'group1': {'': [asset1A asset1B]
'subgroup11': {'': [asset11A asset11B asset11C]}
'subgroup12': {'': [asset12A]}}
'group2': {'subgroup21': {'': [asset21A]}}}
"
[assets reverse-sort?]
(when-not (empty? assets)