penpot/common/test/common_tests/logic/text_notation_test.cljc
alonso.torres 2412b793ca ✨ Test what copy texts keep through sync and switches
Add a battery of tests for text overrides in copies.
- A short notation for text content in tests (thtx): paragraphs of
  runs with short style names, read back with equal runs joined,
  edits in the notation, set-text and set-content through the change
  path, and the override rule for texts (override-units), which says
  which overrides a copy must hold against its main.
- Sync matrix: every whole-text copy edit against every main edit,
  plus the cards of the worked examples, the "Hello world" table, a
  token on a copy, typographies and a library color sync. Where the
  code differs from decisions (k) to (o), the result is pinned
  against F72 to F80.
- Switch matrix: copy edits against variants that differ in letters,
  size, color, a new line or a bolded word; F76, F77, F79 and F81
  pinned.
- Composable case BA: EditText also edits fills, font family and a
  whole text; the copy and the main change different styles, then
  reset or update main, in both runners; F72 pinned.
- Editor output: the content the WASM and v1 editors commit when a
  copy text is typed into, retyped, split with Enter and has a word
  bolded, recorded in the workspace and replayed on a copy. Typing
  sets only the text groups and a style change no text override;
  F79 pinned on both editors' content.
2026-10-13 19:58:34 +02:00

85 lines
4.1 KiB
Clojure

;; 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 common-tests.logic.text-notation-test
"The text notation of `app.common.test-helpers.texts`."
(:require
[app.common.test-helpers.files :as thf]
[app.common.test-helpers.ids-map :as thi]
[app.common.test-helpers.shapes :as ths]
[app.common.test-helpers.texts :as thtx]
[app.common.types.text :as txt]
[clojure.test :as t]))
(t/use-fixtures :each thi/test-fixture)
(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))
[run1 run2] (txt/node-seq txt/is-text-node? content)]
(t/testing "every run carries every run style, fills included"
(t/is (= (assoc thtx/base-style :text "Price: ") run1))
(t/is (= (assoc thtx/base-style
:text "$10"
:font-weight "700"
:font-variant-id "bold"
:fills [{:fill-color "#FF0000" :fill-opacity 1}])
run2)))
(t/testing "a paragraph carries its styles and those of its first run"
(t/is (= (merge thtx/base-style thtx/base-paragraph-style)
(dissoc paragraph :type :children))))
(t/testing "the root carries the vertical alignment"
(t/is (= "top" (:vertical-align content))))))
(t/deftest view-reads-content-back-into-the-notation
(thi/new-id! :file1)
(thi/new-id! :body)
(doseq [text [[[["Hello world"]]]
[[["Price: "] ["$10" {:weight 700}]]]
[[["Add to cart" {:family "Roboto" :weight 600 :italic true :size 18 :spacing 2
:case "uppercase" :decoration "underline" :color :blue}]]]
[{:valign "bottom"}
[{:align "center" :direction "rtl" :line-height 1.5} ["Summer " {:weight 700}] ["sale"]]
[["Ends Sunday"]]]
[[["Read the guide" {:typography :body}]]]
[[["odd" {:font-variant-id "bold"}]]]]]
(t/is (= text (thtx/normalize text)))))
(t/deftest view-joins-runs-with-equal-styles
(t/is (= [[["Hello world"]]]
(thtx/normalize [[["Hello"] [" "] ["world"]]])))
(t/is (= [[["Hello"]] [[""]]]
(thtx/normalize [[["Hello"] [""]] [[""]]]))))
(t/deftest edits-of-a-text-in-the-notation
(thi/new-id! :file1)
(thi/new-id! :body)
(let [typed (thtx/apply-typography [[["Read"]]] :body {:family "Roboto" :size 16 :line-height 1.6})]
(t/is (= [[{:line-height 1.6} ["Read" {:family "Roboto" :size 16 :typography :body}]]]
typed))
(t/testing "changing a style the typography sets drops the typography"
(t/is (= [[{:line-height 1.6} ["Read" {:family "Roboto" :size 20}]]]
(thtx/restyle typed :size 20)))
(t/is (= [[{:line-height 2} ["Read" {:family "Roboto" :size 16}]]]
(thtx/restyle-paragraphs typed :line-height 2))))
(t/testing "changing another style keeps it"
(t/is (= [[{:line-height 1.6} ["Read" {:family "Roboto" :size 16 :typography :body :color :red}]]]
(thtx/restyle typed :color :red)))))
(t/is (= [[{:align "center"} ["Buy now" {:weight 700}]]
[{:align "center"} ["Ends Sunday" {:weight 700}]]]
(thtx/set-letters [[{:align "center"} ["Add " {:weight 700}] ["to cart"]]]
"Buy now\nEnds Sunday")))
(t/is (= [{:valign "bottom"} [["Hello"]]]
(thtx/set-valign [[["Hello"]]] "bottom"))))
(t/deftest set-text-commits-the-content-through-the-change-path
(let [file (-> (thf/sample-file :file1)
(thtx/add-text-component-with-copy [[["Hello world"]]])
(thtx/set-text :copy-child [[["Hello world" {:color :red}]]]))]
(t/is (= [[["Hello world" {:color :red}]]] (thtx/text-of file :copy-child)))
(t/is (= #{:content-group :text-content-attribute}
(:touched (ths/get-shape file :copy-child))))))