Establishes version control for the personal Logseq DB fork before starting the server-client architecture migration and domain features described in docs/agent-guide and the approved implementation plan. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
128 lines
5.5 KiB
Clojure
128 lines
5.5 KiB
Clojure
(ns logseq.tasks.lang-test
|
|
(:require [cljs.test :refer [deftest is testing]]
|
|
[logseq.tasks.lang-lint :as lang-lint]))
|
|
|
|
(deftest translation-placeholders-detect-placeholder-sets
|
|
(is (= #{"1" "2"}
|
|
(lang-lint/translation-placeholders "Open {1} from {2}")))
|
|
(is (= #{}
|
|
(lang-lint/translation-placeholders "Search with Google"))))
|
|
|
|
(deftest placeholder-mismatch-findings-detect-non-default-locale-errors
|
|
(testing "a localized value must match English placeholders exactly once it is defined"
|
|
(let [findings (lang-lint/placeholder-mismatch-findings
|
|
{:en {:electron/link-open-confirm "Are you sure?\n\n{1}"
|
|
:electron/write-file-failed-with-backup "Write failed {1} {2} {3}."}
|
|
:zh-Hant {:electron/link-open-confirm "確定要開啟此外部連結嗎?"
|
|
:electron/write-file-failed-with-backup "寫入失敗。備份檔案:{1}"}
|
|
:zh-CN {:electron/link-open-confirm "确定要打开此链接吗?\n\n{1}"
|
|
:electron/write-file-failed-with-backup "写入文件 {1} 失败,{2}。备份文件已保存到 {3}。"}})]
|
|
(is (= [{:lang :zh-Hant
|
|
:translation-key :electron/link-open-confirm
|
|
:expected-placeholders ["1"]
|
|
:actual-placeholders []
|
|
:default-value "Are you sure?\n\n{1}"
|
|
:localized-value "確定要開啟此外部連結嗎?"}
|
|
{:lang :zh-Hant
|
|
:translation-key :electron/write-file-failed-with-backup
|
|
:expected-placeholders ["1" "2" "3"]
|
|
:actual-placeholders ["1"]
|
|
:default-value "Write failed {1} {2} {3}."
|
|
:localized-value "寫入失敗。備份檔案:{1}"}]
|
|
findings)))))
|
|
|
|
(deftest translation-rich-validation-findings-report-rich-contract-mismatches
|
|
(testing "a localized rich translation must remain a zero-arg function once defined"
|
|
(is (= [{:lang :zh-Hant
|
|
:translation-key :e2ee/cloud-password-rich
|
|
:expected-value-kind :fn
|
|
:actual-value-kind :string}
|
|
{:lang :zh-Hant
|
|
:translation-key :on-boarding/main-title
|
|
:expected-value-kind :fn
|
|
:actual-value-kind :string}]
|
|
(lang-lint/rich-translation-mismatch-findings
|
|
{:en {:on-boarding/main-title (fn [] ["Welcome to " [:strong "Logseq!"]])
|
|
:e2ee/cloud-password-rich (fn [] ["Cloud sentence " [:span "Local sentence"]])
|
|
:e2ee/remember-password-rich (fn [] [[:span "Remember "] "your password."])}
|
|
:zh-Hant {:on-boarding/main-title "歡迎使用 Logseq"
|
|
:e2ee/cloud-password-rich "雲端密碼"
|
|
:e2ee/remember-password-rich (fn [] [[:span "請記住"] "你的密碼。"])}})))))
|
|
|
|
(deftest identical-translation-findings-report-defined-values-equal-to-english
|
|
(is (= [{:lang :ko
|
|
:translation-key :ui/cancel
|
|
:default-value "Cancel"}
|
|
{:lang :ko
|
|
:translation-key :ui/save
|
|
:default-value "Save"}]
|
|
(lang-lint/identical-translation-findings
|
|
{:en {:ui/cancel "Cancel"
|
|
:ui/save "Save"
|
|
:ui/close "Close"}
|
|
:ko {:ui/cancel "Cancel"
|
|
:ui/save "Save"
|
|
:ui/close "닫기"}
|
|
:fr {:ui/cancel "Annuler"}}
|
|
:ko))))
|
|
|
|
(deftest identical-translation-stats-count-defined-values-equal-to-english
|
|
(is (= [{:lang :en
|
|
:translation-count 2
|
|
:same-as-en-count 2}
|
|
{:lang :ko
|
|
:translation-count 2
|
|
:same-as-en-count 1}
|
|
{:lang :fr
|
|
:translation-count 1
|
|
:same-as-en-count 0}]
|
|
(lang-lint/identical-translation-stats
|
|
{:en {:ui/cancel "Cancel"
|
|
:ui/save "Save"}
|
|
:ko {:ui/cancel "Cancel"
|
|
:ui/save "저장"}
|
|
:fr {:ui/cancel "Annuler"}}))))
|
|
|
|
(deftest translation-summary-stats-report-untranslated-and-same-as-en-count
|
|
(is (= [{:lang :en
|
|
:translation-count 4
|
|
:untranslated-count nil
|
|
:same-as-en-count nil}
|
|
{:lang :fr
|
|
:translation-count 2
|
|
:untranslated-count 2
|
|
:same-as-en-count 1}
|
|
{:lang :ko
|
|
:translation-count 3
|
|
:untranslated-count 1
|
|
:same-as-en-count 2}]
|
|
(->> (lang-lint/translation-summary-stats
|
|
{:en {:ui/cancel "Cancel"
|
|
:ui/save "Save"
|
|
:ui/close "Close"
|
|
:ui/delete "Delete"}
|
|
:ko {:ui/cancel "Cancel"
|
|
:ui/save "저장"
|
|
:ui/close "Close"}
|
|
:fr {:ui/cancel "Annuler"
|
|
:ui/save "Save"}})
|
|
(sort-by :lang)
|
|
vec))))
|
|
|
|
(deftest sort-translation-summary-stats-keeps-en-first-then-sorts-by-untranslated-and-same-as-en-count
|
|
(is (= [:en :ko :fr :zh-Hant]
|
|
(->> [{:lang :fr
|
|
:untranslated-count 3
|
|
:same-as-en-count 1}
|
|
{:lang :en
|
|
:untranslated-count nil
|
|
:same-as-en-count nil}
|
|
{:lang :zh-Hant
|
|
:untranslated-count 1
|
|
:same-as-en-count 3}
|
|
{:lang :ko
|
|
:untranslated-count 3
|
|
:same-as-en-count 2}]
|
|
lang-lint/sort-translation-summary-stats
|
|
(mapv :lang)))))
|