Merge pull request #6075 from penpot/niwinz-develop-token-fixes-1

 Add several fixes and improvements to tokens
This commit is contained in:
Andrey Antukh 2025-03-17 14:47:21 +01:00 committed by GitHub
commit c1c22dc6c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 1480 additions and 1447 deletions

View file

@ -376,18 +376,12 @@
[:type [:= :update-active-token-themes]] [:type [:= :update-active-token-themes]]
[:theme-ids [:set :string]]]] [:theme-ids [:set :string]]]]
[:add-token-sets
[:map {:title "AddTokenSetsChange"}
[:type [:= :add-token-sets]]
[:token-sets [:sequential ::ctot/token-set]]]]
[:rename-token-set-group [:rename-token-set-group
[:map {:title "RenameTokenSetGroup"} [:map {:title "RenameTokenSetGroup"}
[:type [:= :rename-token-set-group]] [:type [:= :rename-token-set-group]]
[:set-group-path [:vector :string]] [:set-group-path [:vector :string]]
[:set-group-fname :string]]] [:set-group-fname :string]]]
[:move-token-set-before [:move-token-set-before
[:map {:title "MoveTokenSetBefore"} [:map {:title "MoveTokenSetBefore"}
[:type [:= :move-token-set-before]] [:type [:= :move-token-set-before]]
@ -1050,12 +1044,6 @@
(update data :tokens-lib #(-> % (ctob/ensure-tokens-lib) (update data :tokens-lib #(-> % (ctob/ensure-tokens-lib)
(ctob/set-active-themes theme-ids)))) (ctob/set-active-themes theme-ids))))
(defmethod process-change :add-token-sets
[data {:keys [token-sets]}]
(update data :tokens-lib #(-> %
(ctob/ensure-tokens-lib)
(ctob/add-sets (map ctob/make-token-set token-sets)))))
(defmethod process-change :rename-token-set-group (defmethod process-change :rename-token-set-group
[data {:keys [set-group-path set-group-fname]}] [data {:keys [set-group-path set-group-fname]}]
(update data :tokens-lib (fn [lib] (update data :tokens-lib (fn [lib]

View file

@ -875,7 +875,26 @@
:token nil})) :token nil}))
(apply-changes-local)))) (apply-changes-local))))
(defn set-token-set [changes set-name group? token-set] (defn rename-token-set
[changes name new-name]
(assert-library! changes)
(let [library-data (::library-data (meta changes))
prev-token-set (some-> (get library-data :tokens-lib)
(ctob/get-set name))]
(-> changes
(update :redo-changes conj {:type :set-token-set
:set-name name
:token-set (assoc prev-token-set :name new-name)
:group? false})
(update :undo-changes conj {:type :set-token-set
:set-name new-name
:token-set prev-token-set
:group? false})
(apply-changes-local))))
(defn set-token-set
[changes set-name group? token-set]
(assert-library! changes) (assert-library! changes)
(let [library-data (::library-data (meta changes)) (let [library-data (::library-data (meta changes))
prev-token-set (some-> (get library-data :tokens-lib) prev-token-set (some-> (get library-data :tokens-lib)

View file

@ -44,7 +44,7 @@
(defn vec-starts-with? [v1 v2] (defn vec-starts-with? [v1 v2]
(= (subvec v1 0 (min (count v1) (count v2))) v2)) (= (subvec v1 0 (min (count v1) (count v2))) v2))
(defn calculate-move-token-set-or-set-group (defn- calculate-move-token-set-or-set-group
[tokens-lib {:keys [from-index to-index position collapsed-paths] [tokens-lib {:keys [from-index to-index position collapsed-paths]
:or {collapsed-paths #{}}}] :or {collapsed-paths #{}}}]
(let [tree (-> (ctob/get-set-tree tokens-lib) (let [tree (-> (ctob/get-set-tree tokens-lib)

View file

@ -27,14 +27,17 @@
(def valid-groupable-item? (def valid-groupable-item?
(sm/validator schema:groupable-item)) (sm/validator schema:groupable-item))
(def xf-map-trim
(comp
(map str/trim)
(remove str/empty?)))
(defn split-path (defn split-path
"Decompose a string in the form 'one.two.three' into a vector of strings, removing spaces." "Decompose a string in the form 'one.two.three' into a vector of strings, removing spaces."
[path separator] [path separator]
(let [xf (comp (map str/trim)
(remove str/empty?))]
(->> (str/split path separator) (->> (str/split path separator)
(into [] xf)))) (into [] xf-map-trim)
(not-empty)))
(defn split-path-name [s separator] (defn split-path-name [s separator]
(let [[path name] (str/split s (re-pattern (str "\\" separator)) 2)] (let [[path name] (str/split s (re-pattern (str "\\" separator)) 2)]
@ -61,10 +64,12 @@
(join-path separator)))) (join-path separator))))
(defn get-path (defn get-path
"Get the groups part of the name as a vector. E.g. group.subgroup.name -> ['group' 'subgroup']" "Get the path of object by specified separator (E.g. with '.'
separator, the 'group.subgroup.name' -> ['group' 'subgroup'])"
[item separator] [item separator]
(assert (valid-groupable-item? item) "expected groupable item") (assert (valid-groupable-item? item) "expected groupable item")
(split-path (:name item) separator)) (->> (split-path (:name item) separator)
(not-empty)))
(defn get-groups-str (defn get-groups-str
"Get the groups part of the name. E.g. group.subgroup.name -> group.subgroup" "Get the groups part of the name. E.g. group.subgroup.name -> group.subgroup"
@ -97,14 +102,9 @@
(def token-separator ".") (def token-separator ".")
(defn get-token-path [path] (defn get-token-path
(get-path path token-separator)) [token]
(get-path token token-separator))
;; FIXME: misleading name, we are spliting name into path, not
;; spliting path into path
(defn split-token-path
[path]
(split-path path token-separator))
(defrecord Token [name type value description modified-at]) (defrecord Token [name type value description modified-at])
@ -247,22 +247,33 @@
set-name (add-set-prefix (last paths))] set-name (add-set-prefix (last paths))]
(conj set-path set-name))) (conj set-path set-name)))
(defn get-token-set-path
[token-set]
(get-path token-set set-separator))
(defn split-token-set-name (defn split-token-set-name
[name] [name]
(split-path name set-separator)) (split-path name set-separator))
(defn get-token-set-path [token-set] (defn normalize-set-name
(let [path (get-path token-set set-separator)] "Normalize a set name.
(add-token-set-paths-prefix path)))
If `relative-to` is provided, the normalized name will preserve the
same group prefix as reference name"
([name]
(->> (split-token-set-name name)
(str/join set-separator)))
([name relative-to]
(->> (concat (butlast (split-token-set-name relative-to))
(split-token-set-name name))
(str/join set-separator))))
;; FIXME: revisit
(defn get-token-set-final-name (defn get-token-set-final-name
[name] [name]
(-> (split-token-set-name name) (-> (split-token-set-name name)
(peek))) (peek)))
(defn split-token-set-path [token-set-path]
(split-path token-set-path set-separator))
(defn set-name->prefixed-full-path [name-str] (defn set-name->prefixed-full-path [name-str]
(-> (split-token-set-name name-str) (-> (split-token-set-name name-str)
(set-full-path->set-prefixed-full-path))) (set-full-path->set-prefixed-full-path)))
@ -291,7 +302,7 @@
[tokens & {:keys [update-token-fn] [tokens & {:keys [update-token-fn]
:or {update-token-fn identity}}] :or {update-token-fn identity}}]
(reduce-kv (fn [acc _ token] (reduce-kv (fn [acc _ token]
(let [path (split-token-path (:name token))] (let [path (get-token-path token)]
(assoc-in acc path (update-token-fn token)))) (assoc-in acc path (update-token-fn token))))
{} tokens)) {} tokens))
@ -304,7 +315,7 @@
(fn [acc [_ token]] (fn [acc [_ token]]
(let [temp-id (random-uuid) (let [temp-id (random-uuid)
token (assoc token :temp/id temp-id) token (assoc token :temp/id temp-id)
path (split-token-path (:name token))] path (get-token-path token)]
(-> acc (-> acc
(assoc-in (concat [:tokens-tree] path) token) (assoc-in (concat [:tokens-tree] path) token)
(assoc-in [:ids temp-id] token)))) (assoc-in [:ids temp-id] token))))
@ -316,10 +327,7 @@
(update-token [_ token-name f] "update a token in 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-token [_ token-name] "return token by token-name") (get-token [_ token-name] "return token by token-name")
(get-tokens [_] "return an ordered sequence of all tokens in the set") (get-tokens [_] "return an ordered sequence of all tokens in the set"))
(get-set-prefixed-path-string [_] "convert set name to prefixed full path string")
(get-tokens-tree [_] "returns a tree of tokens split & nested by their name path")
(get-dtcg-tokens-tree [_] "returns tokens tree formated to the dtcg spec"))
(defrecord TokenSet [name description modified-at tokens] (defrecord TokenSet [name description modified-at tokens]
ITokenSet ITokenSet
@ -363,20 +371,7 @@
(get tokens token-name)) (get tokens token-name))
(get-tokens [_] (get-tokens [_]
(vals tokens)) (vals tokens)))
(get-set-prefixed-path-string [_]
(-> (set-name->prefixed-full-path name)
(join-set-path)))
(get-tokens-tree [_]
(tokens-tree tokens))
(get-dtcg-tokens-tree [_]
(tokens-tree tokens :update-token-fn (fn [token]
(cond-> {"$value" (:value token)
"$type" (cto/token-type->dtcg-token-type (:type token))}
(:description token) (assoc "$description" (:description token)))))))
(defn token-set? (defn token-set?
[o] [o]
@ -435,7 +430,6 @@
Prefixed set full path or pfpath: a full path wit prefixes [\"G-some-group\", \"G-some-subgroup\", \"S-some-set\"]. Prefixed set full path or pfpath: a full path wit prefixes [\"G-some-group\", \"G-some-subgroup\", \"S-some-set\"].
Prefixed set final name or pfname: a final name with prefix \"S-some-set\"." Prefixed set final name or pfname: a final name with prefix \"S-some-set\"."
(add-set [_ token-set] "add a set to the library, at the end") (add-set [_ token-set] "add a set to the library, at the end")
(add-sets [_ token-set] "add a collection of sets to the library, at the end")
(update-set [_ set-name f] "modify a set in the library") (update-set [_ set-name f] "modify a set in the library")
(delete-set-path [_ set-path] "delete a set in the library") (delete-set-path [_ set-path] "delete a set in the library")
(delete-set [_ set-name] "delete a set at `set-name` in the library and disable the `set-name` in all themes") (delete-set [_ set-name] "delete a set at `set-name` in the library and disable the `set-name` in all themes")
@ -880,9 +874,6 @@ Will return a value that matches this schema:
themes themes
active-themes))) active-themes)))
(add-sets [this token-sets]
(reduce add-set this token-sets))
(update-set [this set-name f] (update-set [this set-name f]
(let [prefixed-full-path (set-name->prefixed-full-path set-name) (let [prefixed-full-path (set-name->prefixed-full-path set-name)
set (get-in sets prefixed-full-path)] set (get-in sets prefixed-full-path)]
@ -920,7 +911,7 @@ Will return a value that matches this schema:
active-themes))) active-themes)))
(delete-set-group [this set-group-name] (delete-set-group [this set-group-name]
(let [path (split-token-set-path set-group-name) (let [path (split-token-set-name set-group-name)
prefixed-path (map add-set-group-prefix path) prefixed-path (map add-set-group-prefix path)
child-set-names (->> (get-sets-at-path this path) child-set-names (->> (get-sets-at-path this path)
(map :name) (map :name)
@ -1245,7 +1236,7 @@ Will return a value that matches this schema:
(d/ordered-map) active-themes))) (d/ordered-map) active-themes)))
(encode-dtcg [this] (encode-dtcg [this]
(let [themes (into [] (let [themes-xform
(comp (comp
(filter #(and (instance? TokenTheme %) (filter #(and (instance? TokenTheme %)
(not (hidden-temporary-theme? %)))) (not (hidden-temporary-theme? %))))
@ -1256,20 +1247,38 @@ Will return a value that matches this schema:
(-> theme-map (-> theme-map
(set/rename-keys {"sets" "selectedTokenSets"}) (set/rename-keys {"sets" "selectedTokenSets"})
(update "selectedTokenSets" (fn [sets] (update "selectedTokenSets" (fn [sets]
(->> (for [s sets] (->> (for [s sets] [s "enabled"])
[s "enabled"])
(into {}))))))))) (into {})))))))))
(tree-seq d/ordered-map? vals themes)) themes
(->> (tree-seq d/ordered-map? vals themes)
(into [] themes-xform))
;; Active themes without exposing hidden penpot theme ;; Active themes without exposing hidden penpot theme
active-themes-clear (disj active-themes hidden-token-theme-path) active-themes-clear
name-set-tuples (->> sets (disj active-themes hidden-token-theme-path)
update-token-fn
(fn [token]
(cond-> {"$value" (:value token)
"$type" (cto/token-type->dtcg-token-type (:type token))}
(:description token) (assoc "$description" (:description token))))
name-set-tuples
(->> sets
(tree-seq d/ordered-map? vals) (tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet)) (filter (partial instance? TokenSet))
(map (fn [token-set] (map (fn [{:keys [name tokens]}]
[(:name token-set) (get-dtcg-tokens-tree token-set)]))) [name (tokens-tree tokens :update-token-fn update-token-fn)])))
ordered-set-names (map first name-set-tuples)
sets (into {} name-set-tuples) ordered-set-names
active-sets (get-active-themes-set-names this)] (mapv first name-set-tuples)
sets
(into {} name-set-tuples)
active-sets
(get-active-themes-set-names this)]
(-> sets (-> sets
(assoc "$themes" themes) (assoc "$themes" themes)
(assoc-in ["$metadata" "tokenSetOrder"] ordered-set-names) (assoc-in ["$metadata" "tokenSetOrder"] ordered-set-names)
@ -1470,10 +1479,12 @@ Will return a value that matches this schema:
prev-sets (->> (fres/read-object! r) prev-sets (->> (fres/read-object! r)
(tree-seq d/ordered-map? vals) (tree-seq d/ordered-map? vals)
(filter (partial instance? TokenSet))) (filter (partial instance? TokenSet)))
sets (-> (make-tokens-lib)
(add-sets prev-sets) ;; FIXME: wtf we usind deref here?
sets (-> (reduce add-set (make-tokens-lib) prev-sets)
(deref) (deref)
:sets) (:sets))
_set-groups (fres/read-object! r) _set-groups (fres/read-object! r)
themes (fres/read-object! r) themes (fres/read-object! r)
active-themes (fres/read-object! r)] active-themes (fres/read-object! r)]

