diff --git a/common/src/app/common/test_helpers/tokens.cljc b/common/src/app/common/test_helpers/tokens.cljc index 35a7d53aa..7ddb78a3d 100644 --- a/common/src/app/common/test_helpers/tokens.cljc +++ b/common/src/app/common/test_helpers/tokens.cljc @@ -23,6 +23,39 @@ [file f] (ctf/update-file-data file #(update % :tokens-lib f))) +(defn- set-stroke-width + [shape stroke-width] + (let [strokes (if (seq (:strokes shape)) + (:strokes shape) + [{:stroke-style :solid + :stroke-alignment :inner + :stroke-width 1 + :stroke-color "#000000" + :stroke-opacity 1}]) + new-strokes (update strokes 0 assoc :stroke-width stroke-width)] + (ctn/set-shape-attr shape :strokes new-strokes {:ignore-touched true}))) + +(defn- set-stroke-color + [shape stroke-color] + (let [strokes (if (seq (:strokes shape)) + (:strokes shape) + [{:stroke-style :solid + :stroke-alignment :inner + :stroke-width 1 + :stroke-color "#000000" + :stroke-opacity 1}]) + new-strokes (update strokes 0 assoc :stroke-color stroke-color)] + (ctn/set-shape-attr shape :strokes new-strokes {:ignore-touched true}))) + +(defn- set-fill-color + [shape fill-color] + (let [fills (if (seq (:fills shape)) + (:fills shape) + [{:fill-color "#000000" + :fill-opacity 1}]) + new-fills (update fills 0 assoc :fill-color fill-color)] + (ctn/set-shape-attr shape :fills new-fills {:ignore-touched true}))) + (defn apply-token-to-shape [file shape-label token-name token-attrs shape-attrs resolved-value] (let [page (thf/current-page file) @@ -32,7 +65,11 @@ :token {:name token-name} :attributes token-attrs}) (reduce (fn [shape attr] - (ctn/set-shape-attr shape attr resolved-value {:ignore-touched true})) + (case attr + :stroke-width (set-stroke-width shape resolved-value) + :stroke-color (set-stroke-color shape resolved-value) + :fill (set-fill-color shape resolved-value) + (ctn/set-shape-attr shape attr resolved-value {:ignore-touched true}))) $ shape-attrs))] diff --git a/frontend/test/frontend_tests/logic/components_and_tokens.cljs b/frontend/test/frontend_tests/logic/components_and_tokens.cljs index 4175792f0..a51985ef8 100644 --- a/frontend/test/frontend_tests/logic/components_and_tokens.cljs +++ b/frontend/test/frontend_tests/logic/components_and_tokens.cljs @@ -6,6 +6,7 @@ (ns frontend-tests.logic.components-and-tokens (:require [app.common.geom.point :as geom] + [app.common.math :as mth] [app.common.test-helpers.components :as cthc] [app.common.test-helpers.compositions :as ctho] [app.common.test-helpers.files :as cthf] @@ -64,223 +65,333 @@ (t/deftest create-component-with-token (t/async - done - (let [;; ==== Setup - file (setup-base-file) - store (ths/setup-store file) + done + (let [;; ==== Setup + file (setup-base-file) + store (ths/setup-store file) ;; ==== Action - events - [(dws/select-shape (cthi/id :frame1)) - (dwl/add-component)]] + events + [(dws/select-shape (cthi/id :frame1)) + (dwl/add-component)]] - (ths/run-store - store done events - (fn [new-state] - (let [;; ==== Get - file' (ths/get-file-from-store new-state) - frame1' (cths/get-shape file' :frame1) - tokens-frame1' (:applied-tokens frame1')] + (ths/run-store + store done events + (fn [new-state] + (let [;; ==== Get + file' (ths/get-file-from-store new-state) + frame1' (cths/get-shape file' :frame1) + tokens-frame1' (:applied-tokens frame1')] ;; ==== Check - (t/is (= (count tokens-frame1') 2)) - (t/is (= (get tokens-frame1' :rx) "test-token-1")) - (t/is (= (get tokens-frame1' :ry) "test-token-1")) - (t/is (= (get frame1' :rx) 25)) - (t/is (= (get frame1' :ry) 25)))))))) + (t/is (= (count tokens-frame1') 2)) + (t/is (= (get tokens-frame1' :rx) "test-token-1")) + (t/is (= (get tokens-frame1' :ry) "test-token-1")) + (t/is (= (get frame1' :rx) 25)) + (t/is (= (get frame1' :ry) 25)))))))) (t/deftest create-copy-with-token (t/async - done - (let [;; ==== Setup - file (setup-file-with-main) - store (ths/setup-store file) + done + (let [;; ==== Setup + file (setup-file-with-main) + store (ths/setup-store file) ;; ==== Action - events - [(dwl/instantiate-component (:id file) - (cthi/id :component1) - (geom/point 0 0))]] + events + [(dwl/instantiate-component (:id file) + (cthi/id :component1) + (geom/point 0 0))]] - (ths/run-store - store done events - (fn [new-state] - (let [;; ==== Get - selected (wsh/lookup-selected new-state) - c-frame1' (wsh/lookup-shape new-state (first selected)) - tokens-frame1' (:applied-tokens c-frame1')] + (ths/run-store + store done events + (fn [new-state] + (let [;; ==== Get + selected (wsh/lookup-selected new-state) + c-frame1' (wsh/lookup-shape new-state (first selected)) + tokens-frame1' (:applied-tokens c-frame1')] ;; ==== Check - (t/is (= (count tokens-frame1') 2)) - (t/is (= (get tokens-frame1' :rx) "test-token-1")) - (t/is (= (get tokens-frame1' :ry) "test-token-1")) - (t/is (= (get c-frame1' :rx) 25)) - (t/is (= (get c-frame1' :ry) 25)))))))) + (t/is (= (count tokens-frame1') 2)) + (t/is (= (get tokens-frame1' :rx) "test-token-1")) + (t/is (= (get tokens-frame1' :ry) "test-token-1")) + (t/is (= (get c-frame1' :rx) 25)) + (t/is (= (get c-frame1' :ry) 25)))))))) (t/deftest change-token-in-main (t/async - done - (let [;; ==== Setup - file (setup-file-with-copy) - store (ths/setup-store file) + done + (let [;; ==== Setup + file (setup-file-with-copy) + store (ths/setup-store file) ;; ==== Action - events [(wtch/apply-token {:shape-ids [(cthi/id :frame1)] - :attributes #{:rx :ry} - :token (toht/get-token file "test-token-2") - :on-update-shape wtch/update-shape-radius-all})] + events [(wtch/apply-token {:shape-ids [(cthi/id :frame1)] + :attributes #{:rx :ry} + :token (toht/get-token file "test-token-2") + :on-update-shape wtch/update-shape-radius-all})] - step2 (fn [_] - (let [events2 [(dwl/sync-file (:id file) (:id file))]] - (ths/run-store - store done events2 - (fn [new-state] - (let [;; ==== Get - file' (ths/get-file-from-store new-state) - c-frame1' (cths/get-shape file' :c-frame1) - tokens-frame1' (:applied-tokens c-frame1')] + step2 (fn [_] + (let [events2 [(dwl/sync-file (:id file) (:id file))]] + (ths/run-store + store done events2 + (fn [new-state] + (let [;; ==== Get + file' (ths/get-file-from-store new-state) + c-frame1' (cths/get-shape file' :c-frame1) + tokens-frame1' (:applied-tokens c-frame1')] ;; ==== Check - (t/is (= (count tokens-frame1') 2)) - (t/is (= (get tokens-frame1' :rx) "test-token-2")) - (t/is (= (get tokens-frame1' :ry) "test-token-2")) - (t/is (= (get c-frame1' :rx) 50)) - (t/is (= (get c-frame1' :ry) 50)))))))] + (t/is (= (count tokens-frame1') 2)) + (t/is (= (get tokens-frame1' :rx) "test-token-2")) + (t/is (= (get tokens-frame1' :ry) "test-token-2")) + (t/is (= (get c-frame1' :rx) 50)) + (t/is (= (get c-frame1' :ry) 50)))))))] - (tohs/run-store-async - store step2 events identity)))) + (tohs/run-store-async + store step2 events identity)))) (t/deftest remove-token-in-main (t/async - done - (let [;; ==== Setup - file (setup-file-with-copy) - store (ths/setup-store file) + done + (let [;; ==== Setup + file (setup-file-with-copy) + store (ths/setup-store file) ;; ==== Action - events [(wtch/unapply-token {:shape-ids [(cthi/id :frame1)] - :attributes #{:rx :ry} - :token (toht/get-token file "test-token-1")})] + events [(wtch/unapply-token {:shape-ids [(cthi/id :frame1)] + :attributes #{:rx :ry} + :token (toht/get-token file "test-token-1")})] - step2 (fn [_] - (let [events2 [(dwl/sync-file (:id file) (:id file))]] - (ths/run-store - store done events2 - (fn [new-state] - (let [;; ==== Get - file' (ths/get-file-from-store new-state) - c-frame1' (cths/get-shape file' :c-frame1) - tokens-frame1' (:applied-tokens c-frame1')] + step2 (fn [_] + (let [events2 [(dwl/sync-file (:id file) (:id file))]] + (ths/run-store + store done events2 + (fn [new-state] + (let [;; ==== Get + file' (ths/get-file-from-store new-state) + c-frame1' (cths/get-shape file' :c-frame1) + tokens-frame1' (:applied-tokens c-frame1')] ;; ==== Check - (t/is (= (count tokens-frame1') 0)) - (t/is (= (get c-frame1' :rx) 25)) - (t/is (= (get c-frame1' :ry) 25)))))))] + (t/is (= (count tokens-frame1') 0)) + (t/is (= (get c-frame1' :rx) 25)) + (t/is (= (get c-frame1' :ry) 25)))))))] - (tohs/run-store-async - store step2 events identity)))) + (tohs/run-store-async + store step2 events identity)))) (t/deftest modify-token (t/async - done - (let [;; ==== Setup - file (setup-file-with-copy) - store (ths/setup-store file) + done + (let [;; ==== Setup + file (setup-file-with-copy) + store (ths/setup-store file) ;; ==== Action - events [(dt/update-create-token {:token (ctob/make-token :name "test-token-1" - :type :border-radius - :value 66) - :prev-token-name "test-token-1"})] + events [(dt/update-create-token {:token (ctob/make-token :name "test-token-1" + :type :border-radius + :value 66) + :prev-token-name "test-token-1"})] - step2 (fn [_] - (let [events2 [(wtu/update-workspace-tokens) - (dwl/sync-file (:id file) (:id file))]] - (tohs/run-store-async - store done events2 - (fn [new-state] - (let [;; ==== Get - file' (ths/get-file-from-store new-state) - c-frame1' (cths/get-shape file' :c-frame1) - tokens-frame1' (:applied-tokens c-frame1')] + step2 (fn [_] + (let [events2 [(wtu/update-workspace-tokens) + (dwl/sync-file (:id file) (:id file))]] + (tohs/run-store-async + store done events2 + (fn [new-state] + (let [;; ==== Get + file' (ths/get-file-from-store new-state) + c-frame1' (cths/get-shape file' :c-frame1) + tokens-frame1' (:applied-tokens c-frame1')] ;; ==== Check - (t/is (= (count tokens-frame1') 2)) - (t/is (= (get tokens-frame1' :rx) "test-token-1")) - (t/is (= (get tokens-frame1' :ry) "test-token-1")) - (t/is (= (get c-frame1' :rx) 66)) - (t/is (= (get c-frame1' :ry) 66)))))))] + (t/is (= (count tokens-frame1') 2)) + (t/is (= (get tokens-frame1' :rx) "test-token-1")) + (t/is (= (get tokens-frame1' :ry) "test-token-1")) + (t/is (= (get c-frame1' :rx) 66)) + (t/is (= (get c-frame1' :ry) 66)))))))] - (tohs/run-store-async - store step2 events identity)))) + (tohs/run-store-async + store step2 events identity)))) (t/deftest change-token-in-copy-then-change-main (t/async - done - (let [;; ==== Setup - file (setup-file-with-copy) - store (ths/setup-store file) + done + (let [;; ==== Setup + file (setup-file-with-copy) + store (ths/setup-store file) ;; ==== Action - events [(wtch/apply-token {:shape-ids [(cthi/id :c-frame1)] - :attributes #{:rx :ry} - :token (toht/get-token file "test-token-2") - :on-update-shape wtch/update-shape-radius-all}) - (wtch/apply-token {:shape-ids [(cthi/id :frame1)] - :attributes #{:rx :ry} - :token (toht/get-token file "test-token-3") - :on-update-shape wtch/update-shape-radius-all})] + events [(wtch/apply-token {:shape-ids [(cthi/id :c-frame1)] + :attributes #{:rx :ry} + :token (toht/get-token file "test-token-2") + :on-update-shape wtch/update-shape-radius-all}) + (wtch/apply-token {:shape-ids [(cthi/id :frame1)] + :attributes #{:rx :ry} + :token (toht/get-token file "test-token-3") + :on-update-shape wtch/update-shape-radius-all})] - step2 (fn [_] - (let [events2 [(dwl/sync-file (:id file) (:id file))]] - (ths/run-store - store done events2 - (fn [new-state] - (let [;; ==== Get - file' (ths/get-file-from-store new-state) - c-frame1' (cths/get-shape file' :c-frame1) - tokens-frame1' (:applied-tokens c-frame1')] + step2 (fn [_] + (let [events2 [(dwl/sync-file (:id file) (:id file))]] + (ths/run-store + store done events2 + (fn [new-state] + (let [;; ==== Get + file' (ths/get-file-from-store new-state) + c-frame1' (cths/get-shape file' :c-frame1) + tokens-frame1' (:applied-tokens c-frame1')] ;; ==== Check - (t/is (= (count tokens-frame1') 2)) - (t/is (= (get tokens-frame1' :rx) "test-token-2")) - (t/is (= (get tokens-frame1' :ry) "test-token-2")) - (t/is (= (get c-frame1' :rx) 50)) - (t/is (= (get c-frame1' :ry) 50)))))))] + (t/is (= (count tokens-frame1') 2)) + (t/is (= (get tokens-frame1' :rx) "test-token-2")) + (t/is (= (get tokens-frame1' :ry) "test-token-2")) + (t/is (= (get c-frame1' :rx) 50)) + (t/is (= (get c-frame1' :ry) 50)))))))] - (tohs/run-store-async - store step2 events identity)))) + (tohs/run-store-async + store step2 events identity)))) (t/deftest remove-token-in-copy-then-change-main (t/async - done - (let [;; ==== Setup - file (setup-file-with-copy) - store (ths/setup-store file) + done + (let [;; ==== Setup + file (setup-file-with-copy) + store (ths/setup-store file) ;; ==== Action - events [(wtch/unapply-token {:shape-ids [(cthi/id :c-frame1)] - :attributes #{:rx :ry} - :token (toht/get-token file "test-token-1")}) - (wtch/apply-token {:shape-ids [(cthi/id :frame1)] - :attributes #{:rx :ry} - :token (toht/get-token file "test-token-3") - :on-update-shape wtch/update-shape-radius-all})] + events [(wtch/unapply-token {:shape-ids [(cthi/id :c-frame1)] + :attributes #{:rx :ry} + :token (toht/get-token file "test-token-1")}) + (wtch/apply-token {:shape-ids [(cthi/id :frame1)] + :attributes #{:rx :ry} + :token (toht/get-token file "test-token-3") + :on-update-shape wtch/update-shape-radius-all})] - step2 (fn [_] - (let [events2 [(dwl/sync-file (:id file) (:id file))]] - (ths/run-store - store done events2 - (fn [new-state] - (let [;; ==== Get - file' (ths/get-file-from-store new-state) - c-frame1' (cths/get-shape file' :c-frame1) - tokens-frame1' (:applied-tokens c-frame1')] + step2 (fn [_] + (let [events2 [(dwl/sync-file (:id file) (:id file))]] + (ths/run-store + store done events2 + (fn [new-state] + (let [;; ==== Get + file' (ths/get-file-from-store new-state) + c-frame1' (cths/get-shape file' :c-frame1) + tokens-frame1' (:applied-tokens c-frame1')] ;; ==== Check - (t/is (= (count tokens-frame1') 0)) - (t/is (= (get c-frame1' :rx) 25)) - (t/is (= (get c-frame1' :ry) 25)))))))] + (t/is (= (count tokens-frame1') 0)) + (t/is (= (get c-frame1' :rx) 25)) + (t/is (= (get c-frame1' :ry) 25)))))))] - (tohs/run-store-async - store step2 events identity)))) + (tohs/run-store-async + store step2 events identity)))) + +(t/deftest modify-token-all-types + (t/async + done + (let [;; ==== Setup + file (-> (cthf/sample-file :file1) + (ctht/add-tokens-lib) + (ctht/update-tokens-lib #(-> % + (ctob/add-set (ctob/make-token-set :name "test-token-set")) + (ctob/add-theme (ctob/make-token-theme :name "test-theme" + :sets #{"test-token-set"})) + (ctob/set-active-themes #{"/test-theme"}) + (ctob/add-token-in-set "token-radius" + (ctob/make-token :name "token-radius" + :type :border-radius + :value 10)) + (ctob/add-token-in-set "token-rotation" + (ctob/make-token :name "token-rotation" + :type :rotation + :value 30)) + (ctob/add-token-in-set "token-opacity" + (ctob/make-token :name "token-opacity" + :type :opacity + :value 0.7)) + (ctob/add-token-in-set "token-stroke-width" + (ctob/make-token :name "token-stroke-width" + :type :stroke-width + :value 2)) + (ctob/add-token-in-set "token-color" + (ctob/make-token :name "token-color" + :type :color + :value "#00ff00")) + (ctob/add-token-in-set "token-dimensions" + (ctob/make-token :name "token-dimensions" + :type :dimensions + :value 100)))) + (ctho/add-frame :frame1) + (ctht/apply-token-to-shape :frame1 "token-radius" [:rx :ry] [:rx :ry] 10) + (ctht/apply-token-to-shape :frame1 "token-rotation" [:rotation] [:rotation] 30) + (ctht/apply-token-to-shape :frame1 "token-opacity" [:opacity] [:opacity] 0.7) + (ctht/apply-token-to-shape :frame1 "token-stroke-width" [:stroke-width] [:stroke-width] 2) + (ctht/apply-token-to-shape :frame1 "token-color" [:stroke-color] [:stroke-color] "#00ff00") + (ctht/apply-token-to-shape :frame1 "token-color" [:fill] [:fill] "#00ff00") + (ctht/apply-token-to-shape :frame1 "token-dimensions" [:width :height] [:width :height] 100) + (cthc/make-component :component1 :frame1) + (cthc/instantiate-component :component1 :c-frame1)) + store (ths/setup-store file) + + ;; ==== Action + events [(dt/update-create-token {:token (ctob/make-token :name "token-radius" + :type :border-radius + :value 30) + :prev-token-name "token-radius"}) + (dt/update-create-token {:token (ctob/make-token :name "token-rotation" + :type :rotation + :value 45) + :prev-token-name "token-rotation"}) + (dt/update-create-token {:token (ctob/make-token :name "token-opacity" + :type :opacity + :value 0.9) + :prev-token-name "token-opacity"}) + (dt/update-create-token {:token (ctob/make-token :name "token-stroke-width" + :type :stroke-width + :value 8) + :prev-token-name "token-stroke-width"}) + (dt/update-create-token {:token (ctob/make-token :name "token-color" + :type :color + :value "#ff0000") + :prev-token-name "token-color"}) + (dt/update-create-token {:token (ctob/make-token :name "token-dimensions" + :type :dimensions + :value 200) + :prev-token-name "token-dimensions"})] + + step2 (fn [_] + (let [events2 [(wtu/update-workspace-tokens) + (dwl/sync-file (:id file) (:id file))]] + (tohs/run-store-async + store done events2 + (fn [new-state] + (let [;; ==== Get + file' (ths/get-file-from-store new-state) + c-frame1' (cths/get-shape file' :c-frame1) + tokens-frame1' (:applied-tokens c-frame1')] + + ;; ==== Check + (t/is (= (count tokens-frame1') 9)) + (t/is (= (get tokens-frame1' :rx) "token-radius")) + (t/is (= (get tokens-frame1' :ry) "token-radius")) + (t/is (= (get tokens-frame1' :rotation) "token-rotation")) + (t/is (= (get tokens-frame1' :opacity) "token-opacity")) + (t/is (= (get tokens-frame1' :stroke-width) "token-stroke-width")) + (t/is (= (get tokens-frame1' :stroke-color) "token-color")) + (t/is (= (get tokens-frame1' :fill) "token-color")) + (t/is (= (get tokens-frame1' :width) "token-dimensions")) + (t/is (= (get tokens-frame1' :height) "token-dimensions")) + (t/is (= (get c-frame1' :rx) 30)) + (t/is (= (get c-frame1' :ry) 30)) + (t/is (= (get c-frame1' :rotation) 45)) + (t/is (= (get c-frame1' :opacity) 0.9)) + (t/is (= (get-in c-frame1' [:strokes 0 :stroke-width]) 8)) + (t/is (= (get-in c-frame1' [:strokes 0 :stroke-color]) "#ff0000")) + (t/is (= (get-in c-frame1' [:fills 0 :fill-color]) "#ff0000")) + (t/is (mth/close? (get c-frame1' :width) 200)) + (t/is (mth/close? (get c-frame1' :height) 200)) + + (t/is (empty? (:touched c-frame1'))))))))] + + (tohs/run-store-async + store step2 events identity)))) \ No newline at end of file