diff --git a/common/src/app/common/files/tokens.cljc b/common/src/app/common/files/tokens.cljc index 5408f08847..5557cee529 100644 --- a/common/src/app/common/files/tokens.cljc +++ b/common/src/app/common/files/tokens.cljc @@ -504,11 +504,13 @@ (defn get-active-themes "Return an ordered sequence of active themes" [tokens-status tokens-lib] + (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") + (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") (->> (ctob/get-themes tokens-lib) (filter #(ctos/theme-active? tokens-status (ctob/get-id %))))) (defn activate-theme - "Activate a theme and all its sets" + "Activate a theme and all its sets. Deactivate any other theme in the same group." [tokens-status tokens-lib id] (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") @@ -543,69 +545,117 @@ (deactivate-theme tokens-status tokens-lib id) (activate-theme tokens-status tokens-lib id))) -(defn set-active-themes - "Set the active themes and recalculate active sets." - [tokens-status tokens-lib theme-ids] - (assert (ctos/tokens-status? tokens-status)) - (assert (ctob/tokens-lib? tokens-lib)) - (assert (set? theme-ids)) - (let [active-set-ids (calculate-active-sets theme-ids tokens-lib)] - (ctos/set-tokens-status tokens-status theme-ids active-set-ids))) +(defn set-theme-active + "Set a theme's active state and update active sets accordingly." + [tokens-status tokens-lib id active?] + (if active? + (activate-theme tokens-status tokens-lib id) + (deactivate-theme tokens-status tokens-lib id))) -(defn get-active-set-names - "Return a set of active set names, resolved from TokensStatus + TokensLib." +(defn get-active-sets + "Return a clojure set of the active sets, resolved from TokensStatus + TokensLib." [tokens-status tokens-lib] + (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") + (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") (let [active-set-ids (ctos/get-active-set-ids tokens-status)] (into #{} - (comp (filter #(contains? active-set-ids (ctob/get-id %))) - (map ctob/get-name)) - (ctob/get-sets tokens-lib)))) + (comp (map #(ctob/get-set tokens-lib %)) + (filter some?)) + active-set-ids))) -(defn token-set-active? - "Check if a set (by name) is active." - [tokens-status tokens-lib set-name] - (let [active-set-names (get-active-set-names tokens-status tokens-lib)] - (contains? active-set-names set-name))) +(defn set-set-active + "Set directly a set's active state and deactivate all themes." + [tokens-status tokens-lib id active?] + (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") + (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") + (assert (uuid? id) "expected valid set id") + (if (and (ctob/get-set tokens-lib id) + (not= active? (ctos/set-active? tokens-status id))) + (let [active-set-ids (ctos/get-active-set-ids tokens-status) + active-set-ids' (if active? + (conj active-set-ids id) + (disj active-set-ids id))] + (ctos/set-tokens-status tokens-status #{} active-set-ids')) + tokens-status)) + +(defn activate-set + "Activate directly a set, and deactivate all themes." + [tokens-status tokens-lib id] + (set-set-active tokens-status tokens-lib id true)) + +(defn deactivate-set + "Deactivate directly a set, and deactivate all themes." + [tokens-status tokens-lib id] + (set-set-active tokens-status tokens-lib id false)) + +(defn toggle-set-active + "Toggle a set's active state and deactivate all themes." + [tokens-status tokens-lib id] + (set-set-active tokens-status tokens-lib id (not (ctos/set-active? tokens-status id)))) (defn sets-at-path-all-active? "Check active state of sets at a group path. Returns :none, :all, or :partial." [tokens-status tokens-lib group-path] - (let [active-set-names (get-active-set-names tokens-status tokens-lib) - path-sets (into #{} - (map ctob/get-name) - (ctob/get-sets-at-path tokens-lib group-path))] - (if (seq active-set-names) - (let [difference (set/difference path-sets active-set-names)] + (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") + (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") + (assert (vector? group-path) "expected valid group path") + (let [active-set-ids (ctos/get-active-set-ids tokens-status) + path-set-ids (into #{} + (map ctob/get-id) + (ctob/get-sets-at-path tokens-lib group-path))] + (if (seq active-set-ids) + (let [difference (set/difference path-set-ids active-set-ids)] (cond (empty? difference) :all - (seq (set/intersection path-sets active-set-names)) :partial + (seq (set/intersection path-set-ids active-set-ids)) :partial :else :none)) :none))) +(defn toggle-set-group-active + "Toggle the active state of all sets at a group path, and deactivate all themes. + If all sets are active, deactivate all. If none or some are active, activate all." + [tokens-status tokens-lib group-path] + (let [all-active? (sets-at-path-all-active? tokens-status tokens-lib group-path) + + sets-at-path (ctob/get-sets-at-path tokens-lib group-path) + set-ids-at-path (into #{} (map ctob/get-id) sets-at-path) + + active-set-ids (ctos/get-active-set-ids tokens-status) + active-set-ids' (if (contains? #{:all :partial} all-active?) + (set/difference active-set-ids set-ids-at-path) + (set/union active-set-ids set-ids-at-path))] + + (if (not= active-set-ids active-set-ids') + (ctos/set-tokens-status tokens-status #{} active-set-ids') + tokens-status))) + (defn get-tokens-in-active-sets "Get merged tokens from all active sets, in set order." [tokens-status tokens-lib] - (let [active-set-names (get-active-set-names tokens-status tokens-lib) - all-set-names (ctob/get-set-names tokens-lib) - ordered-active (filter active-set-names all-set-names)] - (reduce (fn [tokens set-name] - (let [set (ctob/get-set-by-name tokens-lib set-name)] - (merge tokens (ctob/get-tokens- set)))) + (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") + (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") + (let [active-set-ids (ctos/get-active-set-ids tokens-status) + all-set-ids (map ctob/get-id (ctob/get-sets tokens-lib)) + ordered-active (filter active-set-ids all-set-ids)] + (reduce (fn [tokens set-id] + (merge tokens (ctob/get-tokens tokens-lib set-id))) (d/ordered-map) ordered-active))) (defn get-tokens-in-active-sets-force "Same as get-tokens-in-active-sets but force-including a set by id." [tokens-status tokens-lib force-set-id] - (let [active-set-names (get-active-set-names tokens-status tokens-lib) - all-set-names (ctob/get-set-names tokens-lib) - force-set (ctob/get-set tokens-lib force-set-id) - ordered-active (cond-> (filter active-set-names all-set-names) - (some? force-set) - (conj (ctob/get-name force-set)))] - (reduce (fn [tokens set-name] - (let [set (ctob/get-set-by-name tokens-lib set-name)] + (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") + (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") + (assert (uuid? force-set-id) "expected valid set id") + (let [active-set-ids (ctos/get-active-set-ids tokens-status) + all-set-ids (map ctob/get-id (ctob/get-sets tokens-lib)) + ordered-active (cond-> (filter active-set-ids all-set-ids) + (some? force-set-id) + (conj force-set-id))] + (reduce (fn [tokens set-id] + (let [set (ctob/get-set tokens-lib set-id)] (merge tokens (ctob/get-tokens- set)))) (d/ordered-map) ordered-active))) @@ -614,6 +664,8 @@ "Synchronizes tokens status with the current tokens lib: - Delete any theme or set that no longer exists in the lib." [tokens-status tokens-lib] + (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") + (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") (let [active-theme-ids (ctos/get-active-theme-ids tokens-status) valid-theme-ids (into #{} (filter #(some? (ctob/get-theme tokens-lib %))) diff --git a/common/src/app/common/logic/tokens.cljc b/common/src/app/common/logic/tokens.cljc index 2194105044..483919560c 100644 --- a/common/src/app/common/logic/tokens.cljc +++ b/common/src/app/common/logic/tokens.cljc @@ -8,94 +8,11 @@ (:require [app.common.files.changes-builder :as pcb] [app.common.files.tokens :as cfo] - [app.common.types.tokens-lib :as ctob] - [app.common.types.tokens-status :as ctos] - [clojure.set :as set])) + [app.common.types.tokens-lib :as ctob])) -(defn- generate-update-active-sets - "Update active set ids in tokens-status by applying update-fn to the - current active set ids. Also deactivate all themes since this is a manual - set activation. Returns updated changes." - [changes tokens-status _tokens-lib update-fn] - (let [current-set-ids (ctos/get-active-set-ids tokens-status) - new-set-ids (update-fn current-set-ids) - tokens-status' (ctos/set-tokens-status tokens-status #{} new-set-ids)] - (pcb/set-tokens-status changes tokens-status'))) +;; Tokens lib -(defn generate-set-enabled-token-set - "Enable or disable a token set at `set-name` in `tokens-lib` without modifying a user theme." - [changes tokens-status tokens-lib set-name enabled?] - (let [set-id (ctob/get-id (ctob/get-set-by-name tokens-lib set-name))] - (if set-id - (if enabled? - (generate-update-active-sets changes tokens-status tokens-lib #(conj % set-id)) - (generate-update-active-sets changes tokens-status tokens-lib #(disj % set-id))) - changes))) - -(defn generate-toggle-token-set - "Toggle a token set at `set-name` in `tokens-lib` without modifying a user theme." - [changes tokens-status tokens-lib set-name] - (let [set-id (ctob/get-id (ctob/get-set-by-name tokens-lib set-name))] - (if set-id - (generate-update-active-sets changes tokens-status tokens-lib - #(if (contains? % set-id) (disj % set-id) (conj % set-id))) - changes))) - - -;; ================== nuevo - -(defn generate-activate-theme - [changes tokens-status tokens-lib id] - (let [tokens-status' (cfo/activate-theme tokens-status tokens-lib id)] - (if (not= tokens-status tokens-status') - (pcb/set-tokens-status changes tokens-status') - changes))) - -(defn generate-deactivate-theme - [changes tokens-status tokens-lib id] - (let [tokens-status' (cfo/deactivate-theme tokens-status tokens-lib id)] - (if (not= tokens-status tokens-status') - (pcb/set-tokens-status changes tokens-status') - changes))) - -(defn generate-set-theme-status - [changes tokens-status tokens-lib id active?] - (if active? - (generate-activate-theme changes tokens-status tokens-lib id) - (generate-deactivate-theme changes tokens-status tokens-lib id))) - -(defn generate-toggle-theme - [changes tokens-status tokens-lib id] - (let [active? (ctos/theme-active? tokens-status id)] - (if active? - (generate-deactivate-theme changes tokens-status tokens-lib id) - (generate-activate-theme changes tokens-status tokens-lib id)))) - -(defn generate-sync-tokens-status-with-lib - "Synchronizes tokens status with the current tokens lib" - [changes tokens-status tokens-lib] - (let [tokens-status' (cfo/sync-tokens-status-with-lib tokens-status tokens-lib)] - (if (not= tokens-status tokens-status') - (pcb/set-tokens-status changes tokens-status') - changes))) - -;; ======= fin nuevo - -(defn generate-toggle-token-set-group - "Toggle a token set group at `group-path` in `tokens-lib` without modifying a user theme." - [changes tokens-status tokens-lib group-path] - (let [sets-at-path (ctob/get-sets-at-path tokens-lib group-path) - set-ids (into #{} (map ctob/get-id) sets-at-path) - active? (cfo/sets-at-path-all-active? tokens-status tokens-lib group-path)] - (if (contains? #{:all :partial} active?) - ;; Deactivate all sets at path - (generate-update-active-sets changes tokens-status tokens-lib - #(set/difference % set-ids)) - ;; Activate all sets at path - (generate-update-active-sets changes tokens-status tokens-lib - #(set/union % set-ids))))) - -(defn vec-starts-with? [v1 v2] +(defn- vec-starts-with? [v1 v2] (= (subvec v1 0 (min (count v1) (count v2))) v2)) (defn- calculate-move-token-set-or-set-group @@ -191,3 +108,44 @@ (pcb/set-token-set changes (ctob/get-id set) nil)) changes sets))) + +;; Tokens Status + +(defn- update-tokens-status + [changes tokens-status update-fn & args] + (let [tokens-status' (apply update-fn tokens-status args)] + (if (not= tokens-status tokens-status') + (pcb/set-tokens-status changes tokens-status') + changes))) + +(defn generate-activate-theme + [changes tokens-status tokens-lib id] + (update-tokens-status changes tokens-status cfo/activate-theme tokens-lib id)) + +(defn generate-deactivate-theme + [changes tokens-status tokens-lib id] + (update-tokens-status changes tokens-status cfo/deactivate-theme tokens-lib id)) + +(defn generate-set-theme-status + [changes tokens-status tokens-lib id active?] + (update-tokens-status changes tokens-status cfo/set-theme-active tokens-lib id active?)) + +(defn generate-toggle-theme + [changes tokens-status tokens-lib id] + (update-tokens-status changes tokens-status cfo/toggle-theme-active tokens-lib id)) + +(defn generate-set-enabled-token-set + [changes tokens-status tokens-lib id enabled?] + (update-tokens-status changes tokens-status cfo/set-set-active tokens-lib id enabled?)) + +(defn generate-toggle-token-set + [changes tokens-status tokens-lib id] + (update-tokens-status changes tokens-status cfo/toggle-set-active tokens-lib id)) + +(defn generate-toggle-token-set-group + [changes tokens-status tokens-lib group-path] + (update-tokens-status changes tokens-status cfo/toggle-set-group-active tokens-lib group-path)) + +(defn generate-sync-tokens-status-with-lib + [changes tokens-status tokens-lib] + (update-tokens-status changes tokens-status cfo/sync-tokens-status-with-lib tokens-lib)) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index b8bb3564d5..41000ddcb5 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -480,11 +480,6 @@ [path] (mapv add-set-path-group-prefix path)) -(defn- set-group-path->set-group-prefixed-path-str - [path] - (-> (set-group-path->set-group-prefixed-path path) - (join-set-path))) - (defn add-set-group-prefix [group-path] (str set-group-prefix group-path)) @@ -548,7 +543,7 @@ "Get an ordered sequence of all sets names in the library") (get-set-tree [_] "Get a nested tree of all sets in the library") - (get-sets-at-path [_ path-str] + (get-sets-at-path [_ path-vec] "Get an ordered sequence of sets under `path` in the library")) (def ^:private schema:token-set-node @@ -1108,8 +1103,8 @@ (->> (tree-seq d/ordered-map? vals sets) (filter (partial instance? TokenSet)))) - (get-sets-at-path [_ path] - (some->> (map add-set-path-group-prefix path) + (get-sets-at-path [_ path-vec] + (some->> (map add-set-path-group-prefix path-vec) (get-in sets) (tree-seq d/ordered-map? vals) (filter (partial instance? TokenSet)))) diff --git a/common/test/common_tests/files/tokens_test.cljc b/common/test/common_tests/files/tokens_test.cljc index b6295a7c35..240e3962af 100644 --- a/common/test/common_tests/files/tokens_test.cljc +++ b/common/test/common_tests/files/tokens_test.cljc @@ -14,8 +14,110 @@ [app.common.types.tokens-lib :as ctob] [app.common.types.tokens-status :as ctos] [app.common.uuid :as uuid] + [clojure.datafy :refer [datafy]] [clojure.test :as t])) +;; Helper functions + +(t/deftest test-token-circular-reference? + (t/testing "returns nil when token has no references" + (let [tokens {"spacing" {:name "spacing" :value "16px"}}] + (t/is (nil? (cfo/token-circular-reference? tokens "spacing"))))) + + (t/testing "returns nil for a simple non-circular reference chain" + (let [tokens {"base" {:name "base" :value "10"} + "large" {:name "large" :value "{base}"}}] + (t/is (nil? (cfo/token-circular-reference? tokens "large"))))) + + (t/testing "detects direct self-reference" + (let [tokens {"self" {:name "self" :value "{self}"}}] + (t/is (= "self" (cfo/token-circular-reference? tokens "self"))))) + + (t/testing "detects indirect circular reference" + (let [tokens {"a" {:name "a" :value "{b}"} + "b" {:name "b" :value "{c}"} + "c" {:name "c" :value "{a}"}}] + (t/is (some? (cfo/token-circular-reference? tokens "a"))))) + + (t/testing "returns nil for diamond dependency (no cycle)" + (let [tokens {"base" {:name "base" :value "10"} + "left" {:name "left" :value "{base}"} + "right" {:name "right" :value "{base}"} + "combine" {:name "combine" :value "{left} {right}"}}] + (t/is (nil? (cfo/token-circular-reference? tokens "combine"))))) + + (t/testing "returns nil when token name does not exist in tokens map" + (let [tokens {"a" {:name "a" :value "10"}}] + (t/is (nil? (cfo/token-circular-reference? tokens "nonexistent"))))) + + (t/testing "detects circular reference in map-typed values (typography composite)" + (let [tokens {"family" {:name "family" :value "Arial"} + "size" {:name "size" :value "16px"} + "typog" {:name "typog" :value {:font-family {:reference "{family}"} + :font-size {:reference "{size}"}}} + "cycle" {:name "cycle" :value {:font-family {:reference "{typog}"}}}}] + ;; typog references family and size (no cycle) + (t/is (nil? (cfo/token-circular-reference? tokens "typog")))))) + +(t/deftest test-attributes-map + (t/testing "creates map from attributes to token name" + (t/is (= {:fill "primary" :stroke "primary"} + (cfo/attributes-map [:fill :stroke] {:name "primary"})))) + + (t/testing "returns empty map for empty attributes" + (t/is (= {} (cfo/attributes-map [] {:name "primary"})))) + + (t/testing "maps each attribute independently" + (t/is (= {:x "t" :y "t" :z "t"} + (cfo/attributes-map [:x :y :z] {:name "t"}))))) + +(t/deftest test-remove-attributes-for-token + (t/testing "removes entries matching both attribute set and token name" + (t/is (= {:stroke "other"} + (cfo/remove-attributes-for-token + [:fill :stroke] "primary" + {:fill "primary" :stroke "other"})))) + + (t/testing "keeps entries with matching attribute but different token name" + (t/is (= {:fill "secondary" :stroke "other"} + (cfo/remove-attributes-for-token + [:fill :stroke] "primary" + {:fill "secondary" :stroke "other"})))) + + (t/testing "keeps entries with matching token name but non-matching attribute" + (t/is (= {:opacity "primary"} + (cfo/remove-attributes-for-token + [:fill :stroke] "primary" + {:fill "primary" :opacity "primary"})))) + + (t/testing "returns empty map when all entries match" + (t/is (= {} + (cfo/remove-attributes-for-token + [:fill] "primary" + {:fill "primary"})))) + + (t/testing "returns empty map for empty applied-tokens" + (t/is (= {} + (cfo/remove-attributes-for-token [:fill] "primary" {}))))) + +(t/deftest test-color-token? + (t/testing "returns true for color type" + (t/is (true? (cfo/color-token? {:type :color})))) + + (t/testing "returns false for non-color types" + (t/is (false? (cfo/color-token? {:type :spacing}))) + (t/is (false? (cfo/color-token? {:type :border-radius}))) + (t/is (false? (cfo/color-token? {}))))) + +(t/deftest test-is-reference? + (t/testing "returns truthy when value contains opening brace" + (t/is (cfo/is-reference? {:value "{foo}"})) + (t/is (cfo/is-reference? {:value "calc({bar} + 1)"}))) + + (t/testing "returns falsy when value has no brace" + (t/is (not (cfo/is-reference? {:value "16px"}))) + (t/is (not (cfo/is-reference? {:value ""}))))) + (t/deftest test-parse-token-value (t/testing "parses double from a token value" (t/is (= {:value 100.1 :unit nil} (cfo/parse-token-value "100.1"))) @@ -100,7 +202,7 @@ {:applied-tokens {:x "a"}}] #{:y}))))) -;; Tokens lib +;; Tokens lib in file data (t/deftest test-ensure-tokens-lib (t/testing "ensure-tokens-lib should add a tokens-lib and tokens-status to the file data if they are missing" @@ -143,7 +245,7 @@ (t/is (not (contains? file-data' :tokens-lib))) (t/is (= tokens-file (:tokens-file file-data'))) (t/is (= tokens-status (:tokens-status file-data'))))) - + (t/testing "ensure-tokens-lib should not add a tokens-lib if there is a tokens-file, but should add a tokens-status if it's missing" (let [tokens-file (uuid/next) file (-> (thf/sample-file :file1) @@ -155,6 +257,41 @@ (t/is (contains? file-data' :tokens-status)) (t/is (ctos/tokens-status? (:tokens-status file-data')))))) +(t/deftest test-get-tokens-lib + (t/testing "returns tokens-lib from file data" + (let [tokens-lib (ctob/make-tokens-lib) + file-data {:tokens-lib tokens-lib}] + (t/is (= tokens-lib (cfo/get-tokens-lib file-data))))) + + (t/testing "returns nil when no tokens-lib" + (t/is (nil? (cfo/get-tokens-lib {}))))) + +(t/deftest test-get-tokens-file + (t/testing "returns tokens-file from file data" + (let [file-id (thi/new-id! :tokens-file) + file-data {:tokens-file file-id}] + (t/is (= file-id (cfo/get-tokens-file file-data))))) + + (t/testing "returns nil when no tokens-file" + (t/is (nil? (cfo/get-tokens-file {}))))) + +(t/deftest test-set-tokens-file + (t/testing "sets tokens-file on file data" + (let [file-id (thi/new-id! :tokens-file) + file-data {:other :data} + file-data' (cfo/set-tokens-file file-data file-id)] + (t/is (= file-id (:tokens-file file-data'))) + (t/is (= :data (:other file-data')))))) + +(t/deftest test-get-tokens-status + (t/testing "returns tokens-status from file data" + (let [tokens-status (ctos/make-tokens-status) + file-data {:tokens-status tokens-status}] + (t/is (= tokens-status (cfo/get-tokens-status file-data))))) + + (t/testing "returns nil when no tokens-status" + (t/is (nil? (cfo/get-tokens-status {}))))) + (t/deftest test-update-tokens-lib (t/testing "update when there is no tokens-lib has no effect" (let [file (thf/sample-file :file1) @@ -425,6 +562,409 @@ tokens-status' (cfo/deactivate-theme tokens-status tokens-lib (thi/new-id! :nonexistent))] (t/is (identical? tokens-status tokens-status'))))) +(t/deftest test-toggle-theme-active + (t/testing "activates an inactive theme" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-1) + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status) + tokens-status' (cfo/toggle-theme-active tokens-status tokens-lib (thi/id :theme-1))] + (t/is (ctos/theme-active? tokens-status' (thi/id :theme-1))))) + + (t/testing "deactivates an active theme" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-1) + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{(thi/id :theme-1)} + :active-set-ids #{(thi/id :set-a)}) + tokens-status' (cfo/toggle-theme-active tokens-status tokens-lib (thi/id :theme-1))] + (t/is (not (ctos/theme-active? tokens-status' (thi/id :theme-1))))))) + +(t/deftest test-set-theme-active + (t/testing "activates a theme when active? is true" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-1) + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status) + tokens-status' (cfo/set-theme-active tokens-status tokens-lib (thi/id :theme-1) true)] + (t/is (ctos/theme-active? tokens-status' (thi/id :theme-1))))) + + (t/testing "deactivates a theme when active? is false" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-1) + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{(thi/id :theme-1)} + :active-set-ids #{(thi/id :set-a)}) + tokens-status' (cfo/set-theme-active tokens-status tokens-lib (thi/id :theme-1) false)] + (t/is (not (ctos/theme-active? tokens-status' (thi/id :theme-1))))))) + +(t/deftest test-get-active-sets + (t/testing "returns active sets resolved from status and lib" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "set-b"))) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id}) + active-sets (cfo/get-active-sets tokens-status tokens-lib)] + (t/is (= 1 (count active-sets))) + (t/is (= set-a-id (ctob/get-id (first active-sets)))))) + + (t/testing "returns empty set when no sets are active" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))) + tokens-status (ctos/make-tokens-status) + active-sets (cfo/get-active-sets tokens-status tokens-lib)] + (t/is (empty? active-sets))))) + +(t/deftest test-set-set-active + (t/testing "activates a set and clears all themes" + (let [set-a-id (thi/new-id! :set-a) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id} + :active-set-ids #{}) + tokens-status' (cfo/set-set-active tokens-status tokens-lib set-a-id true)] + (t/is (ctos/set-active? tokens-status' set-a-id)) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status'))))) + + (t/testing "deactivates a set and clears all themes" + (let [set-a-id (thi/new-id! :set-a) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id} + :active-set-ids #{set-a-id}) + tokens-status' (cfo/set-set-active tokens-status tokens-lib set-a-id false)] + (t/is (not (ctos/set-active? tokens-status' set-a-id))) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status'))))) + + (t/testing "returns same status when set is already in target state" + (let [set-a-id (thi/new-id! :set-a) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a"))) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id}) + tokens-status' (cfo/set-set-active tokens-status tokens-lib set-a-id true)] + (t/is (identical? tokens-status tokens-status')))) + + (t/testing "returns same status for non-existent set" + (let [tokens-lib (ctob/make-tokens-lib) + tokens-status (ctos/make-tokens-status) + tokens-status' (cfo/set-set-active tokens-status tokens-lib (thi/new-id! :nonexistent) true)] + (t/is (identical? tokens-status tokens-status'))))) + +(t/deftest test-activate-set + (t/testing "delegates to set-set-active with true" + (let [set-a-id (thi/new-id! :set-a) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status) + tokens-status' (cfo/activate-set tokens-status tokens-lib set-a-id)] + (t/is (ctos/set-active? tokens-status' set-a-id)) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status')))))) + +(t/deftest test-deactivate-set + (t/testing "delegates to set-set-active with false" + (let [set-a-id (thi/new-id! :set-a) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id} + :active-set-ids #{set-a-id}) + tokens-status' (cfo/deactivate-set tokens-status tokens-lib set-a-id)] + (t/is (not (ctos/set-active? tokens-status' set-a-id))) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status')))))) + +(t/deftest test-toggle-set-active + (t/testing "activates an inactive set" + (let [set-a-id (thi/new-id! :set-a) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id} + :active-set-ids #{}) + tokens-status' (cfo/toggle-set-active tokens-status tokens-lib set-a-id)] + (t/is (ctos/set-active? tokens-status' set-a-id)) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status'))))) + + (t/testing "deactivates an active set" + (let [set-a-id (thi/new-id! :set-a) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id} + :active-set-ids #{set-a-id}) + tokens-status' (cfo/toggle-set-active tokens-status tokens-lib set-a-id)] + (t/is (not (ctos/set-active? tokens-status' set-a-id))) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status')))))) + +(t/deftest test-sets-at-path-all-active? + (t/testing "returns :all when all sets at path are active" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "group/set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "group/set-b"))) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id set-b-id})] + (t/is (= :all (cfo/sets-at-path-all-active? tokens-status tokens-lib ["group"]))))) + + (t/testing "returns :none when no sets at path are active" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "group/set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "group/set-b"))) + tokens-status (ctos/make-tokens-status :active-set-ids #{})] + (t/is (= :none (cfo/sets-at-path-all-active? tokens-status tokens-lib ["group"]))))) + + (t/testing "returns :partial when some sets at path are active" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "group/set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "group/set-b"))) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id})] + (t/is (= :partial (cfo/sets-at-path-all-active? tokens-status tokens-lib ["group"]))))) + + (t/testing "returns :none for empty path when no sets exist at root" + (let [tokens-lib (ctob/make-tokens-lib) + tokens-status (ctos/make-tokens-status)] + (t/is (= :none (cfo/sets-at-path-all-active? tokens-status tokens-lib []))))) + + (t/testing "several combinations with longer paths" + (let [baz-id (thi/new-id! :baz) + bam-id (thi/new-id! :bam) + none-id (thi/new-id! :none) + partial-id (thi/new-id! :partial) + all-id (thi/new-id! :all) + invalid-id (thi/new-id! :invalid) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id baz-id :name "foo/bar/baz")) + (ctob/add-set (ctob/make-token-set :id bam-id :name "foo/bar/bam")) + (ctob/add-theme (ctob/make-token-theme :id none-id + :name "none")) + (ctob/add-theme (ctob/make-token-theme :id partial-id + :name "partial" + :sets #{"foo/bar/baz"})) + (ctob/add-theme (ctob/make-token-theme :id all-id + :name "all" + :sets #{"foo/bar/baz" + "foo/bar/bam"})) + (ctob/add-theme (ctob/make-token-theme :id invalid-id + :name "invalid" + :sets #{"foo/missing"}))) + + expected-none (-> (ctos/make-tokens-status {:active-theme-ids #{none-id} + :active-set-ids #{}}) + (cfo/sets-at-path-all-active? tokens-lib ["foo"])) + expected-all (-> (ctos/make-tokens-status {:active-theme-ids #{all-id} + :active-set-ids #{baz-id bam-id}}) + (cfo/sets-at-path-all-active? tokens-lib ["foo"])) + expected-partial (-> (ctos/make-tokens-status {:active-theme-ids #{partial-id} + :active-set-ids #{baz-id}}) + (cfo/sets-at-path-all-active? tokens-lib ["foo"])) + expected-invalid-none (-> (ctos/make-tokens-status {:active-theme-ids #{invalid-id} + :active-set-ids #{}}) + (cfo/sets-at-path-all-active? tokens-lib ["foo"]))] + (t/is (= :none expected-none)) + (t/is (= :all expected-all)) + (t/is (= :partial expected-partial)) + (t/is (= :none expected-invalid-none))))) + +(t/deftest test-toggle-set-group-active + (t/testing "activates all sets in group when none are active, and deactivate all themes" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + set-c-id (thi/new-id! :set-c) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "group/set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "group/set-b")) + (ctob/add-set (ctob/make-token-set :id set-c-id :name "group/set-b/child")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id} + :active-set-ids #{}) + tokens-status' (cfo/toggle-set-group-active tokens-status tokens-lib ["group"])] + (t/is (ctos/set-active? tokens-status' set-a-id)) + (t/is (ctos/set-active? tokens-status' set-b-id)) + (t/is (ctos/set-active? tokens-status' set-c-id)) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status'))))) + + (t/testing "deactivates all sets in group when all are active, and deactivate all themes" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + set-c-id (thi/new-id! :set-c) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "group/set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "group/set-b")) + (ctob/add-set (ctob/make-token-set :id set-c-id :name "group/set-b/child")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{"group/set-a" "group/set-b" "group/set-b/child"}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id} + :active-set-ids #{set-a-id set-b-id set-c-id}) + tokens-status' (cfo/toggle-set-group-active tokens-status tokens-lib ["group"])] + (t/is (not (ctos/set-active? tokens-status' set-a-id))) + (t/is (not (ctos/set-active? tokens-status' set-b-id))) + (t/is (not (ctos/set-active? tokens-status' set-c-id))) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status'))))) + + (t/testing "deactivates all sets in group when only some are active, and deactivate all themes" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + set-c-id (thi/new-id! :set-c) + theme-1-id (thi/new-id! :theme-1) + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "group/set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "group/set-b")) + (ctob/add-set (ctob/make-token-set :id set-c-id :name "group/set-b/child")) + (ctob/add-theme (ctob/make-token-theme :id theme-1-id + :name "theme-1" + :group "" + :sets #{"set-a"}))) + tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id} + :active-set-ids #{set-a-id}) + tokens-status' (cfo/toggle-set-group-active tokens-status tokens-lib ["group"])] + (t/is (not (ctos/set-active? tokens-status' set-a-id))) + (t/is (not (ctos/set-active? tokens-status' set-b-id))) + (t/is (not (ctos/set-active? tokens-status' set-c-id))) + (t/is (= #{} (ctos/get-active-theme-ids tokens-status')))))) + +(t/deftest test-get-tokens-in-active-sets + (t/testing "returns merged tokens from active sets in set order" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tok-a (ctob/make-token :name "spacing" :type :spacing :value "8px") + tok-b (ctob/make-token :name "radius" :type :border-radius :value "4px") + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "set-b")) + (ctob/add-token set-a-id tok-a) + (ctob/add-token set-b-id tok-b)) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id set-b-id}) + tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] + (t/is (= 2 (count tokens))) + (t/is (contains? tokens "spacing")) + (t/is (contains? tokens "radius")))) + + (t/testing "later active sets override earlier sets with same token name" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tok-a (ctob/make-token :name "spacing" :type :spacing :value "8px") + tok-b (ctob/make-token :name "spacing" :type :spacing :value "16px") + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "set-b")) + (ctob/add-token set-a-id tok-a) + (ctob/add-token set-b-id tok-b)) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id set-b-id}) + tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] + (t/is (= 1 (count tokens))) + (t/is (= "16px" (:value (get tokens "spacing")))))) + + (t/testing "tokens in inactive sets are not included" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tok-a (ctob/make-token :name "spacing" :type :spacing :value "8px") + tok-b (ctob/make-token :name "spacing" :type :spacing :value "16px") + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "set-b")) + (ctob/add-token set-a-id tok-a) + (ctob/add-token set-b-id tok-b)) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id}) + tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] + (t/is (= 1 (count tokens))) + (t/is (= "8px" (:value (get tokens "spacing")))))) + + (t/testing "returns empty map when no sets are active" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a"))) + tokens-status (ctos/make-tokens-status) + tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] + (t/is (empty? tokens)))) + + (t/testing "returns empty map when empty lib" + (let [tokens-lib (ctob/make-tokens-lib) + tokens-status (ctos/make-tokens-status) + tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] + (t/is (empty? tokens))))) + +(t/deftest test-get-tokens-in-active-sets-force + (t/testing "includes force-set-id even when not in active sets" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tok-a (ctob/make-token :name "spacing" :type :spacing :value "8px") + tok-b (ctob/make-token :name "radius" :type :border-radius :value "4px") + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "set-b")) + (ctob/add-token set-a-id tok-a) + (ctob/add-token set-b-id tok-b)) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id}) + tokens (cfo/get-tokens-in-active-sets-force tokens-status tokens-lib set-b-id)] + (t/is (= 2 (count tokens))) + (t/is (contains? tokens "spacing")) + (t/is (contains? tokens "radius")))) + + (t/testing "active set tokens override force-set tokens with same name" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + tok-a (ctob/make-token :name "spacing" :type :spacing :value "8px") + tok-b (ctob/make-token :name "spacing" :type :spacing :value "32px") + tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "set-b")) + (ctob/add-token set-a-id tok-a) + (ctob/add-token set-b-id tok-b)) + tokens-status (ctos/make-tokens-status :active-set-ids #{set-a-id}) + tokens (cfo/get-tokens-in-active-sets-force tokens-status tokens-lib set-b-id)] + (t/is (= 1 (count tokens))) + (t/is (= "8px" (:value (get tokens "spacing"))))))) + (t/deftest test-sync-tokens-status-with-lib (t/testing "removes theme ids that no longer exist in the lib" (let [theme-1-id (thi/new-id! :theme-1) diff --git a/common/test/common_tests/logic/token_apply_test.cljc b/common/test/common_tests/logic/token_apply_test.cljc index f0509a0d28..2a6b6c398c 100644 --- a/common/test/common_tests/logic/token_apply_test.cljc +++ b/common/test/common_tests/logic/token_apply_test.cljc @@ -8,7 +8,6 @@ (:require [app.common.data :as d] [app.common.files.changes-builder :as pcb] - [app.common.files.tokens :as cfo] [app.common.logic.shapes :as cls] [app.common.test-helpers.compositions :as tho] [app.common.test-helpers.files :as thf] diff --git a/common/test/common_tests/logic/token_test.cljc b/common/test/common_tests/logic/token_test.cljc index 1fb3f188a3..7b53856574 100644 --- a/common/test/common_tests/logic/token_test.cljc +++ b/common/test/common_tests/logic/token_test.cljc @@ -18,363 +18,7 @@ (t/use-fixtures :each thi/test-fixture) -(t/deftest generate-toggle-token-set-test - (t/testing "toggling an active set will deactivate it" - (let [theme-id (uuid/next) - set-id (thi/new-id! :foo-bar) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-set (ctob/make-token-set :id set-id :name "foo/bar")) - (ctob/add-theme (ctob/make-token-theme :id theme-id - :name "theme" - :sets #{"foo/bar"}))) - :status-fn #(ctos/set-tokens-status % #{theme-id} #{set-id})) - tokens-status (tht/get-tokens-status file) - tokens-lib (tht/get-tokens-lib file) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (clt/generate-toggle-token-set tokens-status tokens-lib "foo/bar")) - - redo (thf/apply-changes file changes) - redo-status (tht/get-tokens-status redo) - undo (thf/apply-undo-changes redo changes) - undo-status (tht/get-tokens-status undo)] - ;; Redo: set is deactivated, all themes deactivated - (t/is (not (ctos/set-active? redo-status set-id))) - (t/is (= #{} (ctos/get-active-theme-ids redo-status))) - ;; Undo: set is active again, themes restored - (t/is (ctos/set-active? undo-status set-id)) - (t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status))))) - - (t/testing "toggling an inactive set will activate it" - (let [theme-id (uuid/next) - set-id (thi/new-id! :foo-bar) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-set (ctob/make-token-set :id set-id :name "foo/bar")) - (ctob/add-theme (ctob/make-token-theme :id theme-id - :name "theme" - :sets #{"foo/bar"}))) - :status-fn #(ctos/set-tokens-status % #{theme-id} #{})) - tokens-status (tht/get-tokens-status file) - tokens-lib (tht/get-tokens-lib file) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (clt/generate-toggle-token-set tokens-status tokens-lib "foo/bar")) - - redo (thf/apply-changes file changes) - redo-status (tht/get-tokens-status redo) - undo (thf/apply-undo-changes redo changes) - undo-status (tht/get-tokens-status undo)] - ;; Redo: set is activated, all themes deactivated - (t/is (ctos/set-active? redo-status set-id)) - (t/is (= #{} (ctos/get-active-theme-ids redo-status))) - ;; Undo: set is inactive again, themes restored - (t/is (not (ctos/set-active? undo-status set-id))) - (t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status))))) - - (t/testing "toggling a set group toggles its sets in status" - (let [set-id (thi/new-id! :foo-bar) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-set (ctob/make-token-set :id set-id :name "foo/bar")))) - - tokens-status (tht/get-tokens-status file) - tokens-lib (tht/get-tokens-lib file) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (clt/generate-toggle-token-set-group tokens-status tokens-lib ["foo"])) - - redo (thf/apply-changes file changes) - redo-status (tht/get-tokens-status redo) - undo (thf/apply-undo-changes redo changes) - undo-status (tht/get-tokens-status undo)] - ;; Redo: set is activated - (t/is (ctos/set-active? redo-status set-id)) - ;; Undo: set is deactivated - (t/is (not (ctos/set-active? undo-status set-id)))))) - -(t/deftest set-token-theme-test - (t/testing "delete token theme" - (let [theme-id (uuid/next) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-theme (ctob/make-token-theme :id theme-id - :name "foo" - :group "main")))) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token-theme theme-id nil)) - - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo)] - ;; Redo - (t/is (nil? (ctob/get-theme redo-lib theme-id))) - ;; Undo - (t/is (some? (ctob/get-theme undo-lib theme-id))))) - - (t/testing "add token theme" - (let [theme-id (uuid/next) - theme (ctob/make-token-theme :id theme-id - :name "foo" - :group "main") - file (tht/sample-file-with-tokens) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token-theme theme-id theme)) - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo)] - ;; Redo - (t/is (some? (ctob/get-theme redo-lib theme-id))) - ;; Undo - (t/is (nil? (ctob/get-theme undo-lib theme-id))))) - - (t/testing "update token theme" - (let [theme-id (uuid/next) - prev-theme-name "foo" - prev-theme (ctob/make-token-theme :id theme-id - :name prev-theme-name - :group "main") - file (tht/sample-file-with-tokens - :lib-fn #(ctob/add-theme % prev-theme)) - new-theme-name "foo1" - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token-theme theme-id (ctob/rename prev-theme new-theme-name))) - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - redo-theme (ctob/get-theme redo-lib theme-id) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo) - undo-theme (ctob/get-theme undo-lib theme-id)] - ;; Redo - (t/is (= new-theme-name (ctob/get-name redo-theme))) - ;; Undo - (t/is (= prev-theme-name (ctob/get-name undo-theme))))) - - (t/testing "toggling token theme updates using changes history" - (let [theme-id (uuid/next) - theme (ctob/make-token-theme :id theme-id - :name "foo-theme" - :group "main") - set-name "bar-set" - token-set (ctob/make-token-set :name set-name) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-theme theme) - (ctob/add-set token-set))) - theme' (assoc theme :sets #{set-name}) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token-theme theme-id theme')) - changed-file (-> file - (thf/apply-changes changes) - (thf/apply-undo-changes changes) - (thf/apply-changes changes)) - changed-lib (tht/get-tokens-lib changed-file)] - (t/is (= #{set-name} - (-> changed-lib (ctob/get-theme theme-id) :sets)))))) - -(t/deftest set-token-test - (t/testing "delete token" - (let [set-name "foo" - set-id (uuid/next) - token-id (uuid/next) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-set (ctob/make-token-set :id set-id - :name set-name)) - (ctob/add-token set-id (ctob/make-token {:name "to.delete.color.red" - :id token-id - :value "red" - :type :color})))) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token set-id token-id nil)) - - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo)] - (t/is (nil? (ctob/get-token redo-lib set-id token-id))) - ;; Undo - (t/is (some? (ctob/get-token undo-lib set-id token-id))))) - - (t/testing "add token" - (let [set-name "foo" - set-id (uuid/next) - token (ctob/make-token {:name "to.add.color.red" - :value "red" - :type :color}) - file (tht/sample-file-with-tokens - :lib-fn #(-> % (ctob/add-set (ctob/make-token-set :id set-id - :name set-name)))) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token set-id (:id token) token)) - - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo)] - (t/is (= token (ctob/get-token redo-lib set-id (:id token)))) - ;; Undo - (t/is (nil? (ctob/get-token undo-lib set-id (:id token)))))) - - (t/testing "update token" - (let [set-name "foo" - set-id (uuid/next) - prev-token (ctob/make-token {:name "to.update.color.red" - :value "red" - :type :color}) - token (-> prev-token - (assoc :name "color.red.changed") - (assoc :value "blue")) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-set (ctob/make-token-set :id set-id - :name set-name)) - (ctob/add-token set-id prev-token))) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token set-id (:id prev-token) token)) - - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo)] - (t/is (tht/token-data-eq? token (ctob/get-token redo-lib set-id (:id token)))) - ;; Undo - (t/is (tht/token-data-eq? prev-token (ctob/get-token undo-lib set-id (:id prev-token))))))) - -(t/deftest set-token-set-test - (t/testing "delete token set" - (let [set-name "foo" - set-id (uuid/next) - file (tht/sample-file-with-tokens - :lib-fn #(ctob/add-set % (ctob/make-token-set :id set-id :name set-name))) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token-set set-id nil)) - - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo)] - (t/is (not (ctob/set-path-exists? redo-lib [set-name]))) - ;; Undo - (t/is (ctob/set-path-exists? undo-lib [set-name])))) - - (t/testing "add token set" - (let [set-name "foo" - set-id (uuid/next) - token-set (ctob/make-token-set :id set-id :name set-name) - file (tht/sample-file-with-tokens) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token-set set-id token-set)) - - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo)] - (t/is (not (ctob/set-path-exists? undo-lib [set-name]))) - ;; Undo - (t/is (ctob/set-path-exists? redo-lib [set-name])))) - - (t/testing "update token set" - (let [set-name "foo" - set-id (uuid/next) - token-set (ctob/make-token-set :id set-id :name set-name) - file (tht/sample-file-with-tokens - :lib-fn #(-> (ctob/add-set % token-set))) - new-set-name "foo1" - - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (pcb/set-token-set set-id (ctob/rename token-set new-set-name))) - - redo (thf/apply-changes file changes) - redo-lib (tht/get-tokens-lib redo) - redo-token-set (ctob/get-set redo-lib set-id) - - undo (thf/apply-undo-changes redo changes) - undo-lib (tht/get-tokens-lib undo) - undo-token-set (ctob/get-set undo-lib set-id)] - - (t/is (= (ctob/get-name redo-token-set) new-set-name)) - ;; Undo - (t/is (= (ctob/get-name undo-token-set) set-name))))) - -(t/deftest generate-toggle-token-set-group-test - (t/testing "toggling set group with no active sets inside will activate all child sets" - (let [set-bar-id (thi/new-id! :foo-bar) - set-baz-id (thi/new-id! :foo-bar-baz) - set-child-id (thi/new-id! :baz-child) - theme-id (uuid/next) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-set (ctob/make-token-set :id set-bar-id :name "foo/bar")) - (ctob/add-set (ctob/make-token-set :id set-baz-id :name "foo/bar/baz")) - (ctob/add-set (ctob/make-token-set :id set-child-id :name "foo/bar/baz/baz-child")) - (ctob/add-theme (ctob/make-token-theme :id theme-id :name "theme"))) - :status-fn #(ctos/set-tokens-status % #{theme-id} #{})) - tokens-status (tht/get-tokens-status file) - tokens-lib (tht/get-tokens-lib file) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (clt/generate-toggle-token-set-group tokens-status tokens-lib ["foo" "bar"])) - - redo (thf/apply-changes file changes) - redo-status (tht/get-tokens-status redo) - undo (thf/apply-undo-changes redo changes) - undo-status (tht/get-tokens-status undo)] - ;; Redo: all child sets activated, all themes deactivated - (t/is (ctos/set-active? redo-status set-baz-id)) - (t/is (ctos/set-active? redo-status set-child-id)) - (t/is (= #{} (ctos/get-active-theme-ids redo-status))) - ;; Undo: child sets deactivated, themes restored - (t/is (not (ctos/set-active? undo-status set-baz-id))) - (t/is (not (ctos/set-active? undo-status set-child-id))) - (t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status)))))) - - (t/testing "toggling set group with partially active sets inside will deactivate all child sets" - (let [set-bar-id (thi/new-id! :foo-bar) - set-baz-id (thi/new-id! :foo-bar-baz) - set-child-id (thi/new-id! :baz-child) - theme-id (uuid/next) - file (tht/sample-file-with-tokens - :lib-fn #(-> % - (ctob/add-set (ctob/make-token-set :id set-bar-id :name "foo/bar")) - (ctob/add-set (ctob/make-token-set :id set-baz-id :name "foo/bar/baz")) - (ctob/add-set (ctob/make-token-set :id set-child-id :name "foo/bar/baz/baz-child")) - (ctob/add-theme (ctob/make-token-theme :id theme-id - :name "theme" - :sets #{"foo/bar/baz"}))) - :status-fn #(ctos/set-tokens-status % #{theme-id} #{set-baz-id})) - - tokens-status (tht/get-tokens-status file) - tokens-lib (tht/get-tokens-lib file) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (clt/generate-toggle-token-set-group tokens-status tokens-lib ["foo" "bar"])) - - redo (thf/apply-changes file changes) - redo-status (tht/get-tokens-status redo) - undo (thf/apply-undo-changes redo changes) - undo-status (tht/get-tokens-status undo)] - ;; Redo: all child sets deactivated, all themes deactivated - (t/is (not (ctos/set-active? redo-status set-baz-id))) - (t/is (not (ctos/set-active? redo-status set-child-id))) - (t/is (= #{} (ctos/get-active-theme-ids redo-status))) - ;; Undo: restores previous state, themes restored - (t/is (ctos/set-active? undo-status set-baz-id)) - (t/is (not (ctos/set-active? undo-status set-child-id))) - (t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status))))) +;; Tokens lib (t/deftest generate-move-token-set-test (t/testing "Ignore dropping set to the same position:" @@ -628,6 +272,283 @@ :position :bot}) #"move token set error: parent-to-child")))))))) +(t/deftest generate-delete-token-set-group-test + (t/testing "deletes all sets under the given group path" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + set-c-id (thi/new-id! :set-c) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-a-id :name "group/set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "group/set-b")) + (ctob/add-set (ctob/make-token-set :id set-c-id :name "other/set-c")))) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-delete-token-set-group tokens-lib ["group"])) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + ;; Redo: group sets deleted, other set remains + (t/is (not (ctob/set-path-exists? redo-lib ["group" "set-a"]))) + (t/is (not (ctob/set-path-exists? redo-lib ["group" "set-b"]))) + (t/is (ctob/set-path-exists? redo-lib ["other" "set-c"])) + ;; Undo: group sets restored + (t/is (ctob/set-path-exists? undo-lib ["group" "set-a"])) + (t/is (ctob/set-path-exists? undo-lib ["group" "set-b"])))) + + (t/testing "deleting a group with nested subgroups deletes all descendant sets" + (let [set-a-id (thi/new-id! :set-a) + set-b-id (thi/new-id! :set-b) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-a-id :name "group/sub/set-a")) + (ctob/add-set (ctob/make-token-set :id set-b-id :name "group/set-b")))) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-delete-token-set-group tokens-lib ["group"])) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + ;; Redo: all group sets deleted + (t/is (not (ctob/set-path-exists? redo-lib ["group" "sub" "set-a"]))) + (t/is (not (ctob/set-path-exists? redo-lib ["group" "set-b"]))) + ;; Undo: all restored + (t/is (ctob/set-path-exists? undo-lib ["group" "sub" "set-a"])) + (t/is (ctob/set-path-exists? undo-lib ["group" "set-b"])))) + + (t/testing "deleting an empty group produces no changes" + (let [file (tht/sample-file-with-tokens + :lib-fn #(ctob/add-set % (ctob/make-token-set :name "other/set-a"))) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-delete-token-set-group tokens-lib ["nonexistent"]))] + (t/is (= [] (:redo-changes changes)))))) + +(t/deftest set-token-theme-test + (t/testing "delete token theme" + (let [theme-id (uuid/next) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-theme (ctob/make-token-theme :id theme-id + :name "foo" + :group "main")))) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token-theme theme-id nil)) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + ;; Redo + (t/is (nil? (ctob/get-theme redo-lib theme-id))) + ;; Undo + (t/is (some? (ctob/get-theme undo-lib theme-id))))) + + (t/testing "add token theme" + (let [theme-id (uuid/next) + theme (ctob/make-token-theme :id theme-id + :name "foo" + :group "main") + file (tht/sample-file-with-tokens) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token-theme theme-id theme)) + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + ;; Redo + (t/is (some? (ctob/get-theme redo-lib theme-id))) + ;; Undo + (t/is (nil? (ctob/get-theme undo-lib theme-id))))) + + (t/testing "update token theme" + (let [theme-id (uuid/next) + prev-theme-name "foo" + prev-theme (ctob/make-token-theme :id theme-id + :name prev-theme-name + :group "main") + file (tht/sample-file-with-tokens + :lib-fn #(ctob/add-theme % prev-theme)) + new-theme-name "foo1" + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token-theme theme-id (ctob/rename prev-theme new-theme-name))) + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + redo-theme (ctob/get-theme redo-lib theme-id) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo) + undo-theme (ctob/get-theme undo-lib theme-id)] + ;; Redo + (t/is (= new-theme-name (ctob/get-name redo-theme))) + ;; Undo + (t/is (= prev-theme-name (ctob/get-name undo-theme))))) + + (t/testing "toggling token theme updates using changes history" + (let [theme-id (uuid/next) + theme (ctob/make-token-theme :id theme-id + :name "foo-theme" + :group "main") + set-name "bar-set" + token-set (ctob/make-token-set :name set-name) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-theme theme) + (ctob/add-set token-set))) + theme' (assoc theme :sets #{set-name}) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token-theme theme-id theme')) + changed-file (-> file + (thf/apply-changes changes) + (thf/apply-undo-changes changes) + (thf/apply-changes changes)) + changed-lib (tht/get-tokens-lib changed-file)] + (t/is (= #{set-name} + (-> changed-lib (ctob/get-theme theme-id) :sets)))))) + +(t/deftest set-token-test + (t/testing "delete token" + (let [set-name "foo" + set-id (uuid/next) + token-id (uuid/next) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-id + :name set-name)) + (ctob/add-token set-id (ctob/make-token {:name "to.delete.color.red" + :id token-id + :value "red" + :type :color})))) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token set-id token-id nil)) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + (t/is (nil? (ctob/get-token redo-lib set-id token-id))) + ;; Undo + (t/is (some? (ctob/get-token undo-lib set-id token-id))))) + + (t/testing "add token" + (let [set-name "foo" + set-id (uuid/next) + token (ctob/make-token {:name "to.add.color.red" + :value "red" + :type :color}) + file (tht/sample-file-with-tokens + :lib-fn #(-> % (ctob/add-set (ctob/make-token-set :id set-id + :name set-name)))) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token set-id (:id token) token)) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + (t/is (= token (ctob/get-token redo-lib set-id (:id token)))) + ;; Undo + (t/is (nil? (ctob/get-token undo-lib set-id (:id token)))))) + + (t/testing "update token" + (let [set-name "foo" + set-id (uuid/next) + prev-token (ctob/make-token {:name "to.update.color.red" + :value "red" + :type :color}) + token (-> prev-token + (assoc :name "color.red.changed") + (assoc :value "blue")) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-id + :name set-name)) + (ctob/add-token set-id prev-token))) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token set-id (:id prev-token) token)) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + (t/is (tht/token-data-eq? token (ctob/get-token redo-lib set-id (:id token)))) + ;; Undo + (t/is (tht/token-data-eq? prev-token (ctob/get-token undo-lib set-id (:id prev-token))))))) + +(t/deftest set-token-set-test + (t/testing "delete token set" + (let [set-name "foo" + set-id (uuid/next) + file (tht/sample-file-with-tokens + :lib-fn #(ctob/add-set % (ctob/make-token-set :id set-id :name set-name))) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token-set set-id nil)) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + (t/is (not (ctob/set-path-exists? redo-lib [set-name]))) + ;; Undo + (t/is (ctob/set-path-exists? undo-lib [set-name])))) + + (t/testing "add token set" + (let [set-name "foo" + set-id (uuid/next) + token-set (ctob/make-token-set :id set-id :name set-name) + file (tht/sample-file-with-tokens) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token-set set-id token-set)) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo)] + (t/is (not (ctob/set-path-exists? undo-lib [set-name]))) + ;; Undo + (t/is (ctob/set-path-exists? redo-lib [set-name])))) + + (t/testing "update token set" + (let [set-name "foo" + set-id (uuid/next) + token-set (ctob/make-token-set :id set-id :name set-name) + file (tht/sample-file-with-tokens + :lib-fn #(-> (ctob/add-set % token-set))) + new-set-name "foo1" + + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (pcb/set-token-set set-id (ctob/rename token-set new-set-name))) + + redo (thf/apply-changes file changes) + redo-lib (tht/get-tokens-lib redo) + redo-token-set (ctob/get-set redo-lib set-id) + + undo (thf/apply-undo-changes redo changes) + undo-lib (tht/get-tokens-lib undo) + undo-token-set (ctob/get-set undo-lib set-id)] + + (t/is (= (ctob/get-name redo-token-set) new-set-name)) + ;; Undo + (t/is (= (ctob/get-name undo-token-set) set-name))))) + +;; Tokens Status + (t/deftest generate-activate-theme-test (t/testing "activating an inactive theme creates changes" (let [set-id (uuid/next) @@ -668,17 +589,8 @@ changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) (clt/generate-activate-theme tokens-status tokens-lib theme-id))] - (t/is (= [] (:redo-changes changes))))) - - (t/testing "activating a non-existent theme returns same changes" - (let [non-existent-id (uuid/next) - file (tht/sample-file-with-tokens) - tokens-status (tht/get-tokens-status file) - tokens-lib (tht/get-tokens-lib file) - changes (-> (pcb/empty-changes) - (pcb/with-library-data (:data file)) - (clt/generate-activate-theme tokens-status tokens-lib non-existent-id))] - (t/is (= [] (:redo-changes changes)))))) + (t/is (= [] (:redo-changes changes))) + (t/is (= [] (:undo-changes changes)))))) (t/deftest generate-deactivate-theme-test (t/testing "deactivating an active theme creates changes" @@ -716,7 +628,8 @@ changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) (clt/generate-deactivate-theme tokens-status tokens-lib theme-id))] - (t/is (= [] (:redo-changes changes)))))) + (t/is (= [] (:redo-changes changes))) + (t/is (= [] (:undo-changes changes)))))) (t/deftest generate-set-theme-status-test (t/testing "setting active? to true activates the theme" @@ -732,25 +645,28 @@ (pcb/with-library-data (:data file)) (clt/generate-set-theme-status tokens-status tokens-lib theme-id true)) file' (thf/apply-changes file changes) - tokens-status' (tht/get-tokens-status file')] - (t/is (ctos/theme-active? tokens-status' theme-id)))) + tokens-status' (tht/get-tokens-status file') + file'' (thf/apply-undo-changes file changes) + tokens-status'' (tht/get-tokens-status file'')] + ;; Redo: theme is active + (t/is (ctos/theme-active? tokens-status' theme-id)) + ;; Undo: theme is inactive + (t/is (not (ctos/theme-active? tokens-status'' theme-id))))) - (t/testing "setting active? to false deactivates the theme" + (t/testing "setting active? to same state returns same changes" (let [theme-id (uuid/next) file (tht/sample-file-with-tokens :lib-fn #(-> % (ctob/add-theme (ctob/make-token-theme :id theme-id :name "t1" - :sets #{}))) - :status-fn #(ctos/set-tokens-status % #{theme-id} #{})) + :sets #{})))) tokens-status (tht/get-tokens-status file) tokens-lib (tht/get-tokens-lib file) changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) - (clt/generate-set-theme-status tokens-status tokens-lib theme-id false)) - file' (thf/apply-changes file changes) - tokens-status' (tht/get-tokens-status file')] - (t/is (not (ctos/theme-active? tokens-status' theme-id)))))) + (clt/generate-set-theme-status tokens-status tokens-lib theme-id false))] + (t/is (= [] (:redo-changes changes))) + (t/is (= [] (:undo-changes changes)))))) (t/deftest generate-toggle-theme-test (t/testing "toggling an active theme deactivates it" @@ -775,7 +691,7 @@ ;; Undo: theme is active again (t/is (ctos/theme-active? tokens-status'' theme-id)))) - (t/testing "toggling an inactive theme activates it" + (t/testing "toggling an inexistent theme returns same changes" (let [theme-id (uuid/next) file (tht/sample-file-with-tokens :lib-fn #(-> % @@ -786,15 +702,151 @@ tokens-lib (tht/get-tokens-lib file) changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) - (clt/generate-toggle-theme tokens-status tokens-lib theme-id)) - file' (thf/apply-changes file changes) - tokens-status' (tht/get-tokens-status file') - file'' (thf/apply-undo-changes file' changes) - tokens-status'' (tht/get-tokens-status file'')] - ;; Redo: theme is active - (t/is (ctos/theme-active? tokens-status' theme-id)) - ;; Undo: theme is inactive - (t/is (not (ctos/theme-active? tokens-status'' theme-id)))))) + (clt/generate-toggle-theme tokens-status tokens-lib (uuid/next)))] + (t/is (= [] (:redo-changes changes))) + (t/is (= [] (:undo-changes changes)))))) + +(t/deftest generate-set-enabled-token-set-test + (t/testing "enabling an inactive set creates changes that activate it and clear themes" + (let [set-id (thi/new-id! :set-a) + theme-id (uuid/next) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-id :name "set-a")) + (ctob/add-theme (ctob/make-token-theme :id theme-id + :name "theme" + :sets #{"set-a"}))) + :status-fn #(ctos/set-tokens-status % #{theme-id} #{})) + tokens-status (tht/get-tokens-status file) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-set-enabled-token-set tokens-status tokens-lib set-id true)) + + redo (thf/apply-changes file changes) + redo-status (tht/get-tokens-status redo) + undo (thf/apply-undo-changes redo changes) + undo-status (tht/get-tokens-status undo)] + ;; Redo: set active, themes cleared + (t/is (ctos/set-active? redo-status set-id)) + (t/is (= #{} (ctos/get-active-theme-ids redo-status))) + ;; Undo: set inactive, themes restored + (t/is (not (ctos/set-active? undo-status set-id))) + (t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status))))) + + (t/testing "enabling an already-active set returns no changes" + (let [set-id (thi/new-id! :set-a) + file (tht/sample-file-with-tokens + :lib-fn #(ctob/add-set % (ctob/make-token-set :id set-id :name "set-a")) + :status-fn #(ctos/set-tokens-status % #{} #{set-id})) + tokens-status (tht/get-tokens-status file) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-set-enabled-token-set tokens-status tokens-lib set-id true))] + (t/is (= [] (:redo-changes changes))) + (t/is (= [] (:undo-changes changes)))))) + +(t/deftest generate-toggle-token-set-test + (t/testing "toggling an active set will deactivate it" + (let [theme-id (uuid/next) + set-id (thi/new-id! :foo-bar) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-id :name "foo/bar")) + (ctob/add-theme (ctob/make-token-theme :id theme-id + :name "theme" + :sets #{"foo/bar"}))) + :status-fn #(ctos/set-tokens-status % #{theme-id} #{set-id})) + tokens-status (tht/get-tokens-status file) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-toggle-token-set tokens-status tokens-lib set-id)) + + redo (thf/apply-changes file changes) + redo-status (tht/get-tokens-status redo) + undo (thf/apply-undo-changes redo changes) + undo-status (tht/get-tokens-status undo)] + ;; Redo: set is deactivated, all themes deactivated + (t/is (not (ctos/set-active? redo-status set-id))) + (t/is (= #{} (ctos/get-active-theme-ids redo-status))) + ;; Undo: set is active again, themes restored + (t/is (ctos/set-active? undo-status set-id)) + (t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status))))) + + (t/testing "toggling an inexistent set will return no changes" + (let [theme-id (uuid/next) + set-id (thi/new-id! :foo-bar) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-id :name "foo/bar")) + (ctob/add-theme (ctob/make-token-theme :id theme-id + :name "theme" + :sets #{"foo/bar"}))) + :status-fn #(ctos/set-tokens-status % #{theme-id} #{})) + tokens-status (tht/get-tokens-status file) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-toggle-token-set tokens-status tokens-lib (uuid/next)))] + (t/is (= [] (:redo-changes changes))) + (t/is (= [] (:undo-changes changes)))))) + +(t/deftest generate-toggle-token-set-group-test + (t/testing "toggling set group with no active sets inside will activate all child sets" + (let [set-bar-id (thi/new-id! :foo-bar) + set-baz-id (thi/new-id! :foo-bar-baz) + set-child-id (thi/new-id! :baz-child) + theme-id (uuid/next) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-bar-id :name "foo/bar")) + (ctob/add-set (ctob/make-token-set :id set-baz-id :name "foo/bar/baz")) + (ctob/add-set (ctob/make-token-set :id set-child-id :name "foo/bar/baz/baz-child")) + (ctob/add-theme (ctob/make-token-theme :id theme-id :name "theme"))) + :status-fn #(ctos/set-tokens-status % #{theme-id} #{})) + tokens-status (tht/get-tokens-status file) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-toggle-token-set-group tokens-status tokens-lib ["foo" "bar"])) + + redo (thf/apply-changes file changes) + redo-status (tht/get-tokens-status redo) + undo (thf/apply-undo-changes redo changes) + undo-status (tht/get-tokens-status undo)] + ;; Redo: all child sets activated, all themes deactivated + (t/is (ctos/set-active? redo-status set-baz-id)) + (t/is (ctos/set-active? redo-status set-child-id)) + (t/is (= #{} (ctos/get-active-theme-ids redo-status))) + ;; Undo: child sets deactivated, themes restored + (t/is (not (ctos/set-active? undo-status set-baz-id))) + (t/is (not (ctos/set-active? undo-status set-child-id))) + (t/is (= #{theme-id} (ctos/get-active-theme-ids undo-status))))) + + (t/testing "toggling an inexistent set group will return no changes" + (let [set-bar-id (thi/new-id! :foo-bar) + set-baz-id (thi/new-id! :foo-bar-baz) + set-child-id (thi/new-id! :baz-child) + theme-id (uuid/next) + file (tht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id set-bar-id :name "foo/bar")) + (ctob/add-set (ctob/make-token-set :id set-baz-id :name "foo/bar/baz")) + (ctob/add-set (ctob/make-token-set :id set-child-id :name "foo/bar/baz/baz-child")) + (ctob/add-theme (ctob/make-token-theme :id theme-id + :name "theme" + :sets #{"foo/bar/baz"}))) + :status-fn #(ctos/set-tokens-status % #{theme-id} #{set-baz-id})) + + tokens-status (tht/get-tokens-status file) + tokens-lib (tht/get-tokens-lib file) + changes (-> (pcb/empty-changes) + (pcb/with-library-data (:data file)) + (clt/generate-toggle-token-set-group tokens-status tokens-lib ["foo" "nonexistent"]))] + (t/is (= [] (:redo-changes changes))) + (t/is (= [] (:undo-changes changes)))))) (t/deftest generate-sync-tokens-status-with-lib-test (t/testing "sync removes stale theme and set ids from status" @@ -834,4 +886,5 @@ changes (-> (pcb/empty-changes) (pcb/with-library-data (:data file)) (clt/generate-sync-tokens-status-with-lib tokens-status tokens-lib))] - (t/is (= [] (:redo-changes changes)))))) + (t/is (= [] (:redo-changes changes))) + (t/is (= [] (:undo-changes changes)))))) diff --git a/common/test/common_tests/types/tokens_lib_test.cljc b/common/test/common_tests/types/tokens_lib_test.cljc index fe372f4429..6baf899521 100644 --- a/common/test/common_tests/types/tokens_lib_test.cljc +++ b/common/test/common_tests/types/tokens_lib_test.cljc @@ -599,206 +599,6 @@ (t/is (= (get-in tokens ["token-2" :value]) 20)) (t/is (= (get-in tokens ["token-3" :value]) 300)))) -#_(t/deftest list-active-themes-tokens-one-theme - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "set-a" - :tokens {"token-1" - (ctob/make-token :name "token-1" - :type :border-radius - :value 10) - "token-2" - (ctob/make-token :name "token-2" - :type :border-radius - :value 20)})) - (ctob/add-set (ctob/make-token-set :name "set-b" - :tokens {"token-1" - (ctob/make-token :name "token-1" - :type :border-radius - :value 100) - "token-3" - (ctob/make-token :name "token-3" - :type :border-radius - :value 300)})) - (ctob/add-set (ctob/make-token-set :name "set-c" - :tokens {"token-1" - (ctob/make-token :name "token-1" - :type :border-radius - :value 1000) - "token-2" - (ctob/make-token :name "token-2" - :type :border-radius - :value 2000) - "token-3" - (ctob/make-token :name "token-3" - :type :border-radius - :value 3000) - "token-4" - (ctob/make-token :name "token-4" - :type :border-radius - :value 4000)})) - (ctob/add-theme (ctob/make-token-theme :name "single-theme" - :sets #{"set-b" "set-c" "set-a"}))) - theme-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "single-theme")) - tokens-status (cfo/set-active-themes (ctos/make-tokens-status) tokens-lib #{theme-id}) - tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] - - ;; Note that sets order inside the theme is undefined. What matters is order in that the - ;; sets have been added to the library. - (t/is (= (mapv key tokens) ["token-1" "token-2" "token-3" "token-4"])) - (t/is (= (get-in tokens ["token-1" :value]) 1000)) - (t/is (= (get-in tokens ["token-2" :value]) 2000)) - (t/is (= (get-in tokens ["token-3" :value]) 3000)) - (t/is (= (get-in tokens ["token-4" :value]) 4000)))) - -#_(t/deftest list-active-themes-tokens-two-themes - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "set-a" - :tokens {"token-1" - (ctob/make-token :name "token-1" - :type :border-radius - :value 10) - "token-2" - (ctob/make-token :name "token-2" - :type :border-radius - :value 20)})) - (ctob/add-set (ctob/make-token-set :name "set-b" - :tokens {"token-1" - (ctob/make-token :name "token-1" - :type :border-radius - :value 100) - "token-3" - (ctob/make-token :name "token-3" - :type :border-radius - :value 300)})) - (ctob/add-set (ctob/make-token-set :name "set-c" - :tokens {"token-1" - (ctob/make-token :name "token-1" - :type :border-radius - :value 1000) - "token-2" - (ctob/make-token :name "token-2" - :type :border-radius - :value 2000) - "token-3" - (ctob/make-token :name "token-3" - :type :border-radius - :value 3000) - "token-4" - (ctob/make-token :name "token-4" - :type :border-radius - :value 4000)})) - (ctob/add-theme (ctob/make-token-theme :name "theme-1" - :sets #{"set-b"})) - (ctob/add-theme (ctob/make-token-theme :name "theme-2" - :sets #{"set-b" "set-a"}))) - theme-1-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "theme-1")) - theme-2-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "theme-2")) - tokens-status (cfo/set-active-themes (ctos/make-tokens-status) tokens-lib #{theme-1-id theme-2-id}) - - tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] - - ;; Note that themes order is irrelevant. What matters is the union of the active sets - ;; and the order of the sets in the library. - (t/is (= (mapv key tokens) ["token-1" "token-2" "token-3"])) - (t/is (= (get-in tokens ["token-1" :value]) 100)) - (t/is (= (get-in tokens ["token-2" :value]) 20)) - (t/is (= (get-in tokens ["token-3" :value]) 300)))) - -#_(t/deftest list-active-themes-tokens-bug-taiga-10617 - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "Mode/Dark" - :tokens {"red" - (ctob/make-token :name "red" - :type :color - :value "#700000")})) - (ctob/add-set (ctob/make-token-set :name "Mode/Light" - :tokens {"red" - (ctob/make-token :name "red" - :type :color - :value "#ff0000")})) - (ctob/add-set (ctob/make-token-set :name "Device/Desktop" - :tokens {"border1" - (ctob/make-token :name "border1" - :type :border-radius - :value 30)})) - (ctob/add-set (ctob/make-token-set :name "Device/Mobile" - :tokens {"border1" - (ctob/make-token :name "border1" - :type :border-radius - :value 50)})) - (ctob/add-theme (ctob/make-token-theme :group "App" - :name "Mobile" - :sets #{"Mode/Dark" "Device/Mobile"})) - (ctob/add-theme (ctob/make-token-theme :group "App" - :name "Web" - :sets #{"Mode/Dark" "Mode/Light" "Device/Desktop"})) - (ctob/add-theme (ctob/make-token-theme :group "Brand" - :name "Brand A" - :sets #{"Mode/Dark" "Mode/Light" "Device/Desktop" "Device/Mobile"})) - (ctob/add-theme (ctob/make-token-theme :group "Brand" - :name "Brand B" - :sets #{}))) - web-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "App" "Web")) - brand-a-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "Brand" "Brand A")) - tokens-status (cfo/set-active-themes (ctos/make-tokens-status) tokens-lib #{web-id brand-a-id}) - tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] - - (t/is (= (mapv key tokens) ["red" "border1"])) - (t/is (= (get-in tokens ["red" :value]) "#ff0000")) - (t/is (= (get-in tokens ["border1" :value]) 50)))) - -#_(t/deftest list-active-themes-tokens-no-tokens - (let [tokens-lib (-> (ctob/make-tokens-lib) - (ctob/add-set (ctob/make-token-set :name "set-a"))) - tokens-status (ctos/make-tokens-status) - tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] - - (t/is (empty? tokens)))) - -#_(t/deftest list-active-themes-tokens-no-sets - (let [tokens-lib (ctob/make-tokens-lib) - tokens-status (ctos/make-tokens-status) - tokens (cfo/get-tokens-in-active-sets tokens-status tokens-lib)] - - (t/is (empty? tokens)))) - -#_(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"}))) - - none-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "none")) - partial-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "partial")) - all-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "all")) - invalid-id (ctob/get-id (ctob/get-theme-by-name tokens-lib "" "invalid")) - - expected-none (-> (ctos/make-tokens-status) - (cfo/set-active-themes tokens-lib #{none-id}) - (cfo/sets-at-path-all-active? tokens-lib ["foo"])) - expected-all (-> (ctos/make-tokens-status) - (cfo/set-active-themes tokens-lib #{all-id}) - (cfo/sets-at-path-all-active? tokens-lib ["foo"])) - expected-partial (-> (ctos/make-tokens-status) - (cfo/set-active-themes tokens-lib #{partial-id}) - (cfo/sets-at-path-all-active? tokens-lib ["foo"])) - expected-invalid-none (-> (ctos/make-tokens-status) - (cfo/set-active-themes tokens-lib #{invalid-id}) - (cfo/sets-at-path-all-active? tokens-lib ["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 [theme-id (uuid/next) tokens-lib (ctob/make-tokens-lib) @@ -1306,12 +1106,12 @@ (let [theme-1-id (uuid/next) theme-2-id (uuid/next) theme-3-id (uuid/next) - theme-4-id (uuid/next) + ;; theme-4-id (uuid/next) tokens-lib (-> (ctob/make-tokens-lib) (ctob/add-theme (ctob/make-token-theme :id theme-1-id :group "" :name "token-theme-1")) (ctob/add-theme (ctob/make-token-theme :id theme-2-id :group "group1" :name "token-theme-2")) (ctob/add-theme (ctob/make-token-theme :id theme-3-id :group "group1" :name "token-theme-3")) - #_(ctob/add-theme (ctob/make-token-theme :in-theme-4-id :group "group2" :name "token-theme-4"))) + #_(ctob/add-theme (ctob/make-token-theme :id theme-4-id :group "group2" :name "token-theme-4"))) tokens-lib' (-> tokens-lib (ctob/update-theme theme-2-id diff --git a/common/test/common_tests/types/tokens_migrations_test.cljc b/common/test/common_tests/types/tokens_migrations_test.cljc index 16b4f5a883..6c7e36e790 100644 --- a/common/test/common_tests/types/tokens_migrations_test.cljc +++ b/common/test/common_tests/types/tokens_migrations_test.cljc @@ -83,7 +83,8 @@ (t/is (= (ctob/get-description theme2') (ctob/get-description theme2)))))) (t/deftest make-tokens-status-from-tokens-lib - (let [tokens-lib (-> (ctob/make-tokens-lib) + (t/testing "active themes and sets from a legacy tokens-lib should be added to the status" + (let [base-lib (-> (ctob/make-tokens-lib) (ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-a) :name "set-a")) (ctob/add-set (ctob/make-token-set :id (thi/new-id! :set-b) @@ -101,18 +102,33 @@ (ctob/add-theme (ctob/make-token-theme :id (thi/new-id! :theme-3) :name "theme-3" :sets #{"set-c" "set-d"}))) - ;; Build a legacy tokens lib to test migration - tokens-lib (ctob/map->tokens-lib {:sets (.-sets tokens-lib) - :themes (.-themes tokens-lib) - :active-themes #{"/theme-1" "/theme-2"}}) + ;; Build a legacy tokens lib to test migration + tokens-lib (ctob/map->tokens-lib {:sets (.-sets base-lib) + :themes (.-themes base-lib) + :active-themes #{"/theme-1" "/theme-2"}}) - tokens-status (cfo/make-tokens-status-from-lib tokens-lib)] + tokens-status (cfo/make-tokens-status-from-lib tokens-lib)] - (t/is (ctos/tokens-status? tokens-status)) - (t/is (ctos/check-tokens-status tokens-status)) - (t/is (= (count (ctos/get-active-theme-ids tokens-status)) 2)) - (t/is (ctos/theme-active? tokens-status (thi/id :theme-1))) - (t/is (ctos/theme-active? tokens-status (thi/id :theme-2))) - (t/is (= 2 (count (ctos/get-active-set-ids tokens-status)))) - (t/is (ctos/set-active? tokens-status (thi/id :set-a))) - (t/is (ctos/set-active? tokens-status (thi/id :set-b))))) + (t/is (ctos/tokens-status? tokens-status)) + (t/is (ctos/check-tokens-status tokens-status)) + (t/is (= (count (ctos/get-active-theme-ids tokens-status)) 2)) + (t/is (ctos/theme-active? tokens-status (thi/id :theme-1))) + (t/is (ctos/theme-active? tokens-status (thi/id :theme-2))) + (t/is (= 2 (count (ctos/get-active-set-ids tokens-status)))) + (t/is (ctos/set-active? tokens-status (thi/id :set-a))) + (t/is (ctos/set-active? tokens-status (thi/id :set-b))))) + + (t/testing "hidden theme should be excluded from active theme ids" + (let [tokens-lib (ctob/make-tokens-lib) + status (cfo/make-tokens-status-from-lib tokens-lib)] + (t/is (not (contains? (ctos/get-active-set-ids status) ctob/hidden-theme-id))))) + + (t/testing "returns empty sets when no active themes" + (let [base-lib (ctob/make-tokens-lib) + tokens-lib (ctob/map->tokens-lib + {:sets (:sets (.sets base-lib)) + :themes (:themes (.themes base-lib)) + :active-themes #{}}) + status (cfo/make-tokens-status-from-lib tokens-lib)] + (t/is (= #{} (ctos/get-active-theme-ids status))) + (t/is (= #{} (ctos/get-active-set-ids status)))))) diff --git a/frontend/src/app/main/data/workspace/tokens/library_edit.cljs b/frontend/src/app/main/data/workspace/tokens/library_edit.cljs index 4812307641..93a72f8ba8 100644 --- a/frontend/src/app/main/data/workspace/tokens/library_edit.cljs +++ b/frontend/src/app/main/data/workspace/tokens/library_edit.cljs @@ -274,6 +274,7 @@ (defn toggle-token-theme-active [id] + (assert (uuid? id) "expected a uuid for `id`") (ptk/reify ::toggle-token-theme-active ptk/WatchEvent (watch [it state _] @@ -289,6 +290,7 @@ (defn delete-token-theme [id] + (assert (uuid? id) "expected a uuid for `id`") (ptk/reify ::delete-token-theme ptk/WatchEvent (watch [it state _] @@ -357,8 +359,8 @@ (dch/commit-changes changes))))))))) (defn set-enabled-token-set - [name enabled?] - (assert (string? name) "expected a string for `name`") + [id enabled?] + (assert (uuid? id) "expected a uuid for `id`") (assert (boolean? enabled?) "expected a boolean for `enabled?`") (ptk/reify ::set-enabled-token-set ptk/WatchEvent @@ -368,14 +370,14 @@ tokens-status (dsh/lookup-tokens-status state) changes (-> (pcb/empty-changes) (pcb/with-library-data data) - (clt/generate-set-enabled-token-set tokens-status tokens-lib name enabled?))] + (clt/generate-set-enabled-token-set tokens-status tokens-lib id enabled?))] (rx/of (dch/commit-changes changes) (dwtp/propagate-workspace-tokens)))))) (defn toggle-token-set - [name] - (assert (string? name) "expected a string for `name`") + [id] + (assert (uuid? id) "expected a uuid for `id`") (ptk/reify ::toggle-token-set ptk/WatchEvent (watch [_ state _] @@ -384,7 +386,7 @@ tokens-status (dsh/lookup-tokens-status state) changes (-> (pcb/empty-changes) (pcb/with-library-data data) - (clt/generate-toggle-token-set tokens-status tokens-lib name))] + (clt/generate-toggle-token-set tokens-status tokens-lib id))] (rx/of (dch/commit-changes changes) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 0342ec71f4..c3457af954 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -500,7 +500,6 @@ (def workspace-token-sets-tree (l/derived (d/nilf ctob/get-set-tree) tokens-lib)) -;; TODOstatus cambiar para que sean ids en todas partes (def workspace-active-theme-paths (l/derived (d/nilf ctos/get-active-theme-ids) tokens-status)) diff --git a/frontend/src/app/main/ui/inspect/styles.cljs b/frontend/src/app/main/ui/inspect/styles.cljs index 2bcdcfb9ad..c049e4d2ae 100644 --- a/frontend/src/app/main/ui/inspect/styles.cljs +++ b/frontend/src/app/main/ui/inspect/styles.cljs @@ -13,6 +13,7 @@ [app.common.types.component :as ctc] [app.common.types.components-list :as ctkl] [app.common.types.shape.layout :as ctl] + [app.common.types.tokens-lib :as ctob] [app.main.data.style-dictionary :as sd] [app.main.refs :as refs] [app.main.ui.inspect.exports :as exports] @@ -115,7 +116,7 @@ active-themes (mf/deref refs/workspace-active-theme-paths) active-sets (mf/with-memo [tokens-status tokens-lib] (when (and tokens-status tokens-lib) - (cfo/get-active-set-names tokens-status tokens-lib))) + (cfo/get-active-sets tokens-status tokens-lib))) active-tokens (mf/with-memo [tokens-status tokens-lib] (when (and tokens-status tokens-lib) (cfo/get-tokens-in-active-sets tokens-status tokens-lib))) @@ -155,7 +156,7 @@ (when (or (seq active-themes) (seq active-sets)) [:li [:> style-box* {:panel :token} - [:> tokens-panel* {:theme-paths active-themes :set-names active-sets}]]]) + [:> tokens-panel* {:theme-paths active-themes :set-names (map ctob/get-name active-sets)}]]]) (for [panel panels] [:li {:key (d/name panel)} (case panel diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index 919fc8cfd2..467a78eb96 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -769,7 +769,9 @@ active-sets-names (mf/with-memo [tokens-status tokens-lib] (when (and tokens-status tokens-lib) - (cfo/get-active-set-names tokens-status tokens-lib))) + (into #{} + (map ctob/get-name) + (cfo/get-active-sets tokens-status tokens-lib)))) active-tokens (if (delay? active-tokens) @active-tokens @@ -785,7 +787,7 @@ (filter-active-sets active-sets-names) (filter-non-empty-sets) (group-sets) - (combine-groups-with-resolved color-tokens)))] + (combine-groups-with-resolved color-tokens)))] (mf/with-effect [] (st/emit! (st/emit! (dsc/push-shortcuts ::colorpicker sc/shortcuts))) diff --git a/frontend/src/app/main/ui/workspace/tokens/management.cljs b/frontend/src/app/main/ui/workspace/tokens/management.cljs index 30adc629df..c50c8e0d58 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management.cljs @@ -2,10 +2,10 @@ (:require-macros [app.main.style :as stl]) (:require [app.common.data :as d] - [app.common.files.tokens :as cfo] [app.common.path-names :as cpn] [app.common.types.shape.layout :as ctsl] [app.common.types.tokens-lib :as ctob] + [app.common.types.tokens-status :as ctos] [app.common.uuid :as uuid] [app.config :as cf] [app.main.data.helpers :as dh] @@ -56,16 +56,12 @@ (when selected-token-set-id (some-> tokens-lib (ctob/get-set selected-token-set-id)))) - active-token-sets-names - (mf/with-memo [tokens-status tokens-lib] - (when (and tokens-status tokens-lib) - (cfo/get-active-set-names tokens-status tokens-lib))) - token-set-active? (mf/use-fn - (mf/deps active-token-sets-names) - (fn [name] - (contains? active-token-sets-names name)))] + (mf/deps tokens-status) + (fn [id] + (ctos/set-active? tokens-status id)))] + [:div {:class (stl/css :sets-header-container)} [:> text* {:as "span" :typography "headline-small" @@ -73,7 +69,7 @@ :data-testid "active-token-set-title"} (tr "workspace.tokens.tokens-section-title" (ctob/get-name selected-token-set))] (when (and (some? selected-token-set-id) - (not (token-set-active? (ctob/get-name selected-token-set)))) + (not (token-set-active? selected-token-set-id))) [:div {:class (stl/css :sets-header-status) :title (tr "workspace.tokens.inactive-set-description")} ;; NOTE: when no set in tokens-lib, the selected-token-set-id ;; will be `nil`, so for properly hide the inactive message we @@ -86,7 +82,7 @@ (mf/defc tokens-section* {::mf/private true} - [{:keys [tokens-lib active-tokens resolved-active-tokens]}] + [{:keys [tokens-lib tokens-status active-tokens resolved-active-tokens]}] (let [objects (mf/deref refs/workspace-page-objects) selected (mf/deref refs/selected-shapes) @@ -307,6 +303,7 @@ :on-delete-node delete-node}] [:> selected-set-info* {:tokens-lib tokens-lib + :tokens-status tokens-status :selected-token-set-id selected-token-set-id}] (for [type filled-group] diff --git a/frontend/src/app/main/ui/workspace/tokens/sets.cljs b/frontend/src/app/main/ui/workspace/tokens/sets.cljs index 27bb9e211a..3aaa4a43e3 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets.cljs @@ -20,8 +20,8 @@ (st/emit! (dwtl/clear-tokens-paths) (dwtl/set-selected-token-set-id id))) -(defn- on-toggle-token-set-click [name] - (st/emit! (dwtl/toggle-token-set name))) +(defn- on-toggle-token-set-click [id] + (st/emit! (dwtl/toggle-token-set id))) (defn- on-toggle-token-set-group-click [path] (st/emit! (dwtl/toggle-token-set-group path))) diff --git a/frontend/src/app/main/ui/workspace/tokens/sets/lists.cljs b/frontend/src/app/main/ui/workspace/tokens/sets/lists.cljs index a679dfd735..8322d30be8 100644 --- a/frontend/src/app/main/ui/workspace/tokens/sets/lists.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/sets/lists.cljs @@ -10,7 +10,6 @@ (:require [app.common.data.macros :as dm] [app.common.types.tokens-lib :as ctob] - [app.common.types.tokens-status :as ctos] [app.main.data.workspace.tokens.library-edit :as dwtl] [app.main.store :as st] [app.main.ui.context :as ctx] @@ -245,7 +244,7 @@ (fn [event] (dom/stop-propagation event) (when (fn? on-toggle) - (on-toggle (ctob/get-name set))))) + (on-toggle (ctob/get-id set))))) on-edit-submit' (mf/use-fn @@ -327,9 +326,7 @@ new-path edition-id]}] - (let [tokens-status (mf/use-ctx ctx/tokens-status) - - collapsed-paths* (mf/use-state #{}) + (let [collapsed-paths* (mf/use-state #{}) collapsed-paths (deref collapsed-paths*) collapsed? diff --git a/frontend/src/app/plugins/tokens.cljs b/frontend/src/app/plugins/tokens.cljs index e8473c903c..6d91da040d 100644 --- a/frontend/src/app/plugins/tokens.cljs +++ b/frontend/src/app/plugins/tokens.cljs @@ -348,20 +348,16 @@ :enumerable false :get (fn [_] - (let [tokens-lib (u/locate-tokens-lib file-id) - tokens-status (u/locate-tokens-status file-id) - set (u/locate-token-set file-id id)] - (cfo/token-set-active? tokens-status tokens-lib (ctob/get-name set)))) + (let [tokens-status (u/locate-tokens-status file-id)] + (ctos/set-active? tokens-status id))) :schema ::sm/boolean :set (fn [_ value] - (let [set (u/locate-token-set file-id id)] - (st/emit! (dwtl/set-enabled-token-set (ctob/get-name set) value))))} + (st/emit! (dwtl/set-enabled-token-set id value)))} :toggleActive (fn [_] - (let [set (u/locate-token-set file-id id)] - (st/emit! (dwtl/toggle-token-set (ctob/get-name set))))) + (st/emit! (dwtl/toggle-token-set id))) :tokens {:this true diff --git a/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs b/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs index 5e30f5fab3..9eb0be8dfa 100644 --- a/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs +++ b/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs @@ -87,17 +87,16 @@ done (let [file (setup-file-with-empty-lib) store (ths/setup-store file) - set (ctob/make-token-set :name "primitives") + set (ctob/make-token-set :id (cthi/new-id! :set1) :name "primitives") events [(dwtl/create-token-set set)]] (tohs/run-store-async store done events (fn [new-state] - (let [file' (ths/get-file-from-state new-state) - lib (get-in file' [:data :tokens-lib])] + (let [file' (ths/get-file-from-state new-state) + lib (ctht/get-tokens-lib file') + status (ctht/get-tokens-status file')] (t/is (some? (ctob/get-set lib (ctob/get-id set)))) - (t/is (false? (cfo/token-set-active? - (ctht/get-tokens-status file') - lib "primitives")))))))))) + (t/is (false? (ctos/set-active? status (cthi/id :set1))))))))))) (t/deftest test-create-then-enable-token-set (t/testing "create followed by set-enabled (as the plugin addSet does) yields an active set" @@ -105,18 +104,17 @@ done (let [file (setup-file-with-empty-lib) store (ths/setup-store file) - set (ctob/make-token-set :name "primitives") + set (ctob/make-token-set :id (cthi/new-id! :set1) :name "primitives") events [(dwtl/create-token-set set) - (dwtl/set-enabled-token-set "primitives" true)]] + (dwtl/set-enabled-token-set (cthi/id :set1) true)]] (tohs/run-store-async store done events (fn [new-state] - (let [file' (ths/get-file-from-state new-state) - lib (get-in file' [:data :tokens-lib])] + (let [file' (ths/get-file-from-state new-state) + lib (ctht/get-tokens-lib file') + status (ctht/get-tokens-status file')] (t/is (some? (ctob/get-set lib (ctob/get-id set)))) - (t/is (true? (cfo/token-set-active? - (ctht/get-tokens-status file') - lib "primitives")))))))))) + (t/is (true? (ctos/set-active? status (cthi/id :set1))))))))))) (t/deftest test-apply-token (t/testing "applies token to shape and updates shape attributes to resolved value"