diff --git a/common/src/app/common/test_helpers/composable/shadow.cljc b/common/src/app/common/test_helpers/composable/shadow.cljc index 5b8058b8d8..0c008e23a1 100644 --- a/common/src/app/common/test_helpers/composable/shadow.cljc +++ b/common/src/app/common/test_helpers/composable/shadow.cljc @@ -397,12 +397,24 @@ (if-let [[main _] (source after new-paths new-main-id shape)] (let [path (get new-paths (:id main)) [old old-main groups] (get old-copies path) - old-main (or old-main (get old-by-path path))] + old-main (or old-main (get old-by-path path)) + text-differences (when (= :text (:type main)) + (thtx/override-units (:content old-main) (:content main))) + carried-text-units (into #{} + (keep (fn [[group unit]] + (when (and (contains? groups group) + (not (contains? text-differences unit))) + unit))) + text-groups) + mixed-typography? (some #(not= (contains? carried-text-units :typography) + (contains? carried-text-units %)) + [:family :weight :size :line-height :spacing :case])] (reduce-kv (fn [result group _] (if-let [unit (get text-groups group)] (cond-> result - (and (not (contains? (thtx/override-units (:content old-main) (:content main)) unit)) + (and (not (and (= unit :typography) mixed-typography?)) + (not (contains? text-differences unit)) (not (same-value? main group {:content (:content old)}))) (-> (assoc-in [(:id shape) group] {:content (:content old)}) (assoc-in [(:id shape) :content-group] {}))) diff --git a/common/test/common_tests/logic/composable_gen_test.cljc b/common/test/common_tests/logic/composable_gen_test.cljc index 93376114d6..25a3d0529a 100644 --- a/common/test/common_tests/logic/composable_gen_test.cljc +++ b/common/test/common_tests/logic/composable_gen_test.cljc @@ -388,6 +388,45 @@ (t/is (= {} (get-in result [:result-text :content-group]))) (t/is (false? (shadow/same-value? (:result-text after) :text-content-size expected))))))) +(t/deftest switch-shadow-keeps-a-typography-only-with-its-style-ownership + (doseq [[new-size keep-reference?] [[14 true] [22 false]]] + (let [content #(thtx/content [[["Same text" {:size %}]]]) + applied (thtx/content + (thtx/apply-typography [[["Same text"]]] :heading + {:family "Roboto" :weight 700 :italic true :size 22 + :line-height 1.6 :spacing 2 :case "uppercase"})) + root {:type :frame :name "Board" :width 100 :height 100 :rotation 0} + text {:type :text :name "Caption" :width 70 :height 25 :rotation 0} + before {:old (assoc root :id :old :shapes [:old-text]) + :old-text (assoc text :id :old-text :parent-id :old :content (content 14)) + :copy (assoc root :id :copy :shape-ref :old :shapes [:copy-text]) + :copy-text (assoc text :id :copy-text :shape-ref :old-text :parent-id :copy :content applied)} + after {:new (assoc root :id :new :shapes [:new-text]) + :new-text (assoc text :id :new-text :parent-id :new :content (content new-size)) + :copy (assoc root :id :copy :shape-ref :new :shapes [:result-text]) + ;; A corrupt result must not supply the model's expected values. + :result-text (assoc text :id :result-text :shape-ref :new-text :parent-id :copy + :content (content 99))} + groups #{:content-group :text-content-typography :text-content-family + :text-content-weight :text-content-size :text-content-line-height + :text-content-spacing :text-content-case} + model {:copy-text (zipmap groups (repeat {:content applied}))} + predicted (get (shadow/swap model before after :copy :old :new true) :result-text) + expected-groups (cond-> groups + (not keep-reference?) (disj :text-content-size :text-content-typography))] + (t/is (= expected-groups (set (keys predicted)))) + (t/is (false? (shadow/same-value? (:result-text after) :text-content-family + (:text-content-family predicted)))) + (when keep-reference? + (t/is (false? (shadow/same-value? (:result-text after) :text-content-typography + (:text-content-typography predicted)))))))) + +(t/deftest typography-ownership-stays-consistent-when-a-variant-changes-size + (t/is (map? (cg/run {:world [2 0 {:library true :variants true :rich-variants true + :text true :text-styles true :layout nil :layout-copies true}] + :ops [[:text-style 4 8 1] [:switch 1 0 0 0] + [:undo] [:undo] [:redo] [:redo]]})))) + (t/deftest source-library-edits-wait-for-explicit-consumer-acceptance (let [initial (cg/initial-state [2 1 {:library true :stale-libraries true}]) situation (:situation initial) diff --git a/frontend/test/frontend_tests/composable_tests/generated_test.cljs b/frontend/test/frontend_tests/composable_tests/generated_test.cljs index a65ee91408..9d0c671ae8 100644 --- a/frontend/test/frontend_tests/composable_tests/generated_test.cljs +++ b/frontend/test/frontend_tests/composable_tests/generated_test.cljs @@ -337,6 +337,12 @@ :ops [[:swap 0 0 0 0] [:text 23 3 1 0] [:text-style 22 8 1] [:undo] [:undo] [:undo] [:redo] [:redo] [:redo]]}))) +(t/deftest ^:async typography-ownership-stays-consistent-when-a-variant-changes-size + (await (replay {:world [2 0 {:library true :variants true :rich-variants true + :text true :text-styles true :layout nil :layout-copies true}] + :ops [[:text-style 4 8 1] [:switch 1 0 0 0] + [:undo] [:undo] [:redo] [:redo]]}))) + (t/deftest ^:async detaching-after-a-nested-switch-keeps-placement-stable-through-sync (await (replay {:world [2 2 {:library true :variants true :rich-variants true :text true :text-styles true :layout :flex :layout-copies true}]