diff --git a/test/shell.d/omarchycn-test.sh b/test/shell.d/omarchycn-test.sh new file mode 100755 index 00000000..5ec310dc --- /dev/null +++ b/test/shell.d/omarchycn-test.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +source "$(dirname -- "${BASH_SOURCE[0]}")/base-test.sh" + +export OMARCHY_PATH="$ROOT" +export PATH="$ROOT/bin:$PATH" + +TEST_HOME=$(mktemp -d) +trap 'rm -rf "$TEST_HOME"' EXIT +export HOME="$TEST_HOME" + +# Version format +version=$("$ROOT/bin/omarchy-cn-version") +[[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+.*-cn\.[0-9]+$ ]] || fail "cn version format" "$version" +pass "omarchy-cn-version reports -cn." + +# Mirror probe: dead host degrades to zeros without aborting under set -e +probe_out=$( + set -euo pipefail + source "$ROOT/cn/lib/mirror.sh" + cn_mirror_probe "https://invalid.invalid.example" +) +[[ $probe_out == "0 0 unknown" ]] || fail "dead mirror probes as 0 0 unknown" "$probe_out" +pass "mirror probe degrades cleanly on dead host" + +# Dev-mirror: apply china writes npm registry, unrelated keys survive re-apply +echo "save-exact=true" > "$HOME/.npmrc" +omarchy-cn-dev-mirror-apply china --target npm > /dev/null +grep -q '^registry=https://registry.npmmirror.com$' "$HOME/.npmrc" || fail "npm china registry written" +grep -q '^save-exact=true$' "$HOME/.npmrc" || fail "unrelated npmrc keys preserved" +pass "dev-mirror apply china manages npm registry non-destructively" + +# Dev-mirror: cargo official leaves no crates-io takeover +omarchy-cn-dev-mirror-apply china --target cargo > /dev/null +omarchy-cn-dev-mirror-apply official --target cargo > /dev/null +if grep -q "crates-io" "$HOME/.cargo/config.toml"; then + fail "cargo official removes managed source block" +fi +pass "dev-mirror cargo official removes the managed block" + +# IME: profile installs rime as default, hotkey surgery keeps other sections +mkdir -p "$HOME/.config/fcitx5" +cp "$ROOT/cn/fcitx5/profile" "$HOME/.config/fcitx5/profile" +grep -q '^DefaultIM=rime$' "$HOME/.config/fcitx5/profile" || fail "shipped profile defaults to rime" +printf '[Behavior]\nShareInputState=No\n\n[Hotkey/TriggerKeys]\n0=Zenkaku_Hankaku\n' > "$HOME/.config/fcitx5/config" +omarchy-cn-ime-hotkey super-space > /dev/null +grep -q '^ShareInputState=No$' "$HOME/.config/fcitx5/config" || fail "hotkey surgery preserves other sections" +grep -q '^0=Super+space$' "$HOME/.config/fcitx5/config" || fail "hotkey surgery sets trigger" +grep -q 'SUPER + ALT + SPACE' "$HOME/.config/hypr/bindings.lua" || fail "menu migration block written" +omarchy-cn-ime-hotkey ctrl-space > /dev/null +if grep -q 'OmarchyCN ime hotkey begin' "$HOME/.config/hypr/bindings.lua"; then + fail "ctrl-space removes migration block" +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" + +# Menu: OmarchyCN entries parse and reference only existing commands +node -e ' + const fs = require("fs"); + const src = fs.readFileSync(process.argv[1], "utf8") + .split("\n").filter(l => !l.trim().startsWith("//")).join("\n") + .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); + for (const key of cn) { + const action = menu[key].action || ""; + const m = action.match(/omarchy-cn-[a-z-]+/); + if (m) { + fs.accessSync(process.argv[2] + "/" + m[0], fs.constants.X_OK); + } + } +' "$ROOT/default/omarchy/omarchy-menu.jsonc" "$ROOT/bin" || + fail "OmarchyCN menu entries reference existing executable commands" +pass "OmarchyCN menu entries parse and reference real commands"