View file

@ -22,8 +22,7 @@
(t/use-fixtures :once setup-virtual-time) (t/use-fixtures :once setup-virtual-time)
(t/deftest tokens (t/deftest make-token
(t/testing "make-token"
(let [now (dt/now) (let [now (dt/now)
token1 (ctob/make-token :name "test-token-1" token1 (ctob/make-token :name "test-token-1"
:type :boolean :type :boolean
@ -48,12 +47,12 @@
(t/is (= (:modified-at token2) now)) (t/is (= (:modified-at token2) now))
(t/is (ctob/check-token token2)))) (t/is (ctob/check-token token2))))
(t/testing "invalid-tokens" (t/deftest make-invalid-token
(let [params {:name 777 :type :invalid}] (let [params {:name 777 :type :invalid}]
(t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token" (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token"
(ctob/make-token params))))) (ctob/make-token params)))))
(t/testing "find-token-value-references" (t/deftest find-token-value-references
(t/testing "finds references inside curly braces in a string" (t/testing "finds references inside curly braces in a string"
(t/is (= #{"foo" "bar"} (ctob/find-token-value-references "{foo} + {bar}"))) (t/is (= #{"foo" "bar"} (ctob/find-token-value-references "{foo} + {bar}")))
(t/testing "ignores extra text" (t/testing "ignores extra text"
@ -61,10 +60,9 @@
(t/testing "ignores string without references" (t/testing "ignores string without references"
(t/is (nil? (ctob/find-token-value-references "1 + 2")))) (t/is (nil? (ctob/find-token-value-references "1 + 2"))))
(t/testing "handles edge-case for extra curly braces" (t/testing "handles edge-case for extra curly braces"
(t/is (= #{"foo" "bar"} (ctob/find-token-value-references "{foo}} + {bar}")))))) (t/is (= #{"foo" "bar"} (ctob/find-token-value-references "{foo}} + {bar}")))))
(t/deftest token-set (t/deftest make-token-set
(t/testing "make-token-set"
(let [now (dt/now) (let [now (dt/now)
token-set1 (ctob/make-token-set :name "test-token-set-1") token-set1 (ctob/make-token-set :name "test-token-set-1")
token-set2 (ctob/make-token-set :name "test-token-set-2" token-set2 (ctob/make-token-set :name "test-token-set-2"
@ -81,12 +79,12 @@
(t/is (= (:modified-at token-set2) now)) (t/is (= (:modified-at token-set2) now))
(t/is (empty? (:tokens token-set2))))) (t/is (empty? (:tokens token-set2)))))
(t/testing "invalid-token-set" (t/deftest make-invalid-token-set
(let [params {:name 777 :description 999}] (let [params {:name 777 :description 999}]
(t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-set" (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-set"
(ctob/make-token-set params))))) (ctob/make-token-set params)))))
(t/testing "move-token-set" (t/deftest move-token-set
(t/testing "flat" (t/testing "flat"
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "A")) (ctob/add-set (ctob/make-token-set :name "A"))
@ -123,6 +121,7 @@
(t/is (= ["Foo/Foo" "Foo/Baz" "Foo/Bar"] (move ["Foo"] ["Foo" "Foo"] ["Foo" "Baz"] false))) (t/is (= ["Foo/Foo" "Foo/Baz" "Foo/Bar"] (move ["Foo"] ["Foo" "Foo"] ["Foo" "Baz"] false)))
(t/is (= ["Foo/Baz" "Foo/Bar" "Foo/Foo"] (move ["Foo"] ["Foo" "Foo"] nil false)))))) (t/is (= ["Foo/Baz" "Foo/Bar" "Foo/Foo"] (move ["Foo"] ["Foo" "Foo"] nil false))))))
;; FIXME
(t/testing "updates theme set names" (t/testing "updates theme set names"
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "Foo/Bar/Baz")) (ctob/add-set (ctob/make-token-set :name "Foo/Bar/Baz"))
@ -132,7 +131,7 @@
(ctob/move-set ["Foo" "Bar" "Baz"] ["Other/Baz"] nil nil))] (ctob/move-set ["Foo" "Bar" "Baz"] ["Other/Baz"] nil nil))]
(t/is (= #{"Other/Baz"} (:sets (ctob/get-theme tokens-lib "" "Theme"))))))) (t/is (= #{"Other/Baz"} (:sets (ctob/get-theme tokens-lib "" "Theme")))))))
(t/testing "move-token-set-group" (t/deftest move-token-set-group
(t/testing "reordering" (t/testing "reordering"
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "Foo/A")) (ctob/add-set (ctob/make-token-set :name "Foo/A"))
@ -157,7 +156,7 @@
(ctob/move-set-group ["Foo"] ["Bar" "Foo"] nil nil))] (ctob/move-set-group ["Foo"] ["Bar" "Foo"] nil nil))]
(t/is (= #{"Bar/Foo/A" "Bar/Foo"} (:sets (ctob/get-theme tokens-lib "" "Theme"))))))) (t/is (= #{"Bar/Foo/A" "Bar/Foo"} (:sets (ctob/get-theme tokens-lib "" "Theme")))))))
(t/testing "tokens-tree" (t/deftest tokens-tree
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "A" (ctob/add-set (ctob/make-token-set :name "A"
:tokens {"foo.bar.baz" (ctob/make-token :name "foo.bar.baz" :tokens {"foo.bar.baz" (ctob/make-token :name "foo.bar.baz"
@ -170,13 +169,13 @@
:type :boolean :type :boolean
:value true)}))) :value true)})))
expected (-> (ctob/get-set tokens-lib "A") expected (-> (ctob/get-set tokens-lib "A")
(ctob/get-tokens-tree))] (get :tokens)
(ctob/tokens-tree))]
(t/is (= (get-in expected ["foo" "bar" "baz" :name]) "foo.bar.baz")) (t/is (= (get-in expected ["foo" "bar" "baz" :name]) "foo.bar.baz"))
(t/is (= (get-in expected ["foo" "bar" "bam" :name]) "foo.bar.bam")) (t/is (= (get-in expected ["foo" "bar" "bam" :name]) "foo.bar.bam"))
(t/is (= (get-in expected ["baz" "boo" :name]) "baz.boo"))))) (t/is (= (get-in expected ["baz" "boo" :name]) "baz.boo"))))
(t/deftest token-theme (t/deftest make-token-theme
(t/testing "make-token-theme"
(let [now (dt/now) (let [now (dt/now)
token-theme1 (ctob/make-token-theme :name "test-token-theme-1") token-theme1 (ctob/make-token-theme :name "test-token-theme-1")
token-theme2 (ctob/make-token-theme :name "test-token-theme-2" token-theme2 (ctob/make-token-theme :name "test-token-theme-2"
@ -200,28 +199,25 @@
(t/is (= (:modified-at token-theme2) now)) (t/is (= (:modified-at token-theme2) now))
(t/is (empty? (:sets token-theme2))))) (t/is (empty? (:sets token-theme2)))))
(t/testing "invalid-token-theme" (t/deftest make-invalid-token-theme
(let [params {:name 777 (let [params {:name 777
:group nil :group nil
:description 999 :description 999
:is-source 42}] :is-source 42}]
(t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-theme" (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-theme"
(ctob/make-token-theme params)))))) (ctob/make-token-theme params)))))
(t/deftest tokens-lib (t/deftest make-tokens-lib
(t/testing "make-tokens-lib"
(let [tokens-lib (ctob/make-tokens-lib)] (let [tokens-lib (ctob/make-tokens-lib)]
(t/is (= (ctob/set-count tokens-lib) 0)))) (t/is (= (ctob/set-count tokens-lib) 0))))
(t/testing "invalid-tokens-lib" (t/deftest make-invalid-tokens-lib
(let [params {:sets nil :themes nil}] (let [params {:sets nil :themes nil}]
(t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid token sets" (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid token sets"
(ctob/make-tokens-lib params)))))) (ctob/make-tokens-lib params)))))
(t/deftest add-token-set-to-token-lib
(t/testing "token-set in a lib"
(t/deftest add-token-set
(let [tokens-lib (ctob/make-tokens-lib) (let [tokens-lib (ctob/make-tokens-lib)
token-set (ctob/make-token-set :name "test-token-set") token-set (ctob/make-token-set :name "test-token-set")
tokens-lib' (ctob/add-set tokens-lib token-set) tokens-lib' (ctob/add-set tokens-lib token-set)
@ -233,7 +229,7 @@
(t/is (= (first token-sets') token-set)) (t/is (= (first token-sets') token-set))
(t/is (= token-set' token-set)))) (t/is (= token-set' token-set))))
(t/deftest update-token-set (t/deftest update-token-set
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))) (ctob/add-set (ctob/make-token-set :name "test-token-set")))
@ -255,7 +251,7 @@
(t/is (= (:description token-set') "some description")) (t/is (= (:description token-set') "some description"))
(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 rename-token-set (t/deftest rename-token-set
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))) (ctob/add-set (ctob/make-token-set :name "test-token-set")))
@ -272,7 +268,7 @@
(t/is (= (:name token-set') "updated-name")) (t/is (= (:name token-set') "updated-name"))
(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 rename-token-set-group (t/deftest rename-token-set-group
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz")) (ctob/add-set (ctob/make-token-set :name "foo/bar/baz"))
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz/baz-child-1")) (ctob/add-set (ctob/make-token-set :name "foo/bar/baz/baz-child-1"))
@ -290,7 +286,7 @@
"foo/bar-renamed/baz-renamed/baz-child-2"))) "foo/bar-renamed/baz-renamed/baz-child-2")))
(t/is (= expected-theme-sets #{"foo/bar-renamed/baz-renamed/baz-child-1"})))) (t/is (= expected-theme-sets #{"foo/bar-renamed/baz-renamed/baz-child-1"}))))
(t/deftest delete-token-set (t/deftest delete-token-set
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme" :sets #{"test-token-set"}))) (ctob/add-theme (ctob/make-token-theme :name "test-token-theme" :sets #{"test-token-set"})))
@ -306,7 +302,7 @@
(t/is (= (:sets token-theme') #{})) (t/is (= (:sets token-theme') #{}))
(t/is (nil? token-set')))) (t/is (nil? token-set'))))
(t/deftest active-themes-set-names (t/deftest active-themes-set-names
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))) (ctob/add-set (ctob/make-token-set :name "test-token-set")))
@ -317,11 +313,9 @@
token-set' (ctob/get-set tokens-lib' "updated-name")] token-set' (ctob/get-set tokens-lib' "updated-name")]
(t/is (= (ctob/set-count tokens-lib') 0)) (t/is (= (ctob/set-count tokens-lib') 0))
(t/is (nil? token-set'))))) (t/is (nil? token-set'))))
(t/deftest add-token
(t/deftest token-in-a-lib
(t/testing "add-token"
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set"))) (ctob/add-set (ctob/make-token-set :name "test-token-set")))
token (ctob/make-token :name "test-token" token (ctob/make-token :name "test-token"
@ -340,7 +334,7 @@
(t/is (= (:name token') "test-token")) (t/is (= (:name token') "test-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/testing "update-token" (t/deftest update-token
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/add-token-in-set "test-token-set"
@ -381,7 +375,7 @@
(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/is (dt/is-after? (:modified-at token') (:modified-at token))))) (t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/testing "rename-token" (t/deftest rename-token
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/add-token-in-set "test-token-set"
@ -413,7 +407,7 @@
(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/is (dt/is-after? (:modified-at token') (:modified-at token))))) (t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/testing "delete-token" (t/deftest delete-token
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/add-token-in-set "test-token-set"
@ -434,7 +428,7 @@
(t/is (nil? token')) (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/testing "list-active-themes-tokens-in-order" (t/deftest list-active-themes-tokens-in-order
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "out-of-order-theme" (ctob/add-theme (ctob/make-token-theme :name "out-of-order-theme"
;; Out of order sets in theme ;; Out of order sets in theme
@ -461,7 +455,7 @@
(t/is (= '("set-a" "set-b" "inactive-set") expected-order)) (t/is (= '("set-a" "set-b" "inactive-set") expected-order))
(t/is (= ["set-a-token" "set-b-token"] expected-token-names)))) (t/is (= ["set-a-token" "set-b-token"] expected-token-names))))
(t/testing "sets-at-path-active-state" (t/deftest sets-at-path-active-state
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "foo/bar/baz")) (ctob/add-set (ctob/make-token-set :name "foo/bar/baz"))
@ -491,10 +485,9 @@
(t/is (= :none expected-none)) (t/is (= :none expected-none))
(t/is (= :all expected-all)) (t/is (= :all expected-all))
(t/is (= :partial expected-partial)) (t/is (= :partial expected-partial))
(t/is (= :none expected-invalid-none))))) (t/is (= :none expected-invalid-none))))
(t/deftest token-theme-in-a-lib (t/deftest add-token-theme
(t/testing "add-token-theme"
(let [tokens-lib (ctob/make-tokens-lib) (let [tokens-lib (ctob/make-tokens-lib)
token-theme (ctob/make-token-theme :name "test-token-theme") token-theme (ctob/make-token-theme :name "test-token-theme")
tokens-lib' (ctob/add-theme tokens-lib token-theme) tokens-lib' (ctob/add-theme tokens-lib token-theme)
@ -506,7 +499,7 @@
(t/is (= (second token-themes') token-theme)) (t/is (= (second token-themes') token-theme))
(t/is (= token-theme' token-theme)))) (t/is (= token-theme' token-theme))))
(t/testing "update-token-theme" (t/deftest update-token-theme
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))) (ctob/add-theme (ctob/make-token-theme :name "test-token-theme")))
@ -528,7 +521,7 @@
(t/is (= (:description token-theme') "some description")) (t/is (= (:description token-theme') "some description"))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/testing "rename-token-theme" (t/deftest rename-token-theme
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))) (ctob/add-theme (ctob/make-token-theme :name "test-token-theme")))
@ -545,7 +538,7 @@
(t/is (= (:name token-theme') "updated-name")) (t/is (= (:name token-theme') "updated-name"))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/testing "delete-token-theme" (t/deftest delete-token-theme
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))) (ctob/add-theme (ctob/make-token-theme :name "test-token-theme")))
@ -558,7 +551,7 @@
(t/is (= (ctob/theme-count tokens-lib') 1)) (t/is (= (ctob/theme-count tokens-lib') 1))
(t/is (nil? token-theme')))) (t/is (nil? token-theme'))))
(t/testing "toggle-set-in-theme" (t/deftest toggle-set-in-theme
(let [tokens-lib (-> (ctob/make-tokens-lib) (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-1"))
(ctob/add-set (ctob/make-token-set :name "token-set-2")) (ctob/add-set (ctob/make-token-set :name "token-set-2"))
@ -572,11 +565,9 @@
token-theme (ctob/get-theme tokens-lib "" "test-token-theme") token-theme (ctob/get-theme tokens-lib "" "test-token-theme")
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/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/deftest transit-serialization
(t/deftest serialization
(t/testing "transit-serialization"
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (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" (ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token"
@ -591,8 +582,8 @@
(t/is (= (ctob/set-count tokens-lib') 1)) (t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (ctob/theme-count tokens-lib') 2)))) (t/is (= (ctob/theme-count tokens-lib') 2))))
#?(:clj #?(:clj
(t/testing "fressian-serialization" (t/deftest fressian-serialization
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (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" (ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token"
@ -605,10 +596,9 @@
(t/is (ctob/valid-tokens-lib? tokens-lib')) (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') 2)))))) (t/is (= (ctob/theme-count tokens-lib') 2)))))
(t/deftest grouping (t/deftest split-and-join-path
(t/testing "split-and-join"
(let [name "group/subgroup/name" (let [name "group/subgroup/name"
path (ctob/split-path name "/") path (ctob/split-path name "/")
name' (ctob/join-path path "/")] name' (ctob/join-path path "/")]
@ -617,14 +607,14 @@
(t/is (= (nth path 2) "name")) (t/is (= (nth path 2) "name"))
(t/is (= name' name)))) (t/is (= name' name))))
(t/testing "remove-spaces" (t/deftest split-and-join-path-with-spaces
(let [name "group / subgroup / name" (let [name "group / subgroup / name"
path (ctob/split-path name "/")] path (ctob/split-path name "/")]
(t/is (= (first path) "group")) (t/is (= (first path) "group"))
(t/is (= (second path) "subgroup")) (t/is (= (second path) "subgroup"))
(t/is (= (nth path 2) "name")))) (t/is (= (nth path 2) "name"))))
(t/testing "group-and-ungroup" (t/deftest group-and-ungroup-token-set
(let [token-set1 (ctob/make-token-set :name "token-set1") (let [token-set1 (ctob/make-token-set :name "token-set1")
token-set2 (ctob/make-token-set :name "some group/token-set2") token-set2 (ctob/make-token-set :name "some group/token-set2")
@ -637,7 +627,7 @@
(t/is (= (:name token-set1'') "token-set1")) (t/is (= (:name token-set1'') "token-set1"))
(t/is (= (:name token-set2'') "some group/token-set2")))) (t/is (= (:name token-set2'') "some group/token-set2"))))
(t/testing "get-groups-str" (t/deftest get-token-set-groups-str
(let [token-set1 (ctob/make-token-set :name "token-set1") (let [token-set1 (ctob/make-token-set :name "token-set1")
token-set2 (ctob/make-token-set :name "some-group/token-set2") token-set2 (ctob/make-token-set :name "some-group/token-set2")
token-set3 (ctob/make-token-set :name "some-group/some-subgroup/token-set3")] token-set3 (ctob/make-token-set :name "some-group/some-subgroup/token-set3")]
@ -645,7 +635,7 @@
(t/is (= (ctob/get-groups-str token-set2 "/") "some-group")) (t/is (= (ctob/get-groups-str token-set2 "/") "some-group"))
(t/is (= (ctob/get-groups-str token-set3 "/") "some-group/some-subgroup")))) (t/is (= (ctob/get-groups-str token-set3 "/") "some-group/some-subgroup"))))
(t/testing "get-final-name" (t/deftest get-token-set-final-name
(let [token-set1 (ctob/make-token-set :name "token-set1") (let [token-set1 (ctob/make-token-set :name "token-set1")
token-set2 (ctob/make-token-set :name "some-group/token-set2") token-set2 (ctob/make-token-set :name "some-group/token-set2")
token-set3 (ctob/make-token-set :name "some-group/some-subgroup/token-set3")] token-set3 (ctob/make-token-set :name "some-group/some-subgroup/token-set3")]
@ -653,8 +643,7 @@
(t/is (= (ctob/get-final-name token-set2 "/") "token-set2")) (t/is (= (ctob/get-final-name token-set2 "/") "token-set2"))
(t/is (= (ctob/get-final-name token-set3 "/") "token-set3")))) (t/is (= (ctob/get-final-name token-set3 "/") "token-set3"))))
(t/testing "grouped tokens" (t/deftest add-tokens-in-set
(t/testing "grouped-tokens"
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/add-token-in-set "test-token-set"
@ -688,7 +677,7 @@
(t/is (= (:name (nth tokens-list 3)) "group1.subgroup11.token4")) (t/is (= (:name (nth tokens-list 3)) "group1.subgroup11.token4"))
(t/is (= (:name (nth tokens-list 4)) "group2.token5")))) (t/is (= (:name (nth tokens-list 4)) "group2.token5"))))
(t/testing "update-token-in-groups" (t/deftest update-token-in-sets
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/add-token-in-set "test-token-set"
@ -723,7 +712,8 @@
(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/is (dt/is-after? (:modified-at token') (:modified-at token))))) (t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/testing "rename-token-in-groups"
(t/deftest update-token-in-sets-rename
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/add-token-in-set "test-token-set"
@ -757,7 +747,7 @@
(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/is (dt/is-after? (:modified-at token') (:modified-at token))))) (t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/testing "move-token-of-group" (t/deftest move-token-of-group
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/add-token-in-set "test-token-set"
@ -792,7 +782,7 @@
(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/is (dt/is-after? (:modified-at token') (:modified-at token))))) (t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
(t/testing "delete-token-in-group" (t/deftest delete-token-in-group
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "test-token-set")) (ctob/add-set (ctob/make-token-set :name "test-token-set"))
(ctob/add-token-in-set "test-token-set" (ctob/add-token-in-set "test-token-set"
@ -813,10 +803,9 @@
(t/is (= (ctob/set-count tokens-lib') 1)) (t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (count (:tokens token-set')) 1)) (t/is (= (count (:tokens token-set')) 1))
(t/is (nil? token')) (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/testing "grouped sets" (t/deftest add-token-set-with-groups
(t/testing "grouped-sets"
(let [tokens-lib (-> (ctob/make-tokens-lib) (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-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2")) (ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))
@ -875,7 +864,7 @@
(t/is (= (ctob/group? (second node-set5)) false)) (t/is (= (ctob/group? (second node-set5)) false))
(t/is (= (:name (second node-set5)) "group2/token-set-5")))) (t/is (= (:name (second node-set5)) "group2/token-set-5"))))
(t/testing "update-set-in-groups" (t/deftest update-token-set-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib) (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-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2")) (ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))
@ -901,7 +890,7 @@
(t/is (= (:description token-set') "some description")) (t/is (= (:description token-set') "some description"))
(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/testing "rename-set-in-groups" (t/deftest rename-token-set-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib) (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-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2")) (ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))
@ -926,11 +915,9 @@
(t/is (= (d/index-of (keys group1') "S-updated-name") 0)) (t/is (= (d/index-of (keys group1') "S-updated-name") 0))
(t/is (= (:name token-set') "group1/updated-name")) (t/is (= (:name token-set') "group1/updated-name"))
(t/is (= (:description token-set') "")) (t/is (= (:description token-set') ""))
(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)))))
sets-tree'))
(t/deftest move-token-set-of-group
(t/testing "move-set-of-group"
(let [tokens-lib (-> (ctob/make-tokens-lib) (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-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2")) (ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))
@ -959,7 +946,7 @@
(t/is (= (:description token-set') "")) (t/is (= (:description token-set') ""))
(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/testing "delete-set-in-group" (t/deftest delete-token-set-in-group
(let [tokens-lib (-> (ctob/make-tokens-lib) (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-1"))
(ctob/add-set (ctob/make-token-set :name "group1/token-set-2"))) (ctob/add-set (ctob/make-token-set :name "group1/token-set-2")))
@ -972,10 +959,9 @@
(t/is (= (ctob/set-count tokens-lib') 1)) (t/is (= (ctob/set-count tokens-lib') 1))
(t/is (= (count sets-tree') 1)) (t/is (= (count sets-tree') 1))
(t/is (nil? token-set'))))) (t/is (nil? token-set'))))
(t/testing "grouped themes" (t/deftest add-theme-with-groups
(t/testing "grouped-themes"
(let [tokens-lib (-> (ctob/make-tokens-lib) (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 "" :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-2"))
@ -1037,7 +1023,7 @@
(t/is (= (ctob/group? (second node-theme4)) false)) (t/is (= (ctob/group? (second node-theme4)) false))
(t/is (= (:name (second node-theme4)) "token-theme-4")))) (t/is (= (:name (second node-theme4)) "token-theme-4"))))
(t/testing "update-theme-in-groups" (t/deftest update-token-theme-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib) (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 "" :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-2"))
@ -1063,7 +1049,7 @@
(t/is (= (:description token-theme') "some description")) (t/is (= (:description token-theme') "some description"))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/testing "get-theme-groups" (t/deftest get-token-theme-groups
(let [token-lib (-> (ctob/make-tokens-lib) (let [token-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 "" :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-2"))
@ -1072,7 +1058,7 @@
token-groups (ctob/get-theme-groups token-lib)] token-groups (ctob/get-theme-groups token-lib)]
(t/is (= token-groups ["group1" "group2"])))) (t/is (= token-groups ["group1" "group2"]))))
(t/testing "rename-theme-in-groups" (t/deftest rename-token-theme-in-groups
(let [tokens-lib (-> (ctob/make-tokens-lib) (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 "" :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-2"))
@ -1100,7 +1086,7 @@
(t/is (= (:description token-theme') "")) (t/is (= (:description token-theme') ""))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/testing "move-theme-of-group" (t/deftest move-token-theme-of-group
(let [tokens-lib (-> (ctob/make-tokens-lib) (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 "" :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-2"))
@ -1130,7 +1116,7 @@
(t/is (= (:description token-theme') "")) (t/is (= (:description token-theme') ""))
(t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme)))))
(t/testing "delete-theme-in-group" (t/deftest delete-token-theme-in-group
(let [tokens-lib (-> (ctob/make-tokens-lib) (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 "" :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-2")))
@ -1143,11 +1129,10 @@
(t/is (= (ctob/theme-count tokens-lib') 2)) (t/is (= (ctob/theme-count tokens-lib') 2))
(t/is (= (count themes-tree') 1)) (t/is (= (count themes-tree') 1))
(t/is (nil? token-theme')))))) (t/is (nil? token-theme'))))
#?(:clj #?(:clj
(t/deftest legacy-json-decoding (t/deftest legacy-json-decoding
(t/testing "decode-legacy-json"
(let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-legacy-example.json") (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-legacy-example.json")
(tr/decode-str)) (tr/decode-str))
lib (ctob/decode-legacy-json (ctob/ensure-tokens-lib nil) json) lib (ctob/decode-legacy-json (ctob/ensure-tokens-lib nil) json)
@ -1178,11 +1163,10 @@
:value "{accent.default}" :value "{accent.default}"
:description ""}))) :description ""})))
(t/testing "invalid tokens got discarded" (t/testing "invalid tokens got discarded"
(t/is (nil? (get-set-token "typography" "H1.Bold")))))))) (t/is (nil? (get-set-token "typography" "H1.Bold")))))))
#?(:clj #?(:clj
(t/deftest dtcg-encoding-decoding (t/deftest dtcg-encoding-decoding-json
(t/testing "decode-dtcg-json"
(let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-example.json") (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-example.json")
(tr/decode-str)) (tr/decode-str))
lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json) lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json)
@ -1212,9 +1196,10 @@
:value "{accent.default}" :value "{accent.default}"
:description ""}))) :description ""})))
(t/testing "invalid tokens got discarded" (t/testing "invalid tokens got discarded"
(t/is (nil? (get-set-token "typography" "H1.Bold")))))) (t/is (nil? (get-set-token "typography" "H1.Bold")))))))
(t/testing "decode-dtcg-json-default-team" #?(:clj
(t/deftest decode-dtcg-json-default-team
(let [json (-> (slurp "test/common_tests/types/data/tokens-default-team-only.json") (let [json (-> (slurp "test/common_tests/types/data/tokens-default-team-only.json")
(tr/decode-str)) (tr/decode-str))
lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json) lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json)
@ -1233,9 +1218,11 @@
{:name "small" {:name "small"
:value "8" :value "8"
:type :border-radius :type :border-radius
:description ""}))))) :description ""}))))))
(t/testing "encode-dtcg-json"
#?(:clj
(t/deftest encode-dtcg-json
(let [now (dt/now) (let [now (dt/now)
tokens-lib (-> (ctob/make-tokens-lib) tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "core" (ctob/add-set (ctob/make-token-set :name "core"
@ -1283,10 +1270,10 @@
{"primary" {"background" {"$value" "{accent.default}" {"primary" {"background" {"$value" "{accent.default}"
"$type" "color" "$type" "color"
"$description" ""}}}}}] "$description" ""}}}}}]
(t/is (= expected result)))))
(t/is (= expected result)))) #?(:clj
(t/deftest encode-decode-dtcg-json
(t/testing "encode-decode-dtcg-json"
(with-redefs [dt/now (constantly #inst "2024-10-16T12:01:20.257840055-00:00")] (with-redefs [dt/now (constantly #inst "2024-10-16T12:01:20.257840055-00:00")]
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "core" (ctob/add-set (ctob/make-token-set :name "core"
@ -1314,9 +1301,10 @@
(t/is (not= with-prev-tokens-lib tokens-lib)) (t/is (not= with-prev-tokens-lib tokens-lib))
(t/is (= @with-prev-tokens-lib @tokens-lib))) (t/is (= @with-prev-tokens-lib @tokens-lib)))
(t/testing "fresh tokens library is also equal" (t/testing "fresh tokens library is also equal"
(= @with-empty-tokens-lib @tokens-lib))))) (= @with-empty-tokens-lib @tokens-lib))))))
(t/testing "encode-default-theme-json" #?(:clj
(t/deftest encode-default-theme-json
(let [tokens-lib (-> (ctob/make-tokens-lib) (let [tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "core" (ctob/add-set (ctob/make-token-set :name "core"
:tokens {"colors.red.600" :tokens {"colors.red.600"
@ -1353,9 +1341,10 @@
"$type" "color" "$type" "color"
"$description" ""}}}}}] "$description" ""}}}}}]
(t/is (= expected result)))) (t/is (= expected result)))))
(t/testing "encode-dtcg-json-with-active-theme-and-set" #?(:clj
(t/deftest encode-dtcg-json-with-active-theme-and-set
(let [now (dt/now) (let [now (dt/now)
tokens-lib (-> (ctob/make-tokens-lib) tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :name "core" (ctob/add-set (ctob/make-token-set :name "core"
@ -1405,4 +1394,4 @@
{"primary" {"background" {"$value" "{accent.default}" {"primary" {"background" {"$value" "{accent.default}"
"$type" "color" "$type" "color"
"$description" ""}}}}}] "$description" ""}}}}}]
(t/is (= expected result)))))) (t/is (= expected result)))))

View file

@ -127,7 +127,7 @@
(wtu/update-workspace-tokens)))))) (wtu/update-workspace-tokens))))))
(defn create-token-set (defn create-token-set
[set-name token-set] [set-name]
(ptk/reify ::create-token-set (ptk/reify ::create-token-set
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
@ -136,17 +136,20 @@
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it state _]
(let [token-set' (-> token-set (let [data (dsh/lookup-file-data state)
(update :name #(if (empty? %) tokens-lib (get data :tokens-lib)
set-name set-name (ctob/normalize-set-name set-name)]
(ctob/join-set-path [% set-name])))) (if (and tokens-lib (ctob/get-set tokens-lib set-name))
data (dsh/lookup-file-data state) (rx/of (ntf/show {:content (tr "errors.token-set-already-exists")
token-set-name (:name token-set') :type :toast
:level :error
:timeout 9000}))
(let [token-set (ctob/make-token-set :name set-name)
changes (-> (pcb/empty-changes it) changes (-> (pcb/empty-changes it)
(pcb/with-library-data data) (pcb/with-library-data data)
(pcb/set-token-set token-set-name false token-set'))] (pcb/set-token-set set-name false token-set))]
(rx/of (set-selected-token-set-name token-set-name) (rx/of (set-selected-token-set-name set-name)
(dch/commit-changes changes)))))) (dch/commit-changes changes))))))))
(defn rename-token-set-group [set-group-path set-group-fname] (defn rename-token-set-group [set-group-path set-group-fname]
(ptk/reify ::rename-token-set-group (ptk/reify ::rename-token-set-group
@ -157,17 +160,25 @@
(rx/of (rx/of
(dch/commit-changes changes)))))) (dch/commit-changes changes))))))
(defn update-token-set [set-name token-set] (defn update-token-set
[token-set name]
(ptk/reify ::update-token-set (ptk/reify ::update-token-set
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it state _]
(let [data (dsh/lookup-file-data state) (let [data (dsh/lookup-file-data state)
changes (-> (pcb/empty-changes it) name (ctob/normalize-set-name name (:name token-set))
tokens-lib (get data :tokens-lib)]
(if (ctob/get-set tokens-lib name)
(rx/of (ntf/show {:content (tr "errors.token-set-already-exists")
:type :toast
:level :error
:timeout 9000}))
(let [changes (-> (pcb/empty-changes it)
(pcb/with-library-data data) (pcb/with-library-data data)
(pcb/set-token-set set-name false token-set))] (pcb/rename-token-set (:name token-set) name))]
(rx/of (rx/of (set-selected-token-set-name (:name token-set))
(set-selected-token-set-name (:name token-set)) (dch/commit-changes changes))))))))
(dch/commit-changes changes))))))
(defn toggle-token-set (defn toggle-token-set
[name] [name]
@ -224,8 +235,8 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ _] (watch [_ _ _]
(let [content (case error (let [content (case error
:path-exists (tr "errors.drag-drop.set-exists" to-path) :path-exists (tr "errors.token-set-exists-on-drop" to-path)
:parent-to-child (tr "errors.drag-drop.parent-to-child") :parent-to-child (tr "errors.drop-token-set-parent-to-child")
nil)] nil)]
(when content (when content
(rx/of (rx/of
@ -243,7 +254,7 @@
(rx/of (rx/of
(dch/commit-changes changes) (dch/commit-changes changes)
(wtu/update-workspace-tokens))) (wtu/update-workspace-tokens)))
(catch js/Error e (catch :default e
(rx/of (rx/of
(drop-error (ex-data e)))))))) (drop-error (ex-data e))))))))
@ -255,7 +266,7 @@
(when-let [changes (clt/generate-move-token-set (pcb/empty-changes it) (get-tokens-lib state) drop-opts)] (when-let [changes (clt/generate-move-token-set (pcb/empty-changes it) (get-tokens-lib state) drop-opts)]
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(wtu/update-workspace-tokens))) (wtu/update-workspace-tokens)))
(catch js/Error e (catch :default e
(rx/of (rx/of
(drop-error (ex-data e)))))))) (drop-error (ex-data e))))))))

