Files
Panama/tests/quickshell/panama-commands-contract
T
Gabriel Brown 185d7edaa5 Open the windows you open together, together
Arrange the desktop, run "Save Layout as Project" from the launcher, name it.
"Open Project" lays it out again on free workspaces, so it never lands on top of
what you are already doing. Saved layouts are listed on the Desktop settings
page, which is where they are removed.

Recorded rather than written by hand, and a terminal's directory is most of why
it is worth having: without it a project opens three terminals in your home
folder and you change directory three times. This machine had two terminals in
the same project when it was written, and reopening there is the difference
between a layout and a working desktop.

Four things had to be found by running it, none of which reading would have
shown.

A terminal's directory is not the terminal's working directory -- that is where
it was launched from. The shell inside it is what has been cd'd. Reading the
wrong one looked correct for exactly as long as the terminals under test had
been started from the right place, which they had.

gtk-launch cannot place a window. It activates over D-Bus, so the process
Hyprland started exits and a [workspace N silent] rule has nothing left to apply
to; Nautilus landed on whatever workspace was in front of you. The Exec line
from the desktop entry is run directly instead. But DBusActivatable
applications do the same thing regardless, so the window is found afterwards and
moved by address -- which also means a window that never appeared is reported
rather than assumed.

/proc/PID/task/PID/children is a file of pids, not a directory. Listing it as
one always raised, so the fast path was never once taken and everything went
through pgrep.

And kitty's --directory needs an equals sign or the short -d; the
space-separated long form is accepted and silently ignored.

The contract exercises a save and open round trip against a stubbed compositor,
and reads a terminal's directory out of a real process tree rather than grepping
the source for a shell name -- an earlier version passed against a helper that
had been changed back, because the constant was still there.

Claude-Session: https://claude.ai/code/session_01Q84axqUE5inJhf5Jz9CFy1
2026-08-21 13:45:16 -04:00

