From c8279fc9939a02b85cbdac35e01f0425ea7c9970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Mon, 24 Aug 2026 20:06:36 -0400 Subject: [PATCH] cn tests: assert fontconfig rule content and required menu entries Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp --- test/shell.d/omarchycn-test.sh | 35 +++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/test/shell.d/omarchycn-test.sh b/test/shell.d/omarchycn-test.sh index abe18168..73ba4c23 100755 --- a/test/shell.d/omarchycn-test.sh +++ b/test/shell.d/omarchycn-test.sh @@ -60,10 +60,25 @@ if grep -q 'OmarchyCN ime hotkey begin' "$HOME/.config/hypr/bindings.lua"; then fi pass "ime hotkey section surgery and menu migration round-trip" -# Fontconfig priority file is well-formed XML -python3 -c "import xml.etree.ElementTree as ET; ET.parse('$ROOT/cn/fontconfig/64-omarchycn-cjk.conf')" || - fail "fontconfig priority file parses as XML" -pass "fontconfig priority file is well-formed" +# Fontconfig priority file is well-formed and carries the required rules +python3 - "$ROOT/cn/fontconfig/64-omarchycn-cjk.conf" <<'PYEOF' || fail "fontconfig rules incomplete" +import sys +import xml.etree.ElementTree as ET +tree = ET.parse(sys.argv[1]) +text = ET.tostring(tree.getroot(), encoding="unicode") +required = [ + "Noto Sans CJK SC", "Noto Serif CJK SC", "Noto Sans Mono CJK SC", + "Noto Sans CJK JP", "Noto Sans CJK KR", "zh-cn", +] +missing = [r for r in required if r not in text] +weak_appends = [ + e for e in tree.getroot().iter("edit") + if e.get("mode") == "append" and e.get("binding") == "weak" +] +if missing or not weak_appends: + raise SystemExit(f"missing={missing} weak_appends={len(weak_appends)}") +PYEOF +pass "fontconfig priority file carries SC/JP/KR rules and weak fallback" # Menu: OmarchyCN entries parse and reference only existing commands node -e ' @@ -73,7 +88,17 @@ node -e ' .replace(/,(\s*[}\]])/g, "$1"); const menu = JSON.parse(src); const cn = Object.keys(menu).filter(k => k.startsWith("omarchycn")); - if (cn.length < 20) throw new Error("expected OmarchyCN entries, got " + cn.length); + const required = [ + "omarchycn", "omarchycn.mirrors.china", "omarchycn.mirrors.official", + "omarchycn.mirrors.benchmark", "omarchycn.mirrors.restore", + "omarchycn.chinese.ime", "omarchycn.chinese.fonts", "omarchycn.chinese.locale", + "omarchycn.chinese.hotkey-ctrl", "omarchycn.chinese.hotkey-super", + "omarchycn.display.s10", "omarchycn.display.s125", "omarchycn.display.s15", + "omarchycn.display.s16", "omarchycn.display.s175", "omarchycn.display.s20", + "omarchycn.diagnostics.doctor", "omarchycn.update", "omarchycn.about", + ]; + const gone = required.filter(k => !(k in menu)); + if (gone.length) throw new Error("missing menu entries: " + gone.join(", ")); for (const key of cn) { const action = menu[key].action || ""; const m = action.match(/omarchy-cn-[a-z-]+/);