View file

@ -293,11 +293,12 @@
:on-save-form on-save-form :on-save-form on-save-form
:disabled? disabled?}]]]]])) :disabled? disabled?}]]]]]))
(defn- make-lib-with-theme [theme sets] (defn- make-lib-with-theme
(-> (ctob/make-tokens-lib) [theme sets]
(ctob/add-theme theme) (let [tlib (-> (ctob/make-tokens-lib)
(ctob/add-sets sets) (ctob/add-theme theme))
(ctob/activate-theme (:group theme) (:name theme)))) tlib (reduce ctob/add-set tlib sets)]
(ctob/activate-theme tlib (:group theme) (:name theme))))
(mf/defc controlled-edit-theme (mf/defc controlled-edit-theme
[{:keys [state set-state]}] [{:keys [state set-state]}]

View file

@ -43,17 +43,27 @@
(st/emit! (dt/set-selected-token-set-name name))) (st/emit! (dt/set-selected-token-set-name name)))
(defn on-update-token-set (defn on-update-token-set
[name token-set] [token-set name]
(st/emit! (dt/clear-token-set-edition) (st/emit! (dt/clear-token-set-edition)
(dt/update-token-set (:name token-set) (ctob/update-name token-set name)))) (dt/update-token-set token-set name)))
(defn- on-update-token-set-group [path name] (defn- on-update-token-set-group
[path name]
(st/emit! (dt/clear-token-set-edition) (st/emit! (dt/clear-token-set-edition)
(dt/rename-token-set-group path name))) (dt/rename-token-set-group path name)))
(defn- on-create-token-set [name token-set] (defn- on-create-token-set
[parent-set name]
(let [;; FIXME: this code should be reusable under helper under
;; common types namespace
name
(if-let [parent-path (ctob/get-token-set-path parent-set)]
(->> (concat parent-path (ctob/split-token-set-name name))
(ctob/join-set-path))
(ctob/normalize-set-name name))]
(st/emit! (ptk/data-event ::ev/event {::ev/name "create-token-set" :name name}) (st/emit! (ptk/data-event ::ev/event {::ev/name "create-token-set" :name name})
(dt/create-token-set name token-set))) (dt/create-token-set name))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; COMPONENTS ;; COMPONENTS
@ -62,13 +72,11 @@
(mf/defc editing-label* (mf/defc editing-label*
{::mf/private true} {::mf/private true}
[{:keys [default-value on-cancel on-submit]}] [{:keys [default-value on-cancel on-submit]}]
(let [ref (mf/use-ref) (let [on-submit
on-submit-valid
(mf/use-fn (mf/use-fn
(mf/deps on-cancel on-submit default-value) (mf/deps on-cancel on-submit default-value)
(fn [event] (fn [event]
(let [value (str/trim (dom/get-target-val event))] (let [value (dom/get-target-val event)]
(if (or (str/empty? value) (if (or (str/empty? value)
(= value default-value)) (= value default-value))
(on-cancel) (on-cancel)
@ -76,16 +84,15 @@
on-key-down on-key-down
(mf/use-fn (mf/use-fn
(mf/deps on-submit-valid on-cancel) (mf/deps on-submit on-cancel)
(fn [event] (fn [event]
(cond (cond
(kbd/enter? event) (on-submit-valid event) (kbd/enter? event) (on-submit event)
(kbd/esc? event) (on-cancel))))] (kbd/esc? event) (on-cancel))))]
[:input [:input
{:class (stl/css :editing-node) {:class (stl/css :editing-node)
:type "text" :type "text"
:ref ref :on-blur on-submit
:on-blur on-submit-valid
:on-key-down on-key-down :on-key-down on-key-down
:auto-focus true :auto-focus true
:placeholder (tr "workspace.token.set-edit-placeholder") :placeholder (tr "workspace.token.set-edit-placeholder")
@ -234,6 +241,7 @@
(mf/defc sets-tree-set* (mf/defc sets-tree-set*
[{:keys [id set label tree-depth tree-path tree-index is-selected is-active is-draggable is-editing [{:keys [id set label tree-depth tree-path tree-index is-selected is-active is-draggable is-editing
on-select on-drop on-toggle on-start-edition on-reset-edition on-edit-submit]}] on-select on-drop on-toggle on-start-edition on-reset-edition on-edit-submit]}]
(let [set-name (get set :name) (let [set-name (get set :name)
can-edit? (mf/use-ctx ctx/can-edit?) can-edit? (mf/use-ctx ctx/can-edit?)
@ -273,7 +281,7 @@
on-edit-submit' on-edit-submit'
(mf/use-fn (mf/use-fn
(mf/deps set on-edit-submit) (mf/deps set on-edit-submit)
#(on-edit-submit % set)) #(on-edit-submit set %))
on-drag on-drag
(mf/use-fn (mf/use-fn

View file

@ -1160,11 +1160,14 @@ msgid "errors.clipboard-not-implemented"
msgstr "Your browser cannot do this operation" msgstr "Your browser cannot do this operation"
#: src/app/main/data/tokens.cljs:199 #: src/app/main/data/tokens.cljs:199
msgid "errors.drag-drop.parent-to-child" msgid "errors.drop-token-set-parent-to-child"
msgstr "Cannot drop a parent set to an own child path." msgstr "Cannot drop a parent set to an own child path."
msgid "errors.token-set-already-exists"
msgstr "A set with the same name already exists"
#: src/app/main/data/tokens.cljs:198 #: src/app/main/data/tokens.cljs:198
msgid "errors.drag-drop.set-exists" msgid "errors.token-set-exists-on-drop"
msgstr "Cannot complete drop, a set with same name already exists at path %s." msgstr "Cannot complete drop, a set with same name already exists at path %s."
#: src/app/main/data/tokens.cljs:294 #: src/app/main/data/tokens.cljs:294

View file

@ -7182,3 +7182,6 @@ msgstr "Soporte de Plugins"
msgid "loader.tips.10.message" msgid "loader.tips.10.message"
msgstr "Extiende Penpot con plugins creados por la comunidad para funcionalidad extra." msgstr "Extiende Penpot con plugins creados por la comunidad para funcionalidad extra."
msgid "errors.token-set-already-exists"
msgstr "Ya existe un set con el mismo nombre"