From e4fb356cb569e0700fe95cd25229250f2eb5b432 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 28 Oct 2026 00:06:57 +0100 Subject: [PATCH] :bug: Replace stale font identities in text test edits Clear raw font identity fields owned by a requested family, weight or italic edit. Preserve the other font unit and retain opaque identities when changing an unrelated style such as size (F226). Four assertions fail before the correction. Focused notation, source, text sync/switch and golden checks pass 51 tests and 1,887 assertions. Full common JVM/JS, frontend, backend and exporter suites and applicable lint/format checks pass. All six generated properties pass 40 programs at seed 712. Golden data and production behavior are unchanged. AI-assisted-by: GPT-6 --- common/src/app/common/test_helpers/texts.cljc | 8 ++- .../logic/text_notation_test.cljc | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/common/src/app/common/test_helpers/texts.cljc b/common/src/app/common/test_helpers/texts.cljc index 079255509f..06fcfeeb71 100644 --- a/common/src/app/common/test_helpers/texts.cljc +++ b/common/src/app/common/test_helpers/texts.cljc @@ -332,14 +332,18 @@ (defn restyle "Set the run style `k` to `v` on every run of `text`. - Named colors and explicit fills replace each other." + Named colors and explicit fills replace each other. Font edits replace + stale raw identities while preserving the other font unit." [text k v] (update-paragraphs text (fn [[style runs]] [style (map (fn [[letters run-style]] [letters (cond-> (assoc run-style k v) (= k :color) (dissoc :fills) - (= k :fills) (dissoc :color))]) + (= k :fills) (dissoc :color) + (= k :family) (dissoc :font-family :font-id) + (= k :weight) (dissoc :font-weight :font-variant-id) + (= k :italic) (dissoc :font-style :font-variant-id))]) (detach-typography runs k))]))) (defn restyle-paragraphs diff --git a/common/test/common_tests/logic/text_notation_test.cljc b/common/test/common_tests/logic/text_notation_test.cljc index 23d5b5c912..c8ed56c220 100644 --- a/common/test/common_tests/logic/text_notation_test.cljc +++ b/common/test/common_tests/logic/text_notation_test.cljc @@ -30,6 +30,60 @@ (t/is (= [[["Library text" {:fills nil :size 18}]]] styled)) (t/is (nil? (get-in (thtx/content styled) [:children 0 :children 0 :children 0 :fills]))))) +(defn- get-run + [text] + (first (txt/node-seq txt/is-text-node? (thtx/content text)))) + +(t/deftest font-family-edit-replaces-the-raw-family-identity + (let [text (thtx/normalize [[["Custom font" {:family "Roboto" :font-id "custom-font" + :weight 700 :font-style "oblique" + :font-variant-id "opaque-variant" :size 18 :color :blue}]]]) + before (get-run text) + after (get-run (thtx/restyle text :family "Inter"))] + (t/is (= {:font-family "Inter" :font-id "gfont-inter"} + (select-keys after [:font-family :font-id]))) + (t/is (= (select-keys before [:font-weight :font-style :font-variant-id]) + (select-keys after [:font-weight :font-style :font-variant-id])) + "a family edit preserves the weight unit's opaque identity") + (t/is (= (select-keys before [:text :font-size :fills]) + (select-keys after [:text :font-size :fills]))))) + +(t/deftest font-weight-edit-replaces-the-raw-variant-identity + (let [text (thtx/normalize [[["Custom font" {:family "Roboto" :font-id "custom-font" + :font-variant-id "opaque-variant" :italic true + :size 18 :color :blue}]]]) + before (get-run text) + after (get-run (thtx/restyle text :weight 700))] + (t/is (= {:font-weight "700" :font-style "italic" :font-variant-id "700italic"} + (select-keys after [:font-weight :font-style :font-variant-id]))) + (t/is (= (select-keys before [:font-family :font-id]) + (select-keys after [:font-family :font-id]))) + (t/is (= (select-keys before [:text :font-size :fills]) + (select-keys after [:text :font-size :fills]))))) + +(t/deftest font-style-edit-replaces-the-raw-style-and-variant-identities + (doseq [[italic style variant] [[true "italic" "700italic"] [false "normal" "700"]]] + (let [text (thtx/normalize [[["Custom font" {:family "Roboto" :font-id "custom-font" + :weight 700 :font-style "oblique" + :font-variant-id "opaque-variant" :size 18 :color :blue}]]]) + before (get-run text) + after (get-run (thtx/restyle text :italic italic))] + (t/is (= {:font-weight "700" :font-style style :font-variant-id variant} + (select-keys after [:font-weight :font-style :font-variant-id]))) + (t/is (= (select-keys before [:font-family :font-id]) + (select-keys after [:font-family :font-id]))) + (t/is (= (select-keys before [:text :font-size :fills]) + (select-keys after [:text :font-size :fills])))))) + +(t/deftest other-text-edits-keep-opaque-font-identities + (let [text (thtx/normalize [[["Custom font" {:family "Roboto" :font-id "custom-font" + :weight 700 :font-style "oblique" + :font-variant-id "opaque-variant" :size 18 :color :blue}]]]) + before (get-run text) + after (get-run (thtx/restyle text :size 24))] + (t/is (= "24" (:font-size after))) + (t/is (= (dissoc before :font-size) (dissoc after :font-size))))) + (t/deftest content-is-written-as-the-editors-write-it (let [content (thtx/content [[["Price: "] ["$10" {:weight 700 :color :red}]]]) paragraph (first (txt/node-seq txt/is-paragraph-node? content))