From a9e8d8f8f7cb4a54709a8d11b7ed1b5a740e0ff0 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 11:52:50 +0100 Subject: [PATCH 01/11] :sparkles: Make the calculate-move-token-set-or-set-group fn private --- common/src/app/common/logic/tokens.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/app/common/logic/tokens.cljc b/common/src/app/common/logic/tokens.cljc index 4c63afac7b..84f2c3b7fc 100644 --- a/common/src/app/common/logic/tokens.cljc +++ b/common/src/app/common/logic/tokens.cljc @@ -44,7 +44,7 @@ (defn vec-starts-with? [v1 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] :or {collapsed-paths #{}}}] (let [tree (-> (ctob/get-set-tree tokens-lib) From 559dcabf0ec12bbe041f235e8238e17e9074229c Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 11:53:09 +0100 Subject: [PATCH 02/11] :sparkles: Normalize token name on creation --- common/src/app/common/types/tokens_lib.cljc | 6 +++++ frontend/src/app/main/data/tokens.cljs | 29 ++++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 2a996eea36..953ca554fc 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -251,6 +251,12 @@ [name] (split-path name set-separator)) +(defn normalize-set-name + [name] + (->> (split-token-set-name name) + (map str/trim) + (str/join set-separator))) + (defn get-token-set-path [token-set] (let [path (get-path token-set set-separator)] (add-token-set-paths-prefix path))) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index 0b178e73a4..f30c0563f8 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -136,15 +136,26 @@ ptk/WatchEvent (watch [it state _] - (let [token-set' (-> token-set - (update :name #(if (empty? %) - set-name - (ctob/join-set-path [% set-name])))) - data (dsh/lookup-file-data state) - token-set-name (:name token-set') - changes (-> (pcb/empty-changes it) - (pcb/with-library-data data) - (pcb/set-token-set token-set-name false token-set'))] + (let [token-set' + ;; FIXME: wtf is this? + (update token-set :name #(if (empty? %) + set-name + (ctob/join-set-path [% set-name]))) + + token-set' + (update token-set' :name ctob/normalize-set-name) + + data + (dsh/lookup-file-data state) + + token-set-name + (:name token-set') + + changes + (-> (pcb/empty-changes it) + (pcb/with-library-data data) + (pcb/set-token-set token-set-name false token-set'))] + (rx/of (set-selected-token-set-name token-set-name) (dch/commit-changes changes)))))) From 1965490bee5b9385f3207593f9f413fc93c6a054 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 11:53:25 +0100 Subject: [PATCH 03/11] :paperclip: Use proper catch matching on tokens drop operation --- frontend/src/app/main/data/tokens.cljs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index f30c0563f8..6c5ca8fdce 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -254,7 +254,7 @@ (rx/of (dch/commit-changes changes) (wtu/update-workspace-tokens))) - (catch js/Error e + (catch :default e (rx/of (drop-error (ex-data e)))))))) @@ -266,7 +266,7 @@ (when-let [changes (clt/generate-move-token-set (pcb/empty-changes it) (get-tokens-lib state) drop-opts)] (rx/of (dch/commit-changes changes) (wtu/update-workspace-tokens))) - (catch js/Error e + (catch :default e (rx/of (drop-error (ex-data e)))))))) From 096b685e2c615839dbfc591747c8f84590845cbb Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 15:10:52 +0100 Subject: [PATCH 04/11] :bug: Prevent token-set overwrite on creation and edition --- common/src/app/common/files/changes.cljc | 1 - .../src/app/common/files/changes_builder.cljc | 23 +- common/src/app/common/types/tokens_lib.cljc | 74 +- .../common_tests/types/tokens_lib_test.cljc | 2569 ++++++++--------- frontend/src/app/main/data/tokens.cljs | 61 +- .../app/main/ui/workspace/tokens/sets.cljs | 38 +- 6 files changed, 1397 insertions(+), 1369 deletions(-) diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index fce5acf55d..1ef5f483da 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -387,7 +387,6 @@ [:set-group-path [:vector :string]] [:set-group-fname :string]]] - [:move-token-set-before [:map {:title "MoveTokenSetBefore"} [:type [:= :move-token-set-before]] diff --git a/common/src/app/common/files/changes_builder.cljc b/common/src/app/common/files/changes_builder.cljc index bfb7ee6994..a4ceb41eb0 100644 --- a/common/src/app/common/files/changes_builder.cljc +++ b/common/src/app/common/files/changes_builder.cljc @@ -875,9 +875,28 @@ :token nil})) (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)) + (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) + (let [library-data (::library-data (meta changes)) prev-token-set (some-> (get library-data :tokens-lib) (ctob/get-set set-name))] (-> changes diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 953ca554fc..0e2a331706 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -27,14 +27,17 @@ (def valid-groupable-item? (sm/validator schema:groupable-item)) +(def xf-map-trim + (comp + (map str/trim) + (remove str/empty?))) + (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)))) + (->> (str/split path separator) + (into [] xf-map-trim) + (not-empty))) (defn split-path-name [s separator] (let [[path name] (str/split s (re-pattern (str "\\" separator)) 2)] @@ -61,10 +64,12 @@ (join-path separator)))) (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] (assert (valid-groupable-item? item) "expected groupable item") - (split-path (:name item) separator)) + (->> (split-path (:name item) separator) + (not-empty))) (defn get-groups-str "Get the groups part of the name. E.g. group.subgroup.name -> group.subgroup" @@ -97,14 +102,9 @@ (def token-separator ".") -(defn get-token-path [path] - (get-path path 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)) +(defn get-token-path + [token] + (get-path token token-separator)) (defrecord Token [name type value description modified-at]) @@ -247,28 +247,38 @@ set-name (add-set-prefix (last paths))] (conj set-path set-name))) +(defn get-token-set-path + [token-set] + (get-path token-set set-separator)) + (defn split-token-set-name [name] (split-path name set-separator)) +;; (defn rename-token-set-preserving-group +;; [token-set name] +;; (let [base (butlast (get-path token-set)) + + (defn normalize-set-name - [name] - (->> (split-token-set-name name) - (map str/trim) - (str/join set-separator))) + "Normalize a set name. -(defn get-token-set-path [token-set] - (let [path (get-path token-set set-separator)] - (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 [name] (-> (split-token-set-name name) (peek))) -(defn split-token-set-path [token-set-path] - (split-path token-set-path set-separator)) - (defn set-name->prefixed-full-path [name-str] (-> (split-token-set-name name-str) (set-full-path->set-prefixed-full-path))) @@ -297,7 +307,7 @@ [tokens & {:keys [update-token-fn] :or {update-token-fn identity}}] (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)))) {} tokens)) @@ -309,8 +319,8 @@ (reduce (fn [acc [_ token]] (let [temp-id (random-uuid) - token (assoc token :temp/id temp-id) - path (split-token-path (:name token))] + token (assoc token :temp/id temp-id) + path (get-token-path token)] (-> acc (assoc-in (concat [:tokens-tree] path) token) (assoc-in [:ids temp-id] token)))) @@ -378,6 +388,7 @@ (get-tokens-tree [_] (tokens-tree tokens)) + ;; FIXME: looks redundant (get-dtcg-tokens-tree [_] (tokens-tree tokens :update-token-fn (fn [token] (cond-> {"$value" (:value token) @@ -926,7 +937,7 @@ Will return a value that matches this schema: active-themes))) (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) child-set-names (->> (get-sets-at-path this path) (map :name) @@ -1268,14 +1279,17 @@ Will return a value that matches this schema: (tree-seq d/ordered-map? vals themes)) ;; Active themes without exposing hidden penpot theme active-themes-clear (disj active-themes hidden-token-theme-path) + name-set-tuples (->> sets (tree-seq d/ordered-map? vals) (filter (partial instance? TokenSet)) (map (fn [token-set] [(:name token-set) (get-dtcg-tokens-tree token-set)]))) - ordered-set-names (map first name-set-tuples) + ordered-set-names (mapv first name-set-tuples) sets (into {} name-set-tuples) active-sets (get-active-themes-set-names this)] + + (-> sets (assoc "$themes" themes) (assoc-in ["$metadata" "tokenSetOrder"] ordered-set-names) diff --git a/common/test/common_tests/types/tokens_lib_test.cljc b/common/test/common_tests/types/tokens_lib_test.cljc index 3845227182..d568240110 100644 --- a/common/test/common_tests/types/tokens_lib_test.cljc +++ b/common/test/common_tests/types/tokens_lib_test.cljc @@ -22,72 +22,70 @@ (t/use-fixtures :once setup-virtual-time) -(t/deftest tokens - (t/testing "make-token" - (let [now (dt/now) - token1 (ctob/make-token :name "test-token-1" - :type :boolean - :value true) - token2 (ctob/make-token :name "test-token-2" - :type :numeric - :value 66 - :description "test description" - :modified-at now)] +(t/deftest make-token + (let [now (dt/now) + token1 (ctob/make-token :name "test-token-1" + :type :boolean + :value true) + token2 (ctob/make-token :name "test-token-2" + :type :numeric + :value 66 + :description "test description" + :modified-at now)] - (t/is (= (:name token1) "test-token-1")) - (t/is (= (:type token1) :boolean)) - (t/is (= (:value token1) true)) - (t/is (= (:description token1) "")) - (t/is (some? (:modified-at token1))) - (t/is (ctob/check-token token1)) + (t/is (= (:name token1) "test-token-1")) + (t/is (= (:type token1) :boolean)) + (t/is (= (:value token1) true)) + (t/is (= (:description token1) "")) + (t/is (some? (:modified-at token1))) + (t/is (ctob/check-token token1)) - (t/is (= (:name token2) "test-token-2")) - (t/is (= (:type token2) :numeric)) - (t/is (= (:value token2) 66)) - (t/is (= (:description token2) "test description")) - (t/is (= (:modified-at token2) now)) - (t/is (ctob/check-token token2)))) + (t/is (= (:name token2) "test-token-2")) + (t/is (= (:type token2) :numeric)) + (t/is (= (:value token2) 66)) + (t/is (= (:description token2) "test description")) + (t/is (= (:modified-at token2) now)) + (t/is (ctob/check-token token2)))) - (t/testing "invalid-tokens" - (let [params {:name 777 :type :invalid}] - (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token" - (ctob/make-token params))))) +(t/deftest make-invalid-token + (let [params {:name 777 :type :invalid}] + (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token" + (ctob/make-token params))))) - (t/testing "find-token-value-references" - (t/testing "finds references inside curly braces in a string" - (t/is (= #{"foo" "bar"} (ctob/find-token-value-references "{foo} + {bar}"))) - (t/testing "ignores extra text" - (t/is (= #{"foo.bar.baz"} (ctob/find-token-value-references "{foo.bar.baz} + something"))))) - (t/testing "ignores string without references" - (t/is (nil? (ctob/find-token-value-references "1 + 2")))) - (t/testing "handles edge-case for extra curly braces" - (t/is (= #{"foo" "bar"} (ctob/find-token-value-references "{foo}} + {bar}")))))) +(t/deftest find-token-value-references + (t/testing "finds references inside curly braces in a string" + (t/is (= #{"foo" "bar"} (ctob/find-token-value-references "{foo} + {bar}"))) + (t/testing "ignores extra text" + (t/is (= #{"foo.bar.baz"} (ctob/find-token-value-references "{foo.bar.baz} + something"))))) + (t/testing "ignores string without references" + (t/is (nil? (ctob/find-token-value-references "1 + 2")))) + (t/testing "handles edge-case for extra curly braces" + (t/is (= #{"foo" "bar"} (ctob/find-token-value-references "{foo}} + {bar}"))))) -(t/deftest token-set - (t/testing "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" - :description "test description" - :modified-at now - :tokens [])] +(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" + :description "test description" + :modified-at now + :tokens [])] - (t/is (= (:name token-set1) "test-token-set-1")) - (t/is (= (:description token-set1) "")) - (t/is (some? (:modified-at token-set1))) - (t/is (empty? (:tokens token-set1))) - (t/is (= (:name token-set2) "test-token-set-2")) - (t/is (= (:description token-set2) "test description")) - (t/is (= (:modified-at token-set2) now)) - (t/is (empty? (:tokens token-set2))))) + (t/is (= (:name token-set1) "test-token-set-1")) + (t/is (= (:description token-set1) "")) + (t/is (some? (:modified-at token-set1))) + (t/is (empty? (:tokens token-set1))) + (t/is (= (:name token-set2) "test-token-set-2")) + (t/is (= (:description token-set2) "test description")) + (t/is (= (:modified-at token-set2) now)) + (t/is (empty? (:tokens token-set2))))) - (t/testing "invalid-token-set" - (let [params {:name 777 :description 999}] - (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-set" - (ctob/make-token-set params))))) +(t/deftest make-invalid-token-set + (let [params {:name 777 :description 999}] + (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-set" + (ctob/make-token-set params))))) - (t/testing "move-token-set" - (t/testing "flat" +(t/deftest move-token-set + (t/testing "flat" (let [tokens-lib (-> (ctob/make-tokens-lib) (ctob/add-set (ctob/make-token-set :name "A")) (ctob/add-set (ctob/make-token-set :name "B")) @@ -105,1218 +103,1178 @@ (t/testing "move to bottom" (t/is (= ["A" "B" "Move"] (move ["Move"] ["Move"] nil false)))))) - (t/testing "nested" - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "Foo/Baz")) - (ctob/add-set (ctob/make-token-set :name "Foo/Bar")) - (ctob/add-set (ctob/make-token-set :name "Foo"))) - move (fn [from-path to-path before-path before-group?] - (->> (ctob/move-set tokens-lib from-path to-path before-path before-group?) - (ctob/get-ordered-set-names) - (into [])))] - (t/testing "move outside of group" - (t/is (= ["Foo/Baz" "Bar" "Foo"] (move ["Foo" "Bar"] ["Bar"] ["Foo"] false))) - (t/is (= ["Bar" "Foo/Baz" "Foo"] (move ["Foo" "Bar"] ["Bar"] ["Foo" "Baz"] true))) - (t/is (= ["Foo/Baz" "Foo" "Bar"] (move ["Foo" "Bar"] ["Bar"] nil false)))) + (t/testing "nested" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "Foo/Baz")) + (ctob/add-set (ctob/make-token-set :name "Foo/Bar")) + (ctob/add-set (ctob/make-token-set :name "Foo"))) + move (fn [from-path to-path before-path before-group?] + (->> (ctob/move-set tokens-lib from-path to-path before-path before-group?) + (ctob/get-ordered-set-names) + (into [])))] + (t/testing "move outside of group" + (t/is (= ["Foo/Baz" "Bar" "Foo"] (move ["Foo" "Bar"] ["Bar"] ["Foo"] false))) + (t/is (= ["Bar" "Foo/Baz" "Foo"] (move ["Foo" "Bar"] ["Bar"] ["Foo" "Baz"] true))) + (t/is (= ["Foo/Baz" "Foo" "Bar"] (move ["Foo" "Bar"] ["Bar"] nil false)))) - (t/testing "move inside of group" - (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/testing "move inside of group" + (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/testing "updates theme set names" - (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 "Other")) - (ctob/add-theme (ctob/make-token-theme :name "Theme" - :sets #{"Foo/Bar/Baz"})) - (ctob/move-set ["Foo" "Bar" "Baz"] ["Other/Baz"] nil nil))] + ;; FIXME + (t/testing "updates theme set names" + (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 "Other")) + (ctob/add-theme (ctob/make-token-theme :name "Theme" + :sets #{"Foo/Bar/Baz"})) + (ctob/move-set ["Foo" "Bar" "Baz"] ["Other/Baz"] nil nil))] (t/is (= #{"Other/Baz"} (:sets (ctob/get-theme tokens-lib "" "Theme"))))))) - (t/testing "move-token-set-group" - (t/testing "reordering" - (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/B")) - (ctob/add-set (ctob/make-token-set :name "Bar/Foo")) - (ctob/add-theme (ctob/make-token-theme :name "Theme" - :sets #{"Foo/A" "Bar/Foo"}))) - move (fn [from-path to-path before-path before-group?] - (->> (ctob/move-set-group tokens-lib from-path to-path before-path before-group?) - (ctob/get-ordered-set-names) - (into [])))] - (t/is (= ["Bar/Foo" "Bar/Foo/A" "Bar/Foo/B"] (move ["Foo"] ["Bar" "Foo"] nil nil))) - (t/is (= ["Bar/Foo" "Foo/A" "Foo/B"] (move ["Bar"] ["Bar"] ["Foo"] true))))) - - (t/testing "updates theme set names" - (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/B")) - (ctob/add-set (ctob/make-token-set :name "Bar/Foo")) - (ctob/add-theme (ctob/make-token-theme :name "Theme" - :sets #{"Foo/A" "Bar/Foo"})) - (ctob/move-set-group ["Foo"] ["Bar" "Foo"] nil nil))] - (t/is (= #{"Bar/Foo/A" "Bar/Foo"} (:sets (ctob/get-theme tokens-lib "" "Theme"))))))) - - (t/testing "tokens-tree" +(t/deftest move-token-set-group + (t/testing "reordering" (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "A" - :tokens {"foo.bar.baz" (ctob/make-token :name "foo.bar.baz" - :type :boolean - :value true) - "foo.bar.bam" (ctob/make-token :name "foo.bar.bam" - :type :boolean - :value true) - "baz.boo" (ctob/make-token :name "baz.boo" - :type :boolean - :value true)}))) - expected (-> (ctob/get-set tokens-lib "A") - (ctob/get-tokens-tree))] - (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 ["baz" "boo" :name]) "baz.boo"))))) + (ctob/add-set (ctob/make-token-set :name "Foo/A")) + (ctob/add-set (ctob/make-token-set :name "Foo/B")) + (ctob/add-set (ctob/make-token-set :name "Bar/Foo")) + (ctob/add-theme (ctob/make-token-theme :name "Theme" + :sets #{"Foo/A" "Bar/Foo"}))) + move (fn [from-path to-path before-path before-group?] + (->> (ctob/move-set-group tokens-lib from-path to-path before-path before-group?) + (ctob/get-ordered-set-names) + (into [])))] + (t/is (= ["Bar/Foo" "Bar/Foo/A" "Bar/Foo/B"] (move ["Foo"] ["Bar" "Foo"] nil nil))) + (t/is (= ["Bar/Foo" "Foo/A" "Foo/B"] (move ["Bar"] ["Bar"] ["Foo"] true))))) -(t/deftest token-theme - (t/testing "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/testing "updates theme set names" + (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/B")) + (ctob/add-set (ctob/make-token-set :name "Bar/Foo")) + (ctob/add-theme (ctob/make-token-theme :name "Theme" + :sets #{"Foo/A" "Bar/Foo"})) + (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 (= (:name token-theme1) "test-token-theme-1")) - (t/is (= (:group token-theme1) "")) - (t/is (= (:description token-theme1) "")) - (t/is (false? (:is-source token-theme1))) - (t/is (some? (:modified-at token-theme1))) - (t/is (empty? (:sets token-theme1))) +(t/deftest tokens-tree + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "A" + :tokens {"foo.bar.baz" (ctob/make-token :name "foo.bar.baz" + :type :boolean + :value true) + "foo.bar.bam" (ctob/make-token :name "foo.bar.bam" + :type :boolean + :value true) + "baz.boo" (ctob/make-token :name "baz.boo" + :type :boolean + :value true)}))) + expected (-> (ctob/get-set tokens-lib "A") + (get :tokens) + (ctob/tokens-tree))] + (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 ["baz" "boo" :name]) "baz.boo")))) - (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 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/testing "invalid-token-theme" - (let [params {:name 777 - :group nil - :description 999 - :is-source 42}] - (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-theme" - (ctob/make-token-theme params)))))) + (t/is (= (:name token-theme1) "test-token-theme-1")) + (t/is (= (:group token-theme1) "")) + (t/is (= (: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 make-invalid-token-theme + (let [params {:name 777 + :group nil + :description 999 + :is-source 42}] + (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid params for token-theme" + (ctob/make-token-theme params))))) -(t/deftest tokens-lib - (t/testing "make-tokens-lib" - (let [tokens-lib (ctob/make-tokens-lib)] - (t/is (= (ctob/set-count tokens-lib) 0)))) +(t/deftest make-tokens-lib + (let [tokens-lib (ctob/make-tokens-lib)] + (t/is (= (ctob/set-count tokens-lib) 0)))) - (t/testing "invalid-tokens-lib" - (let [params {:sets nil :themes nil}] - (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid token sets" - (ctob/make-tokens-lib params)))))) +(t/deftest make-invalid-tokens-lib + (let [params {:sets nil :themes nil}] + (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid token sets" + (ctob/make-tokens-lib params))))) +(t/deftest add-token-set-to-token-lib + (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) -(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) + token-sets' (ctob/get-sets tokens-lib') + token-set' (ctob/get-set tokens-lib' "test-token-set")] - token-sets' (ctob/get-sets tokens-lib') - token-set' (ctob/get-set tokens-lib' "test-token-set")] + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (first token-sets') token-set)) + (t/is (= token-set' token-set)))) - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (first token-sets') token-set)) - (t/is (= token-set' token-set)))) +(t/deftest update-token-set + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set"))) - (t/deftest update-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 + :description "some description"))) + (ctob/update-set "not-existing-set" + (fn [token-set] + (assoc token-set + :description "no-effect")))) - tokens-lib' (-> tokens-lib - (ctob/update-set "test-token-set" - (fn [token-set] - (assoc token-set + 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 (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + +(t/deftest rename-token-set-group + (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/baz-child-1")) + (ctob/add-set (ctob/make-token-set :name "foo/bar/baz/baz-child-2")) + (ctob/add-theme (ctob/make-token-theme :name "theme" :sets #{"foo/bar/baz/baz-child-1"}))) + tokens-lib' (-> tokens-lib + (ctob/rename-set-group ["foo" "bar"] "bar-renamed") + (ctob/rename-set-group ["foo" "bar-renamed" "baz"] "baz-renamed")) + expected-set-names (ctob/get-ordered-set-names tokens-lib') + expected-theme-sets (-> (ctob/get-theme tokens-lib' "" "theme") + :sets)] + (t/is (= expected-set-names + '("foo/bar-renamed/baz" + "foo/bar-renamed/baz-renamed/baz-child-1" + "foo/bar-renamed/baz-renamed/baz-child-2"))) + (t/is (= expected-theme-sets #{"foo/bar-renamed/baz-renamed/baz-child-1"})))) + +(t/deftest delete-token-set + (let [tokens-lib (-> (ctob/make-tokens-lib) + (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"}))) + + tokens-lib' (-> tokens-lib + (ctob/delete-set-path "S-test-token-set") + (ctob/delete-set-path "S-not-existing-set")) + + token-set' (ctob/get-set tokens-lib' "updated-name") + token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")] + + (t/is (= (ctob/set-count tokens-lib') 0)) + (t/is (= (:sets token-theme') #{})) + (t/is (nil? token-set')))) + +(t/deftest active-themes-set-names + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "test-token-set"))) + + tokens-lib' (-> tokens-lib + (ctob/delete-set-path "S-test-token-set") + (ctob/delete-set-path "S-not-existing-set")) + + token-set' (ctob/get-set tokens-lib' "updated-name")] + + (t/is (= (ctob/set-count tokens-lib') 0)) + (t/is (nil? token-set')))) + +(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" + :type :boolean + :value true) + tokens-lib' (-> tokens-lib + (ctob/add-token-in-set "test-token-set" token) + (ctob/add-token-in-set "not-existing-set" token)) + + 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 "test-token"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count (:tokens token-set')) 1)) + (t/is (= (:name token') "test-token")) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + +(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" + (ctob/make-token :name "test-token-1" + :type :boolean + :value true)) + (ctob/add-token-in-set "test-token-set" + (ctob/make-token :name "test-token-2" + :type :boolean + :value true))) + + tokens-lib' (-> tokens-lib + (ctob/update-token-in-set "test-token-set" "test-token-1" + (fn [token] + (assoc token + :description "some description" + :value false))) + (ctob/update-token-in-set "not-existing-set" "test-token-1" + (fn [token] + (assoc token + :name "no-effect"))) + (ctob/update-token-in-set "test-token-set" "not-existing-token" + (fn [token] + (assoc token + :name "no-effect")))) + + 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 "test-token-1"]) + token' (get-in token-set' [:tokens "test-token-1"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count (:tokens token-set')) 2)) + (t/is (= (d/index-of (keys (:tokens token-set')) "test-token-1") 0)) + (t/is (= (:name token') "test-token-1")) + (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 + (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 "test-token-2" + :type :boolean + :value true))) + + tokens-lib' (-> tokens-lib + (ctob/update-token-in-set "test-token-set" "test-token-1" + (fn [token] + (assoc token + :name "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 "test-token-1"]) + token' (get-in token-set' [:tokens "updated-name"])] + + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (count (:tokens token-set')) 2)) + (t/is (= (d/index-of (keys (:tokens token-set')) "updated-name") 0)) + (t/is (= (:name token') "updated-name")) + (t/is (= (:description token') "")) + (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 + (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))) + tokens-lib' (-> tokens-lib + (ctob/delete-token-from-set "test-token-set" "test-token") + (ctob/delete-token-from-set "not-existing-set" "test-token") + (ctob/delete-token-from-set "test-set" "not-existing-token")) + + 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 "test-token"])] + + (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/deftest list-active-themes-tokens-in-order + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :name "out-of-order-theme" + ;; Out of order sets in theme + :sets ["unknown-set" "set-b" "set-a"])) + (ctob/set-active-themes #{"/out-of-order-theme"}) + + (ctob/add-set (ctob/make-token-set :name "set-a")) + (ctob/add-token-in-set "set-a" (ctob/make-token :name "set-a-token" + :type :boolean + :value true)) + (ctob/add-set (ctob/make-token-set :name "set-b")) + (ctob/add-token-in-set "set-b" (ctob/make-token :name "set-b-token" + :type :boolean + :value true)) + ;; Ignore this set + (ctob/add-set (ctob/make-token-set :name "inactive-set")) + (ctob/add-token-in-set "inactive-set" (ctob/make-token :name "inactive-set-token" + :type :boolean + :value true))) + + expected-order (ctob/get-ordered-set-names tokens-lib) + expected-tokens (ctob/get-active-themes-set-tokens tokens-lib) + expected-token-names (mapv key expected-tokens)] + (t/is (= '("set-a" "set-b" "inactive-set") expected-order)) + (t/is (= ["set-a-token" "set-b-token"] expected-token-names)))) + +(t/deftest sets-at-path-active-state + (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/bam")) + + (ctob/add-theme (ctob/make-token-theme :name "none")) + (ctob/add-theme (ctob/make-token-theme :name "partial" + :sets #{"foo/bar/baz"})) + (ctob/add-theme (ctob/make-token-theme :name "all" + :sets #{"foo/bar/baz" + "foo/bar/bam"})) + (ctob/add-theme (ctob/make-token-theme :name "invalid" + :sets #{"foo/missing"}))) + + expected-none (-> tokens-lib + (ctob/set-active-themes #{"/none"}) + (ctob/sets-at-path-all-active? ["foo"])) + expected-all (-> tokens-lib + (ctob/set-active-themes #{"/all"}) + (ctob/sets-at-path-all-active? ["foo"])) + expected-partial (-> tokens-lib + (ctob/set-active-themes #{"/partial"}) + (ctob/sets-at-path-all-active? ["foo"])) + expected-invalid-none (-> tokens-lib + (ctob/set-active-themes #{"/invalid"}) + (ctob/sets-at-path-all-active? ["foo"]))] + (t/is (= :none expected-none)) + (t/is (= :all expected-all)) + (t/is (= :partial expected-partial)) + (t/is (= :none expected-invalid-none)))) + +(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') 2)) + (t/is (= (second 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-set "not-existing-set" - (fn [token-set] - (assoc token-set + (ctob/update-theme "" "not-existing-theme" + (fn [token-theme] + (assoc token-theme :description "no-effect")))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "test-token-set")] + token-theme (ctob/get-theme tokens-lib "" "test-token-theme") + token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")] - (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/is (= (ctob/theme-count tokens-lib') 2)) + (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-set - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set"))) +(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-set "test-token-set" - (fn [token-set] - (assoc token-set + tokens-lib' (-> tokens-lib + (ctob/update-theme "" "test-token-theme" + (fn [token-theme] + (assoc token-theme :name "updated-name")))) - token-set (ctob/get-set tokens-lib "test-token-set") - token-set' (ctob/get-set tokens-lib' "updated-name")] + token-theme (ctob/get-theme tokens-lib "" "test-token-theme") + token-theme' (ctob/get-theme tokens-lib' "" "updated-name")] - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (:name token-set') "updated-name")) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + (t/is (= (ctob/theme-count tokens-lib') 2)) + (t/is (= (:name token-theme') "updated-name")) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) - (t/deftest rename-token-set-group - (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/baz-child-1")) - (ctob/add-set (ctob/make-token-set :name "foo/bar/baz/baz-child-2")) - (ctob/add-theme (ctob/make-token-theme :name "theme" :sets #{"foo/bar/baz/baz-child-1"}))) - tokens-lib' (-> tokens-lib - (ctob/rename-set-group ["foo" "bar"] "bar-renamed") - (ctob/rename-set-group ["foo" "bar-renamed" "baz"] "baz-renamed")) - expected-set-names (ctob/get-ordered-set-names tokens-lib') - expected-theme-sets (-> (ctob/get-theme tokens-lib' "" "theme") - :sets)] - (t/is (= expected-set-names - '("foo/bar-renamed/baz" - "foo/bar-renamed/baz-renamed/baz-child-1" - "foo/bar-renamed/baz-renamed/baz-child-2"))) - (t/is (= expected-theme-sets #{"foo/bar-renamed/baz-renamed/baz-child-1"})))) +(t/deftest delete-token-theme + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-theme (ctob/make-token-theme :name "test-token-theme"))) - (t/deftest delete-token-set - (let [tokens-lib (-> (ctob/make-tokens-lib) - (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"}))) + tokens-lib' (-> tokens-lib + (ctob/delete-theme "" "test-token-theme") + (ctob/delete-theme "" "not-existing-theme")) - tokens-lib' (-> tokens-lib - (ctob/delete-set-path "S-test-token-set") - (ctob/delete-set-path "S-not-existing-set")) + token-theme' (ctob/get-theme tokens-lib' "" "updated-name")] - token-set' (ctob/get-set tokens-lib' "updated-name") - token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")] + (t/is (= (ctob/theme-count tokens-lib') 1)) + (t/is (nil? token-theme')))) - (t/is (= (ctob/set-count tokens-lib') 0)) - (t/is (= (:sets token-theme') #{})) - (t/is (nil? token-set')))) +(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")) - (t/deftest active-themes-set-names - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "test-token-set"))) + token-theme (ctob/get-theme tokens-lib "" "test-token-theme") + token-theme' (ctob/get-theme tokens-lib' "" "test-token-theme")] - tokens-lib' (-> tokens-lib - (ctob/delete-set-path "S-test-token-set") - (ctob/delete-set-path "S-not-existing-set")) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) - token-set' (ctob/get-set tokens-lib' "updated-name")] - - (t/is (= (ctob/set-count tokens-lib') 0)) - (t/is (nil? token-set'))))) - - -(t/deftest token-in-a-lib - (t/testing "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" - :type :boolean - :value true) - tokens-lib' (-> tokens-lib - (ctob/add-token-in-set "test-token-set" token) - (ctob/add-token-in-set "not-existing-set" token)) - - 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 "test-token"])] - - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (count (:tokens token-set')) 1)) - (t/is (= (:name token') "test-token")) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) - - (t/testing "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" - (ctob/make-token :name "test-token-1" - :type :boolean - :value true)) - (ctob/add-token-in-set "test-token-set" - (ctob/make-token :name "test-token-2" - :type :boolean - :value true))) - - tokens-lib' (-> tokens-lib - (ctob/update-token-in-set "test-token-set" "test-token-1" - (fn [token] - (assoc token - :description "some description" - :value false))) - (ctob/update-token-in-set "not-existing-set" "test-token-1" - (fn [token] - (assoc token - :name "no-effect"))) - (ctob/update-token-in-set "test-token-set" "not-existing-token" - (fn [token] - (assoc token - :name "no-effect")))) - - 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 "test-token-1"]) - token' (get-in token-set' [:tokens "test-token-1"])] - - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (count (:tokens token-set')) 2)) - (t/is (= (d/index-of (keys (:tokens token-set')) "test-token-1") 0)) - (t/is (= (:name token') "test-token-1")) - (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/testing "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" - (ctob/make-token :name "test-token-1" - :type :boolean - :value true)) - (ctob/add-token-in-set "test-token-set" - (ctob/make-token :name "test-token-2" - :type :boolean - :value true))) - - tokens-lib' (-> tokens-lib - (ctob/update-token-in-set "test-token-set" "test-token-1" - (fn [token] - (assoc token - :name "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 "test-token-1"]) - token' (get-in token-set' [:tokens "updated-name"])] - - (t/is (= (ctob/set-count tokens-lib') 1)) - (t/is (= (count (:tokens token-set')) 2)) - (t/is (= (d/index-of (keys (:tokens token-set')) "updated-name") 0)) - (t/is (= (:name token') "updated-name")) - (t/is (= (:description token') "")) - (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/testing "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" - (ctob/make-token :name "test-token" - :type :boolean - :value true))) - tokens-lib' (-> tokens-lib - (ctob/delete-token-from-set "test-token-set" "test-token") - (ctob/delete-token-from-set "not-existing-set" "test-token") - (ctob/delete-token-from-set "test-set" "not-existing-token")) - - 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 "test-token"])] - - (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/testing "list-active-themes-tokens-in-order" - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-theme (ctob/make-token-theme :name "out-of-order-theme" - ;; Out of order sets in theme - :sets ["unknown-set" "set-b" "set-a"])) - (ctob/set-active-themes #{"/out-of-order-theme"}) - - (ctob/add-set (ctob/make-token-set :name "set-a")) - (ctob/add-token-in-set "set-a" (ctob/make-token :name "set-a-token" - :type :boolean - :value true)) - (ctob/add-set (ctob/make-token-set :name "set-b")) - (ctob/add-token-in-set "set-b" (ctob/make-token :name "set-b-token" - :type :boolean - :value true)) - ;; Ignore this set - (ctob/add-set (ctob/make-token-set :name "inactive-set")) - (ctob/add-token-in-set "inactive-set" (ctob/make-token :name "inactive-set-token" +(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)] - expected-order (ctob/get-ordered-set-names tokens-lib) - expected-tokens (ctob/get-active-themes-set-tokens tokens-lib) - expected-token-names (mapv key expected-tokens)] - (t/is (= '("set-a" "set-b" "inactive-set") expected-order)) - (t/is (= ["set-a-token" "set-b-token"] expected-token-names)))) + (t/is (ctob/valid-tokens-lib? tokens-lib')) + (t/is (= (ctob/set-count tokens-lib') 1)) + (t/is (= (ctob/theme-count tokens-lib') 2)))) - (t/testing "sets-at-path-active-state" - (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/bam")) - - (ctob/add-theme (ctob/make-token-theme :name "none")) - (ctob/add-theme (ctob/make-token-theme :name "partial" - :sets #{"foo/bar/baz"})) - (ctob/add-theme (ctob/make-token-theme :name "all" - :sets #{"foo/bar/baz" - "foo/bar/bam"})) - (ctob/add-theme (ctob/make-token-theme :name "invalid" - :sets #{"foo/missing"}))) - - expected-none (-> tokens-lib - (ctob/set-active-themes #{"/none"}) - (ctob/sets-at-path-all-active? ["foo"])) - expected-all (-> tokens-lib - (ctob/set-active-themes #{"/all"}) - (ctob/sets-at-path-all-active? ["foo"])) - expected-partial (-> tokens-lib - (ctob/set-active-themes #{"/partial"}) - (ctob/sets-at-path-all-active? ["foo"])) - expected-invalid-none (-> tokens-lib - (ctob/set-active-themes #{"/invalid"}) - (ctob/sets-at-path-all-active? ["foo"]))] - (t/is (= :none expected-none)) - (t/is (= :all expected-all)) - (t/is (= :partial expected-partial)) - (t/is (= :none expected-invalid-none))))) - -(t/deftest token-theme-in-a-lib - (t/testing "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') 2)) - (t/is (= (second token-themes') token-theme)) - (t/is (= token-theme' token-theme)))) - - (t/testing "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') 2)) - (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/testing "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') 2)) - (t/is (= (:name token-theme') "updated-name")) - (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) - - (t/testing "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') 1)) - (t/is (nil? token-theme')))) - - (t/testing "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/deftest serialization - (t/testing "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)) - (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/theme-count tokens-lib') 2)))) - - #?(:clj - (t/testing "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)) - (ctob/add-theme (ctob/make-token-theme :name "test-token-theme")) +#?(:clj + (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)) + (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/theme-count tokens-lib') 2)))))) - -(t/deftest grouping - (t/testing "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/testing "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/testing "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/testing "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/testing "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/testing "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/testing "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/testing "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') "")) - (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/testing "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') "")) - (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/testing "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/testing "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) "S-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) "G-group1")) - (t/is (= (ctob/group? (second node-group1)) true)) - (t/is (= (count (second node-group1)) 3)) - - (t/is (= (first node-set2) "S-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) "S-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) "G-subgroup11")) - (t/is (= (ctob/group? (second node-subgroup11)) true)) - (t/is (= (count (second node-subgroup11)) 1)) - - (t/is (= (first node-set4) "S-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) "S-token-set-5")) - (t/is (= (ctob/group? (second node-set5)) false)) - (t/is (= (:name (second node-set5)) "group2/token-set-5")))) - - (t/testing "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' "G-group1") - token-set (get-in sets-tree ["G-group1" "S-token-set-2"]) - token-set' (get-in sets-tree' ["G-group1" "S-token-set-2"])] - - (t/is (= (ctob/set-count tokens-lib') 5)) - (t/is (= (count group1') 3)) - (t/is (= (d/index-of (keys group1') "S-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/testing "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' "G-group1") - token-set (get-in sets-tree ["G-group1" "S-token-set-2"]) - token-set' (get-in sets-tree' ["G-group1" "S-updated-name"])] - - (t/is (= (ctob/set-count tokens-lib') 5)) - (t/is (= (count group1') 3)) - (t/is (= (d/index-of (keys group1') "S-updated-name") 0)) - (t/is (= (:name token-set') "group1/updated-name")) - (t/is (= (:description token-set') "")) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))) - sets-tree')) - - - (t/testing "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' "G-group1") - group2' (get sets-tree' "G-group2") - token-set (get-in sets-tree ["G-group1" "S-token-set-2"]) - token-set' (get-in sets-tree' ["G-group2" "S-updated-name"])] - - (t/is (= (ctob/set-count tokens-lib') 4)) - (t/is (= (count group1') 2)) - (t/is (= (count group2') 1)) - (t/is (nil? (get group1' "S-updated-name"))) - (t/is (= (:name token-set') "group2/updated-name")) - (t/is (= (:description token-set') "")) - (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) - - (t/testing "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-path "G-group1/S-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/testing "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) - - [hidden-theme 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) 5)) - (t/is (= (:name (nth themes-list 0)) "__PENPOT__HIDDEN__TOKEN__THEME__")) - (t/is (= (:name (nth themes-list 1)) "token-theme-1")) - (t/is (= (:name (nth themes-list 2)) "token-theme-2")) - (t/is (= (:name (nth themes-list 3)) "token-theme-3")) - (t/is (= (:name (nth themes-list 4)) "token-theme-4")) - (t/is (= (:group (nth themes-list 1)) "")) - (t/is (= (:group (nth themes-list 2)) "group1")) - (t/is (= (:group (nth themes-list 3)) "group1")) - (t/is (= (:group (nth themes-list 4)) "group2")) - - (t/is (= (first node-group0) "")) - (t/is (= (ctob/group? (second node-group0)) true)) - (t/is (= (count (second node-group0)) 2)) - - (t/is (= (first hidden-theme) "__PENPOT__HIDDEN__TOKEN__THEME__")) - (t/is (= (ctob/group? (second hidden-theme)) false)) - (t/is (= (:name (second hidden-theme)) "__PENPOT__HIDDEN__TOKEN__THEME__")) - - (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/testing "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') 5)) - (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/testing "get-theme-groups" - (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 "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"))) - token-groups (ctob/get-theme-groups token-lib)] - (t/is (= token-groups ["group1" "group2"])))) - - (t/testing "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') 5)) - (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') "")) - (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) - - (t/testing "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') 4)) - (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') "")) - (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) - - (t/testing "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') 2)) - (t/is (= (count themes-tree') 1)) - (t/is (nil? token-theme')))))) + 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/theme-count tokens-lib') 2))))) + +(t/deftest split-and-join-path + (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 split-and-join-path-with-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-token-set + (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-token-set-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-token-set-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/deftest add-tokens-in-set + (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-sets + (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 update-token-in-sets-rename + (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') "")) + (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') "")) + (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/deftest add-token-set-with-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"))) + + 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) "S-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) "G-group1")) + (t/is (= (ctob/group? (second node-group1)) true)) + (t/is (= (count (second node-group1)) 3)) + + (t/is (= (first node-set2) "S-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) "S-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) "G-subgroup11")) + (t/is (= (ctob/group? (second node-subgroup11)) true)) + (t/is (= (count (second node-subgroup11)) 1)) + + (t/is (= (first node-set4) "S-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) "S-token-set-5")) + (t/is (= (ctob/group? (second node-set5)) false)) + (t/is (= (:name (second node-set5)) "group2/token-set-5")))) + +(t/deftest update-token-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' "G-group1") + token-set (get-in sets-tree ["G-group1" "S-token-set-2"]) + token-set' (get-in sets-tree' ["G-group1" "S-token-set-2"])] + + (t/is (= (ctob/set-count tokens-lib') 5)) + (t/is (= (count group1') 3)) + (t/is (= (d/index-of (keys group1') "S-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-token-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' "G-group1") + token-set (get-in sets-tree ["G-group1" "S-token-set-2"]) + token-set' (get-in sets-tree' ["G-group1" "S-updated-name"])] + + (t/is (= (ctob/set-count tokens-lib') 5)) + (t/is (= (count group1') 3)) + (t/is (= (d/index-of (keys group1') "S-updated-name") 0)) + (t/is (= (:name token-set') "group1/updated-name")) + (t/is (= (:description token-set') "")) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + +(t/deftest move-token-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' "G-group1") + group2' (get sets-tree' "G-group2") + token-set (get-in sets-tree ["G-group1" "S-token-set-2"]) + token-set' (get-in sets-tree' ["G-group2" "S-updated-name"])] + + (t/is (= (ctob/set-count tokens-lib') 4)) + (t/is (= (count group1') 2)) + (t/is (= (count group2') 1)) + (t/is (nil? (get group1' "S-updated-name"))) + (t/is (= (:name token-set') "group2/updated-name")) + (t/is (= (:description token-set') "")) + (t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set))))) + +(t/deftest delete-token-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-path "G-group1/S-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/deftest add-theme-with-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"))) + + 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) + + [hidden-theme 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) 5)) + (t/is (= (:name (nth themes-list 0)) "__PENPOT__HIDDEN__TOKEN__THEME__")) + (t/is (= (:name (nth themes-list 1)) "token-theme-1")) + (t/is (= (:name (nth themes-list 2)) "token-theme-2")) + (t/is (= (:name (nth themes-list 3)) "token-theme-3")) + (t/is (= (:name (nth themes-list 4)) "token-theme-4")) + (t/is (= (:group (nth themes-list 1)) "")) + (t/is (= (:group (nth themes-list 2)) "group1")) + (t/is (= (:group (nth themes-list 3)) "group1")) + (t/is (= (:group (nth themes-list 4)) "group2")) + + (t/is (= (first node-group0) "")) + (t/is (= (ctob/group? (second node-group0)) true)) + (t/is (= (count (second node-group0)) 2)) + + (t/is (= (first hidden-theme) "__PENPOT__HIDDEN__TOKEN__THEME__")) + (t/is (= (ctob/group? (second hidden-theme)) false)) + (t/is (= (:name (second hidden-theme)) "__PENPOT__HIDDEN__TOKEN__THEME__")) + + (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-token-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') 5)) + (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 get-token-theme-groups + (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 "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"))) + token-groups (ctob/get-theme-groups token-lib)] + (t/is (= token-groups ["group1" "group2"])))) + +(t/deftest rename-token-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') 5)) + (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') "")) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) + +(t/deftest move-token-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') 4)) + (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') "")) + (t/is (dt/is-after? (:modified-at token-theme') (:modified-at token-theme))))) + +(t/deftest delete-token-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') 2)) + (t/is (= (count themes-tree') 1)) + (t/is (nil? token-theme')))) #?(:clj (t/deftest legacy-json-decoding - (t/testing "decode-legacy-json" - (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-legacy-example.json") - (tr/decode-str)) - lib (ctob/decode-legacy-json (ctob/ensure-tokens-lib nil) json) - get-set-token (fn [set-name token-name] - (some-> (ctob/get-set lib set-name) - (ctob/get-token token-name) - (dissoc :modified-at))) - token-theme (ctob/get-theme lib "group-1" "theme-1")] - (t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib))) - (t/testing "set exists in theme" - (t/is (= (:group token-theme) "group-1")) - (t/is (= (:name token-theme) "theme-1")) - (t/is (= (:sets token-theme) #{"light"}))) - (t/testing "tokens exist in core set" - (t/is (= (get-set-token "core" "colors.red.600") - {:name "colors.red.600" - :type :color - :value "#e53e3e" - :description ""})) - (t/is (= (get-set-token "core" "spacing.multi-value") - {:name "spacing.multi-value" - :type :spacing - :value "{dimension.sm} {dimension.xl}" - :description "You can have multiple values in a single spacing token"})) - (t/is (= (get-set-token "theme" "button.primary.background") - {:name "button.primary.background" - :type :color - :value "{accent.default}" - :description ""}))) - (t/testing "invalid tokens got discarded" - (t/is (nil? (get-set-token "typography" "H1.Bold")))))))) + (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-legacy-example.json") + (tr/decode-str)) + lib (ctob/decode-legacy-json (ctob/ensure-tokens-lib nil) json) + get-set-token (fn [set-name token-name] + (some-> (ctob/get-set lib set-name) + (ctob/get-token token-name) + (dissoc :modified-at))) + token-theme (ctob/get-theme lib "group-1" "theme-1")] + (t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib))) + (t/testing "set exists in theme" + (t/is (= (:group token-theme) "group-1")) + (t/is (= (:name token-theme) "theme-1")) + (t/is (= (:sets token-theme) #{"light"}))) + (t/testing "tokens exist in core set" + (t/is (= (get-set-token "core" "colors.red.600") + {:name "colors.red.600" + :type :color + :value "#e53e3e" + :description ""})) + (t/is (= (get-set-token "core" "spacing.multi-value") + {:name "spacing.multi-value" + :type :spacing + :value "{dimension.sm} {dimension.xl}" + :description "You can have multiple values in a single spacing token"})) + (t/is (= (get-set-token "theme" "button.primary.background") + {:name "button.primary.background" + :type :color + :value "{accent.default}" + :description ""}))) + (t/testing "invalid tokens got discarded" + (t/is (nil? (get-set-token "typography" "H1.Bold"))))))) #?(:clj - (t/deftest dtcg-encoding-decoding - (t/testing "decode-dtcg-json" - (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-example.json") - (tr/decode-str)) - lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json) - get-set-token (fn [set-name token-name] - (some-> (ctob/get-set lib set-name) - (ctob/get-token token-name))) - token-theme (ctob/get-theme lib "group-1" "theme-1")] - (t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib))) - (t/testing "set exists in theme" - (t/is (= (:group token-theme) "group-1")) - (t/is (= (:name token-theme) "theme-1")) - (t/is (= (:sets token-theme) #{"light"}))) - (t/testing "tokens exist in core set" - (t/is (tht/token-data-eq? (get-set-token "core" "colors.red.600") - {:name "colors.red.600" - :type :color - :value "#e53e3e" - :description ""})) - (t/is (tht/token-data-eq? (get-set-token "core" "spacing.multi-value") - {:name "spacing.multi-value" - :type :spacing - :value "{dimension.sm} {dimension.xl}" - :description "You can have multiple values in a single spacing token"})) - (t/is (tht/token-data-eq? (get-set-token "theme" "button.primary.background") - {:name "button.primary.background" - :type :color - :value "{accent.default}" - :description ""}))) - (t/testing "invalid tokens got discarded" - (t/is (nil? (get-set-token "typography" "H1.Bold")))))) + (t/deftest dtcg-encoding-decoding-json + (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-example.json") + (tr/decode-str)) + lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json) + get-set-token (fn [set-name token-name] + (some-> (ctob/get-set lib set-name) + (ctob/get-token token-name))) + token-theme (ctob/get-theme lib "group-1" "theme-1")] + (t/is (= '("core" "light" "dark" "theme") (ctob/get-ordered-set-names lib))) + (t/testing "set exists in theme" + (t/is (= (:group token-theme) "group-1")) + (t/is (= (:name token-theme) "theme-1")) + (t/is (= (:sets token-theme) #{"light"}))) + (t/testing "tokens exist in core set" + (t/is (tht/token-data-eq? (get-set-token "core" "colors.red.600") + {:name "colors.red.600" + :type :color + :value "#e53e3e" + :description ""})) + (t/is (tht/token-data-eq? (get-set-token "core" "spacing.multi-value") + {:name "spacing.multi-value" + :type :spacing + :value "{dimension.sm} {dimension.xl}" + :description "You can have multiple values in a single spacing token"})) + (t/is (tht/token-data-eq? (get-set-token "theme" "button.primary.background") + {:name "button.primary.background" + :type :color + :value "{accent.default}" + :description ""}))) + (t/testing "invalid tokens got discarded" + (t/is (nil? (get-set-token "typography" "H1.Bold"))))))) - (t/testing "decode-dtcg-json-default-team" - (let [json (-> (slurp "test/common_tests/types/data/tokens-default-team-only.json") - (tr/decode-str)) - lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json) - get-set-token (fn [set-name token-name] - (some-> (ctob/get-set lib set-name) - (ctob/get-token token-name))) - themes (ctob/get-themes lib) - first-theme (first themes)] - (t/is (= '("dark") (ctob/get-ordered-set-names lib))) - (t/is (= 1 (count themes))) - (t/testing "existing theme is default theme" - (t/is (= (:group first-theme) "")) - (t/is (= (:name first-theme) ctob/hidden-token-theme-name))) - (t/testing "token exist in dark set" - (t/is (tht/token-data-eq? (get-set-token "dark" "small") - {:name "small" - :value "8" - :type :border-radius - :description ""}))))) +#?(:clj + (t/deftest decode-dtcg-json-default-team + (let [json (-> (slurp "test/common_tests/types/data/tokens-default-team-only.json") + (tr/decode-str)) + lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json) + get-set-token (fn [set-name token-name] + (some-> (ctob/get-set lib set-name) + (ctob/get-token token-name))) + themes (ctob/get-themes lib) + first-theme (first themes)] + (t/is (= '("dark") (ctob/get-ordered-set-names lib))) + (t/is (= 1 (count themes))) + (t/testing "existing theme is default theme" + (t/is (= (:group first-theme) "")) + (t/is (= (:name first-theme) ctob/hidden-token-theme-name))) + (t/testing "token exist in dark set" + (t/is (tht/token-data-eq? (get-set-token "dark" "small") + {:name "small" + :value "8" + :type :border-radius + :description ""})))))) - (t/testing "encode-dtcg-json" - (let [now (dt/now) - tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "core" - :tokens {"colors.red.600" - (ctob/make-token - {:name "colors.red.600" - :type :color - :value "#e53e3e"}) - "spacing.multi-value" - (ctob/make-token - {:name "spacing.multi-value" - :type :spacing - :value "{dimension.sm} {dimension.xl}" - :description "You can have multiple values in a single spacing token"}) - "button.primary.background" - (ctob/make-token - {:name "button.primary.background" - :type :color - :value "{accent.default}"})})) - (ctob/add-theme (ctob/make-token-theme :name "theme-1" - :group "group-1" - :id "test-id-00" - :modified-at now - :sets #{"core"}))) - result (ctob/encode-dtcg tokens-lib) - expected {"$themes" [{"description" "" - "group" "group-1" - "is-source" false - "modified-at" now - "id" "test-id-00" - "name" "theme-1" - "selectedTokenSets" {"core" "enabled"}}] - "$metadata" {"tokenSetOrder" ["core"] - "activeSets" #{}, "activeThemes" #{}} - "core" - {"colors" {"red" {"600" {"$value" "#e53e3e" + +#?(:clj + (t/deftest encode-dtcg-json + (let [now (dt/now) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "core" + :tokens {"colors.red.600" + (ctob/make-token + {:name "colors.red.600" + :type :color + :value "#e53e3e"}) + "spacing.multi-value" + (ctob/make-token + {:name "spacing.multi-value" + :type :spacing + :value "{dimension.sm} {dimension.xl}" + :description "You can have multiple values in a single spacing token"}) + "button.primary.background" + (ctob/make-token + {:name "button.primary.background" + :type :color + :value "{accent.default}"})})) + (ctob/add-theme (ctob/make-token-theme :name "theme-1" + :group "group-1" + :id "test-id-00" + :modified-at now + :sets #{"core"}))) + result (ctob/encode-dtcg tokens-lib) + expected {"$themes" [{"description" "" + "group" "group-1" + "is-source" false + "modified-at" now + "id" "test-id-00" + "name" "theme-1" + "selectedTokenSets" {"core" "enabled"}}] + "$metadata" {"tokenSetOrder" ["core"] + "activeSets" #{}, "activeThemes" #{}} + "core" + {"colors" {"red" {"600" {"$value" "#e53e3e" + "$type" "color" + "$description" ""}}} + "spacing" + {"multi-value" + {"$value" "{dimension.sm} {dimension.xl}" + "$type" "spacing" + "$description" "You can have multiple values in a single spacing token"}} + "button" + {"primary" {"background" {"$value" "{accent.default}" "$type" "color" - "$description" ""}}} - "spacing" - {"multi-value" - {"$value" "{dimension.sm} {dimension.xl}" - "$type" "spacing" - "$description" "You can have multiple values in a single spacing token"}} - "button" - {"primary" {"background" {"$value" "{accent.default}" - "$type" "color" - "$description" ""}}}}}] + "$description" ""}}}}}] + (t/is (= expected result))))) - (t/is (= expected result)))) - - (t/testing "encode-decode-dtcg-json" - (with-redefs [dt/now (constantly #inst "2024-10-16T12:01:20.257840055-00:00")] - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "core" - :tokens {"colors.red.600" - (ctob/make-token - {:name "colors.red.600" - :type :color - :value "#e53e3e"}) - "spacing.multi-value" - (ctob/make-token - {:name "spacing.multi-value" - :type :spacing - :value "{dimension.sm} {dimension.xl}" - :description "You can have multiple values in a single spacing token"}) - "button.primary.background" - (ctob/make-token - {:name "button.primary.background" - :type :color - :value "{accent.default}"})}))) - - encoded (ctob/encode-dtcg tokens-lib) - with-prev-tokens-lib (ctob/decode-dtcg-json tokens-lib encoded) - with-empty-tokens-lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) encoded)] - (t/testing "library got updated but data is equal" - (t/is (not= with-prev-tokens-lib tokens-lib)) - (t/is (= @with-prev-tokens-lib @tokens-lib))) - (t/testing "fresh tokens library is also equal" - (= @with-empty-tokens-lib @tokens-lib))))) - - (t/testing "encode-default-theme-json" +#?(:clj + (t/deftest encode-decode-dtcg-json + (with-redefs [dt/now (constantly #inst "2024-10-16T12:01:20.257840055-00:00")] (let [tokens-lib (-> (ctob/make-tokens-lib) (ctob/add-set (ctob/make-token-set :name "core" :tokens {"colors.red.600" @@ -1335,74 +1293,105 @@ {:name "button.primary.background" :type :color :value "{accent.default}"})}))) - result (ctob/encode-dtcg tokens-lib) - expected {"$themes" [] - "$metadata" {"tokenSetOrder" ["core"] - "activeSets" #{}, "activeThemes" #{}} - "core" - {"colors" {"red" {"600" {"$value" "#e53e3e" - "$type" "color" - "$description" ""}}} - "spacing" - {"multi-value" - {"$value" "{dimension.sm} {dimension.xl}" - "$type" "spacing" - "$description" "You can have multiple values in a single spacing token"}} - "button" - {"primary" {"background" {"$value" "{accent.default}" - "$type" "color" - "$description" ""}}}}}] - (t/is (= expected result)))) + encoded (ctob/encode-dtcg tokens-lib) + with-prev-tokens-lib (ctob/decode-dtcg-json tokens-lib encoded) + with-empty-tokens-lib (ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) encoded)] + (t/testing "library got updated but data is equal" + (t/is (not= with-prev-tokens-lib tokens-lib)) + (t/is (= @with-prev-tokens-lib @tokens-lib))) + (t/testing "fresh tokens library is also equal" + (= @with-empty-tokens-lib @tokens-lib)))))) - (t/testing "encode-dtcg-json-with-active-theme-and-set" - (let [now (dt/now) - tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "core" - :tokens {"colors.red.600" - (ctob/make-token - {:name "colors.red.600" - :type :color - :value "#e53e3e"}) - "spacing.multi-value" - (ctob/make-token - {:name "spacing.multi-value" - :type :spacing - :value "{dimension.sm} {dimension.xl}" - :description "You can have multiple values in a single spacing token"}) - "button.primary.background" - (ctob/make-token - {:name "button.primary.background" - :type :color - :value "{accent.default}"})})) - (ctob/add-theme (ctob/make-token-theme :name "theme-1" - :group "group-1" - :id "test-id-01" - :modified-at now - :sets #{"core"})) - (ctob/toggle-theme-active? "group-1" "theme-1")) - result (ctob/encode-dtcg tokens-lib) - expected {"$themes" [{"description" "" - "group" "group-1" - "is-source" false - "modified-at" now - "id" "test-id-01" - "name" "theme-1" - "selectedTokenSets" {"core" "enabled"}}] - "$metadata" {"tokenSetOrder" ["core"] - "activeSets" #{"core"}, - "activeThemes" #{"group-1/theme-1"}} - "core" - {"colors" {"red" {"600" {"$value" "#e53e3e" +#?(:clj + (t/deftest encode-default-theme-json + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "core" + :tokens {"colors.red.600" + (ctob/make-token + {:name "colors.red.600" + :type :color + :value "#e53e3e"}) + "spacing.multi-value" + (ctob/make-token + {:name "spacing.multi-value" + :type :spacing + :value "{dimension.sm} {dimension.xl}" + :description "You can have multiple values in a single spacing token"}) + "button.primary.background" + (ctob/make-token + {:name "button.primary.background" + :type :color + :value "{accent.default}"})}))) + result (ctob/encode-dtcg tokens-lib) + expected {"$themes" [] + "$metadata" {"tokenSetOrder" ["core"] + "activeSets" #{}, "activeThemes" #{}} + "core" + {"colors" {"red" {"600" {"$value" "#e53e3e" + "$type" "color" + "$description" ""}}} + "spacing" + {"multi-value" + {"$value" "{dimension.sm} {dimension.xl}" + "$type" "spacing" + "$description" "You can have multiple values in a single spacing token"}} + "button" + {"primary" {"background" {"$value" "{accent.default}" "$type" "color" - "$description" ""}}} - "spacing" - {"multi-value" - {"$value" "{dimension.sm} {dimension.xl}" - "$type" "spacing" - "$description" "You can have multiple values in a single spacing token"}} - "button" - {"primary" {"background" {"$value" "{accent.default}" - "$type" "color" - "$description" ""}}}}}] - (t/is (= expected result)))))) + "$description" ""}}}}}] + + (t/is (= expected result))))) + +#?(:clj + (t/deftest encode-dtcg-json-with-active-theme-and-set + (let [now (dt/now) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "core" + :tokens {"colors.red.600" + (ctob/make-token + {:name "colors.red.600" + :type :color + :value "#e53e3e"}) + "spacing.multi-value" + (ctob/make-token + {:name "spacing.multi-value" + :type :spacing + :value "{dimension.sm} {dimension.xl}" + :description "You can have multiple values in a single spacing token"}) + "button.primary.background" + (ctob/make-token + {:name "button.primary.background" + :type :color + :value "{accent.default}"})})) + (ctob/add-theme (ctob/make-token-theme :name "theme-1" + :group "group-1" + :id "test-id-01" + :modified-at now + :sets #{"core"})) + (ctob/toggle-theme-active? "group-1" "theme-1")) + result (ctob/encode-dtcg tokens-lib) + expected {"$themes" [{"description" "" + "group" "group-1" + "is-source" false + "modified-at" now + "id" "test-id-01" + "name" "theme-1" + "selectedTokenSets" {"core" "enabled"}}] + "$metadata" {"tokenSetOrder" ["core"] + "activeSets" #{"core"}, + "activeThemes" #{"group-1/theme-1"}} + "core" + {"colors" {"red" {"600" {"$value" "#e53e3e" + "$type" "color" + "$description" ""}}} + "spacing" + {"multi-value" + {"$value" "{dimension.sm} {dimension.xl}" + "$type" "spacing" + "$description" "You can have multiple values in a single spacing token"}} + "button" + {"primary" {"background" {"$value" "{accent.default}" + "$type" "color" + "$description" ""}}}}}] + (t/is (= expected result))))) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index 6c5ca8fdce..4a4bcd321f 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -127,7 +127,7 @@ (wtu/update-workspace-tokens)))))) (defn create-token-set - [set-name token-set] + [set-name] (ptk/reify ::create-token-set ptk/UpdateEvent (update [_ state] @@ -136,28 +136,16 @@ ptk/WatchEvent (watch [it state _] - (let [token-set' - ;; FIXME: wtf is this? - (update token-set :name #(if (empty? %) - set-name - (ctob/join-set-path [% set-name]))) - - token-set' - (update token-set' :name ctob/normalize-set-name) - - data - (dsh/lookup-file-data state) - - token-set-name - (:name token-set') - - changes - (-> (pcb/empty-changes it) - (pcb/with-library-data data) - (pcb/set-token-set token-set-name false token-set'))] - - (rx/of (set-selected-token-set-name token-set-name) - (dch/commit-changes changes)))))) + (let [data (dsh/lookup-file-data state) + tokens-lib (get data :tokens-lib) + set-name (ctob/normalize-set-name set-name)] + (when-not (ctob/get-set tokens-lib set-name) + (let [token-set (ctob/make-token-set :name set-name) + changes (-> (pcb/empty-changes it) + (pcb/with-library-data data) + (pcb/set-token-set set-name false token-set))] + (rx/of (set-selected-token-set-name set-name) + (dch/commit-changes changes)))))))) (defn rename-token-set-group [set-group-path set-group-fname] (ptk/reify ::rename-token-set-group @@ -168,17 +156,28 @@ (rx/of (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/WatchEvent (watch [it state _] - (let [data (dsh/lookup-file-data state) - changes (-> (pcb/empty-changes it) - (pcb/with-library-data data) - (pcb/set-token-set set-name false token-set))] - (rx/of - (set-selected-token-set-name (:name token-set)) - (dch/commit-changes changes)))))) + (let [data (dsh/lookup-file-data state) + name (ctob/normalize-set-name name (:name token-set)) + tokens-lib (get data :tokens-lib)] + + (cond + (= (:name token-set) name) + nil + + (ctob/get-set tokens-lib name) + nil + + :else + (let [changes (-> (pcb/empty-changes it) + (pcb/with-library-data data) + (pcb/rename-token-set (:name token-set) name))] + (rx/of (set-selected-token-set-name (:name token-set)) + (dch/commit-changes changes)))))))) (defn toggle-token-set [name] diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 096cddb777..9ad06f0cb8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -43,17 +43,27 @@ (st/emit! (dt/set-selected-token-set-name name))) (defn on-update-token-set - [name token-set] + [token-set name] (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) (dt/rename-token-set-group path name))) -(defn- on-create-token-set [name token-set] - (st/emit! (ptk/data-event ::ev/event {::ev/name "create-token-set" :name name}) - (dt/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}) + (dt/create-token-set name)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; COMPONENTS @@ -62,13 +72,11 @@ (mf/defc editing-label* {::mf/private true} [{:keys [default-value on-cancel on-submit]}] - (let [ref (mf/use-ref) - - on-submit-valid + (let [on-submit (mf/use-fn (mf/deps on-cancel on-submit default-value) (fn [event] - (let [value (str/trim (dom/get-target-val event))] + (let [value (dom/get-target-val event)] (if (or (str/empty? value) (= value default-value)) (on-cancel) @@ -76,16 +84,15 @@ on-key-down (mf/use-fn - (mf/deps on-submit-valid on-cancel) + (mf/deps on-submit on-cancel) (fn [event] (cond - (kbd/enter? event) (on-submit-valid event) + (kbd/enter? event) (on-submit event) (kbd/esc? event) (on-cancel))))] [:input {:class (stl/css :editing-node) :type "text" - :ref ref - :on-blur on-submit-valid + :on-blur on-submit :on-key-down on-key-down :auto-focus true :placeholder (tr "workspace.token.set-edit-placeholder") @@ -234,6 +241,7 @@ (mf/defc sets-tree-set* [{: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]}] + (let [set-name (get set :name) can-edit? (mf/use-ctx ctx/can-edit?) @@ -273,7 +281,7 @@ on-edit-submit' (mf/use-fn (mf/deps set on-edit-submit) - #(on-edit-submit % set)) + #(on-edit-submit set %)) on-drag (mf/use-fn From 1893cd306a67858bab03382a174d4142d17c7d64 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 15:18:28 +0100 Subject: [PATCH 05/11] :sparkles: Improve translation strings for token set drop errors --- frontend/src/app/main/data/tokens.cljs | 4 ++-- frontend/translations/en.po | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index 4a4bcd321f..e7f51dcfc2 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -234,8 +234,8 @@ ptk/WatchEvent (watch [_ _ _] (let [content (case error - :path-exists (tr "errors.drag-drop.set-exists" to-path) - :parent-to-child (tr "errors.drag-drop.parent-to-child") + :path-exists (tr "errors.token-set-exists-on-drop" to-path) + :parent-to-child (tr "errors.drop-token-set-parent-to-child") nil)] (when content (rx/of diff --git a/frontend/translations/en.po b/frontend/translations/en.po index df13275781..1ceda7145d 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -1160,11 +1160,11 @@ msgid "errors.clipboard-not-implemented" msgstr "Your browser cannot do this operation" #: 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." #: 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." #: src/app/main/data/tokens.cljs:294 From 40f69d320e6a0d46b148e4ec796310454549da6a Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 15:22:56 +0100 Subject: [PATCH 06/11] :sparkles: Show proper toast message on token-set rename error --- frontend/src/app/main/data/tokens.cljs | 19 ++++++++++--------- frontend/translations/en.po | 3 +++ frontend/translations/es.po | 3 +++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index e7f51dcfc2..e272fe193a 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -139,7 +139,11 @@ (let [data (dsh/lookup-file-data state) tokens-lib (get data :tokens-lib) set-name (ctob/normalize-set-name set-name)] - (when-not (ctob/get-set tokens-lib set-name) + (if (ctob/get-set tokens-lib set-name) + (rx/of (ntf/show {:content (tr "errors.token-set-already-exists") + :type :toast + :level :error + :timeout 9000})) (let [token-set (ctob/make-token-set :name set-name) changes (-> (pcb/empty-changes it) (pcb/with-library-data data) @@ -165,14 +169,11 @@ name (ctob/normalize-set-name name (:name token-set)) tokens-lib (get data :tokens-lib)] - (cond - (= (:name token-set) name) - nil - - (ctob/get-set tokens-lib name) - nil - - :else + (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/rename-token-set (:name token-set) name))] diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 1ceda7145d..8c9efd8770 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -1163,6 +1163,9 @@ msgstr "Your browser cannot do this operation" msgid "errors.drop-token-set-parent-to-child" 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 msgid "errors.token-set-exists-on-drop" msgstr "Cannot complete drop, a set with same name already exists at path %s." diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 56e0136e38..1ec6011973 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -7182,3 +7182,6 @@ msgstr "Soporte de Plugins" msgid "loader.tips.10.message" 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" From f2f492bf3fb42544e1cd62842988f0e968379919 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 15:48:00 +0100 Subject: [PATCH 07/11] :fire: Remove commented code --- common/src/app/common/types/tokens_lib.cljc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 0e2a331706..9a2d6b33ab 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -255,11 +255,6 @@ [name] (split-path name set-separator)) -;; (defn rename-token-set-preserving-group -;; [token-set name] -;; (let [base (butlast (get-path token-set)) - - (defn normalize-set-name "Normalize a set name. From 626c65df025a133c6c11e943caa9cae23f2e2a06 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 15:59:21 +0100 Subject: [PATCH 08/11] :fire: Remove unnecesary API from tokens lib Removes the `get-dtcg-tokens-tree` protocol method --- common/src/app/common/types/tokens_lib.cljc | 75 +++++++++++---------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 9a2d6b33ab..441e7a3aca 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -329,8 +329,7 @@ (get-token [_ token-name] "return token by token-name") (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")) + (get-tokens-tree [_] "returns a tree of tokens split & nested by their name path")) (defrecord TokenSet [name description modified-at tokens] ITokenSet @@ -381,14 +380,7 @@ (join-set-path))) (get-tokens-tree [_] - (tokens-tree tokens)) - - ;; FIXME: looks redundant - (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))))))) + (tokens-tree tokens))) (defn token-set? [o] @@ -1257,33 +1249,48 @@ Will return a value that matches this schema: (d/ordered-map) active-themes))) (encode-dtcg [this] - (let [themes (into [] - (comp - (filter #(and (instance? TokenTheme %) - (not (hidden-temporary-theme? %)))) - (map (fn [token-theme] - (let [theme-map (->> token-theme - (into {}) - walk/stringify-keys)] - (-> theme-map - (set/rename-keys {"sets" "selectedTokenSets"}) - (update "selectedTokenSets" (fn [sets] - (->> (for [s sets] - [s "enabled"]) - (into {}))))))))) - (tree-seq d/ordered-map? vals themes)) + (let [themes-xform + (comp + (filter #(and (instance? TokenTheme %) + (not (hidden-temporary-theme? %)))) + (map (fn [token-theme] + (let [theme-map (->> token-theme + (into {}) + walk/stringify-keys)] + (-> theme-map + (set/rename-keys {"sets" "selectedTokenSets"}) + (update "selectedTokenSets" (fn [sets] + (->> (for [s sets] [s "enabled"]) + (into {}))))))))) + themes + (->> (tree-seq d/ordered-map? vals themes) + (into [] themes-xform)) + ;; Active themes without exposing hidden penpot theme - active-themes-clear (disj active-themes hidden-token-theme-path) + active-themes-clear + (disj active-themes hidden-token-theme-path) - name-set-tuples (->> sets - (tree-seq d/ordered-map? vals) - (filter (partial instance? TokenSet)) - (map (fn [token-set] - [(:name token-set) (get-dtcg-tokens-tree token-set)]))) - ordered-set-names (mapv first name-set-tuples) - sets (into {} name-set-tuples) - active-sets (get-active-themes-set-names this)] + 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) + (filter (partial instance? TokenSet)) + (map (fn [{:keys [name tokens]}] + [name (tokens-tree tokens :update-token-fn update-token-fn)]))) + + ordered-set-names + (mapv first name-set-tuples) + + sets + (into {} name-set-tuples) + + active-sets + (get-active-themes-set-names this)] (-> sets (assoc "$themes" themes) From 5c3709b5d84c9343cc9e04d768163cbf97502674 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 16:00:20 +0100 Subject: [PATCH 09/11] :fire: Remove unused API from tokens-lib Removes the protocol method: `get-tokens-tree` --- common/src/app/common/types/tokens_lib.cljc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 441e7a3aca..e572e9446d 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -328,8 +328,7 @@ (delete-token [_ token-name] "delete a token from the list") (get-token [_ token-name] "return token by token-name") (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-set-prefixed-path-string [_] "convert set name to prefixed full path string")) (defrecord TokenSet [name description modified-at tokens] ITokenSet @@ -377,10 +376,7 @@ (get-set-prefixed-path-string [_] (-> (set-name->prefixed-full-path name) - (join-set-path))) - - (get-tokens-tree [_] - (tokens-tree tokens))) + (join-set-path)))) (defn token-set? [o] From 802c67ace4071ce8122acac367d2107b3b0c8d73 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 16:01:41 +0100 Subject: [PATCH 10/11] :fire: Remove unused API from tokens-lib Removes the protocol method: `get-set-prefixed-path-string` --- common/src/app/common/types/tokens_lib.cljc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index e572e9446d..4fa55c3ed6 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -327,8 +327,7 @@ (update-token [_ token-name f] "update a token in the list") (delete-token [_ token-name] "delete a token from the list") (get-token [_ token-name] "return token by token-name") - (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 [_] "return an ordered sequence of all tokens in the set")) (defrecord TokenSet [name description modified-at tokens] ITokenSet @@ -372,11 +371,7 @@ (get tokens token-name)) (get-tokens [_] - (vals tokens)) - - (get-set-prefixed-path-string [_] - (-> (set-name->prefixed-full-path name) - (join-set-path)))) + (vals tokens))) (defn token-set? [o] From 1e10e3818e7d5a3b1e3a553ea604f86d2aadc5bc Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 14 Mar 2025 16:48:31 +0100 Subject: [PATCH 11/11] :fire: Remove not necessary API from tokens-lib: add-sets --- common/src/app/common/files/changes.cljc | 11 ------- common/src/app/common/types/tokens_lib.cljc | 14 ++++---- .../common_tests/types/tokens_lib_test.cljc | 32 +++++++++---------- frontend/src/app/main/data/tokens.cljs | 2 +- .../ui/workspace/tokens/modals/themes.cljs | 11 ++++--- 5 files changed, 29 insertions(+), 41 deletions(-) diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index 1ef5f483da..a830bdefce 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -376,11 +376,6 @@ [:type [:= :update-active-token-themes]] [:theme-ids [:set :string]]]] - [:add-token-sets - [:map {:title "AddTokenSetsChange"} - [:type [:= :add-token-sets]] - [:token-sets [:sequential ::ctot/token-set]]]] - [:rename-token-set-group [:map {:title "RenameTokenSetGroup"} [:type [:= :rename-token-set-group]] @@ -1049,12 +1044,6 @@ (update data :tokens-lib #(-> % (ctob/ensure-tokens-lib) (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 [data {:keys [set-group-path set-group-fname]}] (update data :tokens-lib (fn [lib] diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 4fa55c3ed6..3cceedc30b 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -430,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 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-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") (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") @@ -875,9 +874,6 @@ Will return a value that matches this schema: themes active-themes))) - (add-sets [this token-sets] - (reduce add-set this token-sets)) - (update-set [this set-name f] (let [prefixed-full-path (set-name->prefixed-full-path set-name) set (get-in sets prefixed-full-path)] @@ -1483,10 +1479,12 @@ Will return a value that matches this schema: prev-sets (->> (fres/read-object! r) (tree-seq d/ordered-map? vals) (filter (partial instance? TokenSet))) - sets (-> (make-tokens-lib) - (add-sets prev-sets) - (deref) - :sets) + + ;; FIXME: wtf we usind deref here? + sets (-> (reduce add-set (make-tokens-lib) prev-sets) + (deref) + (:sets)) + _set-groups (fres/read-object! r) themes (fres/read-object! r) active-themes (fres/read-object! r)] diff --git a/common/test/common_tests/types/tokens_lib_test.cljc b/common/test/common_tests/types/tokens_lib_test.cljc index d568240110..ba9cb5f122 100644 --- a/common/test/common_tests/types/tokens_lib_test.cljc +++ b/common/test/common_tests/types/tokens_lib_test.cljc @@ -86,22 +86,22 @@ (t/deftest move-token-set (t/testing "flat" - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "A")) - (ctob/add-set (ctob/make-token-set :name "B")) - (ctob/add-set (ctob/make-token-set :name "Move"))) - move (fn [from-path to-path before-path before-group?] - (->> (ctob/move-set tokens-lib from-path to-path before-path before-group?) - (ctob/get-ordered-set-names) - (into [])))] - (t/testing "move to top" - (t/is (= ["Move" "A" "B"] (move ["Move"] ["Move"] ["A"] false)))) + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :name "A")) + (ctob/add-set (ctob/make-token-set :name "B")) + (ctob/add-set (ctob/make-token-set :name "Move"))) + move (fn [from-path to-path before-path before-group?] + (->> (ctob/move-set tokens-lib from-path to-path before-path before-group?) + (ctob/get-ordered-set-names) + (into [])))] + (t/testing "move to top" + (t/is (= ["Move" "A" "B"] (move ["Move"] ["Move"] ["A"] false)))) - (t/testing "move in-between" - (t/is (= ["A" "Move" "B"] (move ["Move"] ["Move"] ["B"] false)))) + (t/testing "move in-between" + (t/is (= ["A" "Move" "B"] (move ["Move"] ["Move"] ["B"] false)))) - (t/testing "move to bottom" - (t/is (= ["A" "B" "Move"] (move ["Move"] ["Move"] nil false)))))) + (t/testing "move to bottom" + (t/is (= ["A" "B" "Move"] (move ["Move"] ["Move"] nil false)))))) (t/testing "nested" (let [tokens-lib (-> (ctob/make-tokens-lib) @@ -129,7 +129,7 @@ (ctob/add-theme (ctob/make-token-theme :name "Theme" :sets #{"Foo/Bar/Baz"})) (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/deftest move-token-set-group (t/testing "reordering" @@ -590,7 +590,7 @@ :type :boolean :value true)) (ctob/add-theme (ctob/make-token-theme :name "test-token-theme")) - (ctob/toggle-set-in-theme "" "test-token-theme" "test-token-set")) + (ctob/toggle-set-in-theme "" "test-token-theme" "test-token-set")) encoded-blob (fres/encode tokens-lib) tokens-lib' (fres/decode encoded-blob)] diff --git a/frontend/src/app/main/data/tokens.cljs b/frontend/src/app/main/data/tokens.cljs index e272fe193a..ff6bd74e97 100644 --- a/frontend/src/app/main/data/tokens.cljs +++ b/frontend/src/app/main/data/tokens.cljs @@ -139,7 +139,7 @@ (let [data (dsh/lookup-file-data state) tokens-lib (get data :tokens-lib) set-name (ctob/normalize-set-name set-name)] - (if (ctob/get-set tokens-lib set-name) + (if (and tokens-lib (ctob/get-set tokens-lib set-name)) (rx/of (ntf/show {:content (tr "errors.token-set-already-exists") :type :toast :level :error diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 59eea1915f..0a2ba9f198 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -293,11 +293,12 @@ :on-save-form on-save-form :disabled? disabled?}]]]]])) -(defn- make-lib-with-theme [theme sets] - (-> (ctob/make-tokens-lib) - (ctob/add-theme theme) - (ctob/add-sets sets) - (ctob/activate-theme (:group theme) (:name theme)))) +(defn- make-lib-with-theme + [theme sets] + (let [tlib (-> (ctob/make-tokens-lib) + (ctob/add-theme theme)) + tlib (reduce ctob/add-set tlib sets)] + (ctob/activate-theme tlib (:group theme) (:name theme)))) (mf/defc controlled-edit-theme [{:keys [state set-state]}]