146 lines
6.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
commands_dir="$repo_dir/config/local/share/vicinae/scripts"
work="$(mktemp -d /tmp/panama-commands.XXXXXX)"
dispatch_log="$work/dispatch.log"
fail() {
printf 'Panama commands contract: %s\n' "$1" >&2
exit 1
}
cleanup() {
rm -rf "$work"
}
trap cleanup EXIT
declare -A expected=(
[open-control-center]=control-center
[open-notifications]=notifications
[open-calendar]=calendar
[open-clipboard]=clipboard
[open-mission-control]=overview
[open-settings]=settings
[check-system-health]=health
[toggle-dnd]=dnd
[toggle-caffeine]=caffeine
[toggle-night-light]=night-light
[start-focus]=focus-start
[end-focus]=focus-end
[capture]=capture
[screen-intelligence]=intelligence
[quick-screenshot]=screenshot
[toggle-microphone]=microphone
[open-prism-gallery]=gallery
[restart-shell]=restart-shell
)
# The per-page settings commands are generated from the settings page list, so
# they are enumerated from that list rather than restated here -- a hand-written
# copy would have to be edited every time a page is added, which is exactly the
# kind of second list this generator exists to avoid.
sidebar="$repo_dir/config/dot/quickshell/modules/settings/SettingsSidebar.qml"
while read -r page; do
[[ -n "$page" ]] || continue
[[ "$page" == "home" ]] && continue
expected[settings-$page]="settings-page $page"
done < <(grep -oE '\{ page: "[a-z-]+"' "$sidebar" | sed 's/.*"\([a-z-]*\)"/\1/')
(( ${#expected[@]} > 18 )) || fail 'no generated per-page commands were found; run scripts/panama-settings-commands'
# Commands that do not go through panama-action, and should not.
#
# Every command above asks the shell to do something, so routing them through
# one dispatcher is what keeps that surface small. search-web is a different
# animal: it takes a query and opens a browser, and neither half needs the
# shell. Sending it through panama-action would mean a web search stops working
# when Quickshell is down -- which is exactly when somebody is reaching for the
# launcher to look up what went wrong.
#
# The project commands are the same shape: they record or restore a window
# layout, which is panama-project's job and involves the shell not at all.
#
# They are still commands, so everything else below applies to them: a title,
# a description, search vocabulary, the Panama icon, and closing quietly.
declare -a standalone=(search-web save-project open-project)
# Generated commands must match their source. A stale command dispatches to a
# page that has been renamed or removed, and the launcher reports nothing wrong.
"$repo_dir/config/dot/quickshell/scripts/panama-settings-commands" --check >/dev/null \
|| fail 'the generated per-page commands are stale; run scripts/panama-settings-commands'
mkdir -p "$work/home/.config/quickshell/scripts"
cat >"$work/home/.config/quickshell/scripts/panama-action" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$*" >>"$PANAMA_COMMAND_TEST_LOG"
EOF
chmod +x "$work/home/.config/quickshell/scripts/panama-action"
[[ -d "$commands_dir" ]] || fail 'Vicinae command directory is missing'
# Every file in the directory, not a glob on an extension. These scripts carry
# none: a shebang and the executable bit already select the interpreter, and an
# extension is one more thing that has to stay in sync -- which it did not.
mapfile -t actual_files < <(find "$commands_dir" -maxdepth 1 -type f -printf '%f\n' | sort)
declared=$(( ${#expected[@]} + ${#standalone[@]} ))
[[ ${#actual_files[@]} -eq $declared ]] \
|| fail "expected $declared commands, found ${#actual_files[@]}"
declare -A seen_titles=()
for script_name in "${!expected[@]}" "${standalone[@]}"; do
script="$commands_dir/$script_name"
[[ -x "$script" ]] || fail "$script_name is missing or not executable"
vicinae script check "$script" >/dev/null \
|| fail "$script_name is rejected by Vicinae"
title="$(sed -n 's/^# @vicinae.title //p' "$script")"
# No product prefix: this is the desktop's own settings, not a third-party
# add-on announcing itself in someone else's launcher. Uniqueness still
# matters, because two commands with one title are indistinguishable there.
[[ -n $title ]] || fail "$script_name has no title"
[[ $title != Panama* ]] || fail "$script_name still carries the product prefix: $title"
[[ -z ${seen_titles[$title]+x} ]] || fail "duplicate launcher title: $title"
seen_titles[$title]=1
grep -Fxq '# @vicinae.mode silent' "$script" \
|| fail "$script_name does not close quietly after success"
grep -Fq '# @vicinae.description ' "$script" \
|| fail "$script_name has no searchable description"
grep -Fq '# @vicinae.keywords ' "$script" \
|| fail "$script_name has no search vocabulary"
grep -Fxq '# @vicinae.icon ../../icons/hicolor/scalable/apps/panama-settings.svg' "$script" \
|| fail "$script_name does not use the Panama application identity"
if [[ $script_name == check-system-health ]]; then
[[ $title == 'Check System Health' ]] \
|| fail "health command has the wrong title: $title"
grep -Fxq '# @vicinae.schemaVersion 1' "$script" \
|| fail 'health command does not use schema version 1'
grep -Fxq '# @vicinae.keywords ["health", "doctor", "repair", "services"]' "$script" \
|| fail 'health command has the wrong search vocabulary'
grep -Fxq 'exec "$HOME/.config/quickshell/scripts/panama-action" health' "$script" \
|| fail 'health command bypasses the stable dispatcher path'
fi
# A standalone command has nothing to dispatch, and running it would open a
# browser at whoever is running the tests.
if [[ -z ${expected[$script_name]+x} ]]; then
if grep -Fq 'panama-action' "$script"; then
fail "$script_name is listed as standalone but goes through panama-action"
fi
continue
fi
: >"$dispatch_log"
HOME="$work/home" PANAMA_COMMAND_TEST_LOG="$dispatch_log" "$script"
dispatched="$(cat "$dispatch_log")"
[[ $dispatched == "${expected[$script_name]}" ]] \
|| fail "$script_name dispatched [$dispatched], expected [${expected[$script_name]}]"
done
printf 'Panama commands contract: PASS (%d commands)\n' "$declared"