#!/usr/bin/env bash # Every pinned application must resolve to an installed desktop entry. # # DockBody drops a pin it cannot resolve rather than drawing a broken icon, # which is the right behaviour at runtime and a terrible one to debug: a typo in # the shipped list, or an application that changed its desktop id, simply # removes an icon from the dock with nothing logged. # # Also asserts the Settings entry resolves and carries Panama's own icon, since # it is the first pin and the one most likely to be wrong after a rename. set -euo pipefail repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" harness="$repo_dir/config/dot/quickshell/dock-pin-harness.qml" config_home="$(mktemp -d /tmp/panama-dockpins.XXXXXX)" fail() { printf 'dock pins contract: %s\n' "$1" >&2 exit 1 } run() { XDG_CONFIG_HOME="$config_home" qs -p "$harness" "$@"; } harness_pid="" cleanup() { # By PID, never `pkill -f dock-pin-harness`: that pattern also matches the # shell running this script. [[ -n "$harness_pid" ]] && kill "$harness_pid" >/dev/null 2>&1 || true rm -rf "$config_home" } trap cleanup EXIT XDG_CONFIG_HOME="$config_home" qs -p "$harness" --daemonize >/dev/null for _ in $(seq 1 40); do run ipc show 2>/dev/null | rg -q '^target dock-pin-test$' && break sleep 0.1 done run ipc show 2>/dev/null | rg -q '^target dock-pin-test$' || fail 'test IPC target did not start' harness_pid="$(run list | awk '/Process ID:/ { print $3; exit }')" # DesktopEntries populates asynchronously; asking before it has finished reports # every pin as missing, which is a false failure rather than a real one. loaded=0 for _ in $(seq 1 60); do loaded="$(run ipc call dock-pin-test count 2>/dev/null || printf 0)" [[ "$loaded" =~ ^[0-9]+$ ]] && (( loaded > 0 )) && break sleep 0.25 done (( loaded > 0 )) || fail 'no desktop entries were discovered at all' state="$(run ipc call dock-pin-test resolve)" missing="$(jq -r '.missing | join(", ")' <<<"$state")" [[ -z "$missing" ]] || fail "these pinned applications do not resolve and would vanish from the dock: $missing" jq -e '.first.id == "panama-settings" and .first.found == true' <<<"$state" >/dev/null \ || fail "Panama Settings is not the first pin, or does not resolve: $(jq -c .first <<<"$state")" jq -e '.first.icon == "panama-settings"' <<<"$state" >/dev/null \ || fail "Settings is not using Panama's own icon: $(jq -r .first.icon <<<"$state")" icon="$HOME/.local/share/icons/hicolor/scalable/apps/panama-settings.svg" [[ -r "$icon" ]] || fail "the icon it names is not installed at $icon" trap - EXIT cleanup printf 'dock pins contract: PASS (%s pins, all resolve)\n' "$(jq -r .total <<<"$state")"