diff --git a/common/src/app/common/files/tokens.cljc b/common/src/app/common/files/tokens.cljc index a673e393d1..dbb9b73cb8 100644 --- a/common/src/app/common/files/tokens.cljc +++ b/common/src/app/common/files/tokens.cljc @@ -534,6 +534,12 @@ [file-data f & args] (d/update-when file-data :tokens-status #(apply f % args))) +(defn set-tokens-status + "Replace the tokens-status inside file-data with a new one." + [file-data tokens-status] + (assert (or (nil? tokens-status) (ctos/tokens-status? tokens-status)) "expected valid tokens-status or nil") + (assoc file-data :tokens-status tokens-status)) + ;; Tokens status with tokens lib (defn- calculate-active-sets diff --git a/common/src/app/common/test_helpers/tokens.cljc b/common/src/app/common/test_helpers/tokens.cljc index 23a0550a4a..cf1f96afcd 100644 --- a/common/src/app/common/test_helpers/tokens.cljc +++ b/common/src/app/common/test_helpers/tokens.cljc @@ -16,7 +16,8 @@ [app.common.types.shape-tree :as ctst] [app.common.types.text :as ctt] [app.common.types.token :as cto] - [app.common.types.tokens-lib :as ctob])) + [app.common.types.tokens-lib :as ctob] + [app.common.types.tokens-status :as ctos])) (defn get-tokens-source [file] @@ -44,6 +45,19 @@ [file f] (ctf/update-file-data file #(cfo/update-tokens-status % f))) +(defn set-tokens-source + [file library] + (let [library-id (:id library) + library-tokens-status (if library + (-> library ctf/file-data cfo/get-tokens-status) + (ctos/make-tokens-status))] + (ctf/update-file-data + file + (fn [data] + (-> data + (cfo/set-tokens-source library-id) + (cfo/set-tokens-status library-tokens-status)))))) + (defn sample-file-with-tokens [& {:keys [lib-fn status-fn file-id] :as params :or {lib-fn identity status-fn identity file-id :file1}}] diff --git a/common/test/common_tests/files/tokens_test.cljc b/common/test/common_tests/files/tokens_test.cljc index 93b87a12e1..7773437952 100644 --- a/common/test/common_tests/files/tokens_test.cljc +++ b/common/test/common_tests/files/tokens_test.cljc @@ -574,8 +574,12 @@ (t/deftest test-update-tokens-status (t/testing "update when there is no tokens-status has no effect" - (let [file (thf/sample-file :file1) - file' (cfo/update-tokens-status file #(t/is false "This should not be called"))] + (let [file (thf/sample-file :file1) + file' (ctf/update-file-data file + (fn [data] + (cfo/update-tokens-status + data + #(t/is false "This should not be called"))))] (t/is (= file file')))) (t/testing "update a tokens-status applies the changes correctly" @@ -596,6 +600,23 @@ (t/is (ctos/theme-active? tokens-status' (thi/id :theme1))) (t/is (= 0 (count (ctos/get-active-set-ids tokens-status'))))))) +(t/deftest test-set-tokens-status + (t/testing "set to empty" + (let [file (-> (thf/sample-file :file1) + (assoc :tokens-status (ctos/make-tokens-status))) + file' (ctf/update-file-data file #(cfo/set-tokens-status % nil)) + tokens-status' (tht/get-tokens-status file')] + (t/is (nil? tokens-status')))) + + (t/testing "set to a new status" + (let [tokens-status1 (ctos/make-tokens-status) + tokens-status2 (ctos/make-tokens-status) + file (-> (thf/sample-file :file1) + (assoc :tokens-status tokens-status1)) + file' (ctf/update-file-data file #(cfo/set-tokens-status % tokens-status2)) + tokens-status' (tht/get-tokens-status file')] + (t/is (= tokens-status2 tokens-status'))))) + ;; Tokens status with tokens lib ;; This is a private function but it deserves specific tests for all use cases diff --git a/frontend/test/frontend_tests/helpers/state.cljs b/frontend/test/frontend_tests/helpers/state.cljs index 8f891de222..fb685ba3d1 100644 --- a/frontend/test/frontend_tests/helpers/state.cljs +++ b/frontend/test/frontend_tests/helpers/state.cljs @@ -6,9 +6,11 @@ (ns frontend-tests.helpers.state (:require + [app.common.data :as d] [app.common.pprint :refer [pprint]] [app.common.schema :as sm] [app.common.test-helpers.files :as cthf] + [app.common.test-helpers.tokens :as ctht] [app.main.data.workspace.layout :as layout] [app.main.features :as features] [beicon.v2.core :as rx] @@ -34,12 +36,21 @@ (defn setup-store ([file] (setup-store file nil)) - ([file {:keys [renderer] :as _opts}] - (let [state (-> initial-state + ([file {:keys [renderer libraries tokens-source-library] :as _opts + :or {libraries [] tokens-source-library nil}}] + (let [file (cond-> file + (some? tokens-source-library) + (ctht/set-tokens-source tokens-source-library)) + libraries (map #(assoc % + :library-of (:id file) + :is-shared true) + libraries) + files (d/index-by :id (cons file libraries)) + state (-> initial-state (assoc :current-file-id (:id file) :current-page-id (cthf/current-page-id file) :permissions {:can-edit true} - :files {(:id file) file}) + :files files) (cond-> (some? renderer) (assoc-in [:profile :props :renderer] renderer))) store (ptk/store {:state state :on-error on-error})] diff --git a/frontend/test/frontend_tests/runner.cljs b/frontend/test/frontend_tests/runner.cljs index ee159cbf7b..1273f5f24b 100644 --- a/frontend/test/frontend_tests/runner.cljs +++ b/frontend/test/frontend_tests/runner.cljs @@ -72,6 +72,7 @@ [frontend-tests.tokens.import-export-test] [frontend-tests.tokens.logic.token-actions-test] [frontend-tests.tokens.logic.token-data-test] + [frontend-tests.tokens.logic.token-libraries-test] [frontend-tests.tokens.logic.token-remapping-test] [frontend-tests.tokens.logic.tokens-status-test] [frontend-tests.tokens.style-dictionary-test] @@ -111,99 +112,102 @@ (.exit js/process 1))) (def test-namespaces - ['frontend-tests.basic-shapes-test - 'frontend-tests.code-gen-style-test - 'frontend-tests.composable-tests.comp.sync-test - 'frontend-tests.copy-as-svg-test - 'frontend-tests.data.dashboard-test - 'frontend-tests.data.nitrate-test - 'frontend-tests.data.profile-test - 'frontend-tests.data.repo-test - 'frontend-tests.data.store-test - 'frontend-tests.data.exports-assets-test - 'frontend-tests.data.uploads-test - 'frontend-tests.data.viewer-test - 'frontend-tests.data.workspace-colors-test - 'frontend-tests.data.workspace-comments-test - 'frontend-tests.data.workspace-interactions-test - 'frontend-tests.data.workspace-mcp-test - 'frontend-tests.data.workspace-media-test - 'frontend-tests.data.workspace-pages-test - 'frontend-tests.data.workspace-path-edition-test - 'frontend-tests.data.workspace-reflow-test - 'frontend-tests.data.workspace-shortcuts-test - 'frontend-tests.data.workspace-texts-test - 'frontend-tests.data.workspace-thumbnails-test - 'frontend-tests.errors-test - 'frontend-tests.fonts-test - 'frontend-tests.helpers-shapes-test - 'frontend-tests.logic.comp-remove-swap-slots-test - 'frontend-tests.logic.components-and-tokens - 'frontend-tests.logic.copying-and-duplicating-test - 'frontend-tests.logic.frame-guides-test - 'frontend-tests.logic.groups-test - 'frontend-tests.logic.nudge-selected-shapes-test - 'frontend-tests.logic.path-actions-test - 'frontend-tests.logic.path-clipboard-test - 'frontend-tests.logic.path-helpers-test - 'frontend-tests.logic.path-lifecycle-test - 'frontend-tests.logic.path-tools-test - 'frontend-tests.logic.pasting-in-containers-test - 'frontend-tests.main-errors-test - 'frontend-tests.logic.sidebar-transform-coalescing-test - 'frontend-tests.logic.update-position-test - 'frontend-tests.logic.wasm-modifiers-nil-id-test - 'frontend-tests.plugins.comments-test - 'frontend-tests.plugins.context-shapes-test - 'frontend-tests.plugins.file-test - 'frontend-tests.plugins.format-test - 'frontend-tests.plugins.grid-test - 'frontend-tests.plugins.interactions-test - 'frontend-tests.plugins.library-test - 'frontend-tests.plugins.local-storage-test - 'frontend-tests.plugins.page-active-validation-test - 'frontend-tests.plugins.page-test - 'frontend-tests.plugins.parser-test - 'frontend-tests.plugins.shape-bugfixes-test - 'frontend-tests.plugins.text-test - 'frontend-tests.plugins.tokens-test - 'frontend-tests.plugins.utils-test - 'frontend-tests.plugins.value-objects-test - 'frontend-tests.render-wasm.process-objects-test - 'frontend-tests.render-wasm.text-editor-apply-styles-test - 'frontend-tests.render-wasm.text-editor-caret-color-test - 'frontend-tests.svg-fills-test - 'frontend-tests.tokens.copy-paste-props-test - 'frontend-tests.tokens.import-export-test - 'frontend-tests.tokens.logic.token-actions-test - 'frontend-tests.tokens.logic.token-data-test - 'frontend-tests.tokens.logic.token-remapping-test - 'frontend-tests.tokens.style-dictionary-test - 'frontend-tests.tokens.token-errors-test - 'frontend-tests.tokens.logic.tokens-status-test - 'frontend-tests.tokens.workspace-tokens-remap-test - 'frontend-tests.ui.check-updates-test - 'frontend-tests.ui.colorpicker-token-set-order-test - 'frontend-tests.ui.comments-clustering-test - 'frontend-tests.ui.comments-position-modifier-test - 'frontend-tests.ui.ds-controls-numeric-input-test - 'frontend-tests.ui.gradient-handlers-test - 'frontend-tests.ui.layout-container-multiple-test - 'frontend-tests.ui.measures-menu-props-test - 'frontend-tests.ui.routes-test - 'frontend-tests.render-dimensions-test - 'frontend-tests.text-editor-paste-guard-test - 'frontend-tests.ui.settings-password-schema-test - 'frontend-tests.ui.settings-shortcuts-test - 'frontend-tests.util-clipboard-test - 'frontend-tests.util-object-test - 'frontend-tests.util-range-tree-test - 'frontend-tests.util-simple-math-test - 'frontend-tests.util-text-editor-test - 'frontend-tests.util-webapi-test - 'frontend-tests.util.dom.dnd-test - 'frontend-tests.util-zip-test - 'frontend-tests.worker-snap-test]) + [ + ;; 'frontend-tests.basic-shapes-test + ;; 'frontend-tests.code-gen-style-test + ;; 'frontend-tests.composable-tests.comp.sync-test + ;; 'frontend-tests.copy-as-svg-test + ;; 'frontend-tests.data.dashboard-test + ;; 'frontend-tests.data.nitrate-test + ;; 'frontend-tests.data.profile-test + ;; 'frontend-tests.data.repo-test + ;; 'frontend-tests.data.store-test + ;; 'frontend-tests.data.exports-assets-test + ;; 'frontend-tests.data.uploads-test + ;; 'frontend-tests.data.viewer-test + ;; 'frontend-tests.data.workspace-colors-test + ;; 'frontend-tests.data.workspace-comments-test + ;; 'frontend-tests.data.workspace-interactions-test + ;; 'frontend-tests.data.workspace-mcp-test + ;; 'frontend-tests.data.workspace-media-test + ;; 'frontend-tests.data.workspace-pages-test + ;; 'frontend-tests.data.workspace-path-edition-test + ;; 'frontend-tests.data.workspace-reflow-test + ;; 'frontend-tests.data.workspace-shortcuts-test + ;; 'frontend-tests.data.workspace-texts-test + ;; 'frontend-tests.data.workspace-thumbnails-test + ;; 'frontend-tests.errors-test + ;; 'frontend-tests.fonts-test + ;; 'frontend-tests.helpers-shapes-test + ;; 'frontend-tests.logic.comp-remove-swap-slots-test + ;; 'frontend-tests.logic.components-and-tokens + ;; 'frontend-tests.logic.copying-and-duplicating-test + ;; 'frontend-tests.logic.frame-guides-test + ;; 'frontend-tests.logic.groups-test + ;; 'frontend-tests.logic.nudge-selected-shapes-test + ;; 'frontend-tests.logic.path-actions-test + ;; 'frontend-tests.logic.path-clipboard-test + ;; 'frontend-tests.logic.path-helpers-test + ;; 'frontend-tests.logic.path-lifecycle-test + ;; 'frontend-tests.logic.path-tools-test + ;; 'frontend-tests.logic.pasting-in-containers-test + ;; 'frontend-tests.main-errors-test + ;; 'frontend-tests.logic.sidebar-transform-coalescing-test + ;; 'frontend-tests.logic.update-position-test + ;; 'frontend-tests.logic.wasm-modifiers-nil-id-test + ;; 'frontend-tests.plugins.comments-test + ;; 'frontend-tests.plugins.context-shapes-test + ;; 'frontend-tests.plugins.file-test + ;; 'frontend-tests.plugins.format-test + ;; 'frontend-tests.plugins.grid-test + ;; 'frontend-tests.plugins.interactions-test + ;; 'frontend-tests.plugins.library-test + ;; 'frontend-tests.plugins.local-storage-test + ;; 'frontend-tests.plugins.page-active-validation-test + ;; 'frontend-tests.plugins.page-test + ;; 'frontend-tests.plugins.parser-test + ;; 'frontend-tests.plugins.shape-bugfixes-test + ;; 'frontend-tests.plugins.text-test + ;; 'frontend-tests.plugins.tokens-test + ;; 'frontend-tests.plugins.utils-test + ;; 'frontend-tests.plugins.value-objects-test + ;; 'frontend-tests.render-wasm.process-objects-test + ;; 'frontend-tests.render-wasm.text-editor-apply-styles-test + ;; 'frontend-tests.render-wasm.text-editor-caret-color-test + ;; 'frontend-tests.svg-fills-test + ;; 'frontend-tests.tokens.copy-paste-props-test + ;; 'frontend-tests.tokens.import-export-test + ;; 'frontend-tests.tokens.logic.token-actions-test + ;; 'frontend-tests.tokens.logic.token-data-test + 'frontend-tests.tokens.logic.token-libraries-test + ;; 'frontend-tests.tokens.logic.token-remapping-test + ;; 'frontend-tests.tokens.style-dictionary-test + ;; 'frontend-tests.tokens.token-errors-test + ;; 'frontend-tests.tokens.logic.tokens-status-test + ;; 'frontend-tests.tokens.workspace-tokens-remap-test + ;; 'frontend-tests.ui.check-updates-test + ;; 'frontend-tests.ui.colorpicker-token-set-order-test + ;; 'frontend-tests.ui.comments-clustering-test + ;; 'frontend-tests.ui.comments-position-modifier-test + ;; 'frontend-tests.ui.ds-controls-numeric-input-test + ;; 'frontend-tests.ui.gradient-handlers-test + ;; 'frontend-tests.ui.layout-container-multiple-test + ;; 'frontend-tests.ui.measures-menu-props-test + ;; 'frontend-tests.ui.routes-test + ;; 'frontend-tests.render-dimensions-test + ;; 'frontend-tests.text-editor-paste-guard-test + ;; 'frontend-tests.ui.settings-password-schema-test + ;; 'frontend-tests.ui.settings-shortcuts-test + ;; 'frontend-tests.util-clipboard-test + ;; 'frontend-tests.util-object-test + ;; 'frontend-tests.util-range-tree-test + ;; 'frontend-tests.util-simple-math-test + ;; 'frontend-tests.util-text-editor-test + ;; 'frontend-tests.util-webapi-test + ;; 'frontend-tests.util.dom.dnd-test + ;; 'frontend-tests.util-zip-test + ;; 'frontend-tests.worker-snap-test + ]) (assert (every? find-ns-obj test-namespaces) "test-namespaces contains a namespace that isn't required in runner.cljs") diff --git a/frontend/test/frontend_tests/tokens/helpers/state.cljs b/frontend/test/frontend_tests/tokens/helpers/state.cljs index e03b15b099..fd5659a32b 100644 --- a/frontend/test/frontend_tests/tokens/helpers/state.cljs +++ b/frontend/test/frontend_tests/tokens/helpers/state.cljs @@ -32,9 +32,8 @@ (ptk/reify ::end+ ptk/WatchEvent (watch [_ state _] - (let [data (dsh/lookup-file-data state) - tokens-status (cfo/get-tokens-status data) - tokens-lib (cfo/get-tokens-lib data)] + (let [tokens-status (dsh/lookup-tokens-status state) + tokens-lib (dsh/lookup-tokens-lib state)] (if (and tokens-status tokens-lib) (->> (cfo/get-tokens-in-active-sets tokens-status tokens-lib) (sd/resolve-tokens) diff --git a/frontend/test/frontend_tests/tokens/logic/token_libraries_test.cljs b/frontend/test/frontend_tests/tokens/logic/token_libraries_test.cljs new file mode 100644 index 0000000000..30b2108d60 --- /dev/null +++ b/frontend/test/frontend_tests/tokens/logic/token_libraries_test.cljs @@ -0,0 +1,78 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS SUBSIDIARY SL + +(ns frontend-tests.tokens.logic.token-libraries-test + (:require + [app.common.test-helpers.files :as cthf] + [app.common.test-helpers.ids-map :as cthi] + [app.common.test-helpers.shapes :as cths] + [app.common.test-helpers.tokens :as ctht] + [app.common.types.tokens-lib :as ctob] + [app.common.types.tokens-status :as ctos] + [app.main.data.workspace.tokens.application :as dwta] + [cljs.test :as t :include-macros true] + [frontend-tests.helpers.pages :as thp] + [frontend-tests.helpers.state :as ths] + [frontend-tests.helpers.wasm :as thw] + [frontend-tests.tokens.helpers.state :as tohs] + [frontend-tests.tokens.helpers.tokens :as toht])) + +(t/use-fixtures :each + {:before (fn [] + (thp/reset-idmap!) + (thw/setup-wasm-mocks!)) + :after thw/teardown-wasm-mocks!}) + +(defn setup-file [] + (-> (cthf/sample-file :file-1 :page-label :page-1) + (cths/add-sample-shape :rect-1 + :type :rect + :r1 0 :r2 0 :r3 0 :r4 0))) + +(defn setup-file-with-tokens + [] + (-> (ctht/sample-file-with-tokens + :lib-fn #(-> % + (ctob/add-set (ctob/make-token-set :id (cthi/new-id! :set-a) + :name "Set A")) + (ctob/add-set (ctob/make-token-set :id (cthi/new-id! :set-b) + :name "Set B")) + (ctob/add-token (cthi/id :set-a) + (ctob/make-token {:name "borderRadius.sm" + :value "12" + :type :border-radius})) + (ctob/add-token (cthi/id :set-b) + (ctob/make-token {:name "borderRadius.sm" + :value "24" + :type :border-radius}))) + :status-fn #(ctos/set-tokens-status % #{} #{(cthi/id :set-a)})))) + +(t/deftest test-apply-token-from-lib + (t/testing "applies token from library to local shape updates shape attributes to resolved value" + (t/async + done + (let [library (setup-file-with-tokens) + file (setup-file) + store (ths/setup-store file {:libraries [library] + :tokens-source-library library}) + rect-1 (cths/get-shape file :rect-1) + token (toht/get-token library "borderRadius.sm") + events [(dwta/apply-token {:shape-ids [(:id rect-1)] + :attributes #{:r1 :r2 :r3 :r4} + :token token + :on-update-shape dwta/update-shape-radius})]] + (tohs/run-store-async + store done events + (fn [new-state] + (let [file' (ths/get-file-from-state new-state) + rect-1' (cths/get-shape file' :rect-1)] + + (t/testing "shape `:applied-tokens` got updated" + (t/is (some? (:applied-tokens rect-1'))) + (t/is (= (:r1 (:applied-tokens rect-1')) (:name token)))) + + (t/testing "shape radius got update to the resolved token value." + (t/is (= (:r1 rect-1') 12))))))))))