Select-menu options gain an optional third field rendered under the label, filtered alongside it, and returned with the selection. The plugin picker uses it to show every plugin's id and act on the id the selection hands back, replacing the duplicate-name label suffix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
186 lines
7.2 KiB
Bash
Executable File
186 lines
7.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
|
|
|
require_command jq
|
|
|
|
TMPDIR=$(mktemp -d)
|
|
trap 'rm -rf "$TMPDIR"' EXIT
|
|
|
|
STUB_DIR="$TMPDIR/stub"
|
|
mkdir -p "$STUB_DIR"
|
|
|
|
# The picker reads the plugin list from omarchy-plugin-list and hands what it
|
|
# decided to a verb-specific command, so stubbing both ends shows which plugin
|
|
# a pick actually resolved to -- the thing a source-level check cannot see.
|
|
cat >"$STUB_DIR/omarchy-plugin-list" <<'STUB'
|
|
#!/bin/bash
|
|
cat "$FAKE_PLUGINS"
|
|
STUB
|
|
|
|
for command in omarchy-plugin-enable omarchy-plugin-disable; do
|
|
cat >"$STUB_DIR/$command" <<'STUB'
|
|
#!/bin/bash
|
|
printf '%s %s\n' "${0##*/}" "$*" >>"$FAKE_CALLS"
|
|
STUB
|
|
done
|
|
|
|
# Records the rows it was offered, then answers with the pick under test.
|
|
cat >"$STUB_DIR/omarchy-menu-select" <<'STUB'
|
|
#!/bin/bash
|
|
cat >"$FAKE_ROWS"
|
|
printf '%s\n' "$FAKE_PICK"
|
|
STUB
|
|
|
|
cat >"$STUB_DIR/omarchy-notification-send" <<'STUB'
|
|
#!/bin/bash
|
|
printf 'notification: %s\n' "$*" >>"$FAKE_CALLS"
|
|
STUB
|
|
|
|
cat >"$STUB_DIR/omarchy-launch-floating-terminal-with-presentation" <<'STUB'
|
|
#!/bin/bash
|
|
printf 'terminal: %s\n' "$*" >>"$FAKE_CALLS"
|
|
STUB
|
|
|
|
chmod +x "$STUB_DIR"/*
|
|
|
|
# Runs the picker against a plugin list, answering its prompt with $2. Leaves
|
|
# the rows it offered in $ROWS and what it called in $CALLS.
|
|
pick() {
|
|
local verb="$1" choice="$2"
|
|
|
|
: >"$TMPDIR/calls"
|
|
: >"$TMPDIR/rows"
|
|
HOME="$TMPDIR/home" \
|
|
PATH="$STUB_DIR:$PATH" \
|
|
FAKE_PLUGINS="$TMPDIR/plugins.json" \
|
|
FAKE_CALLS="$TMPDIR/calls" \
|
|
FAKE_ROWS="$TMPDIR/rows" \
|
|
FAKE_PICK="$choice" \
|
|
"$ROOT/bin/omarchy-menu-plugin" "$verb" >/dev/null 2>&1
|
|
|
|
ROWS=$(cat "$TMPDIR/rows")
|
|
CALLS=$(cat "$TMPDIR/calls")
|
|
}
|
|
|
|
# Two plugins can declare the same display name. The id rides along as row
|
|
# subtext and comes back with the selection, so the pick resolves by id.
|
|
cat >"$TMPDIR/plugins.json" <<'JSON'
|
|
[
|
|
{"id": "omarchy.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": true},
|
|
{"id": "tester.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false}
|
|
]
|
|
JSON
|
|
|
|
pick enable "$(printf 'Clock\ttester.clock')"
|
|
[[ $ROWS == *"$(printf 'Clock\tomarchy.clock')"* && $ROWS == *"$(printf 'Clock\ttester.clock')"* ]] \
|
|
|| fail "picker offers the id as subtext on every row" "$ROWS"
|
|
pass "picker offers the id as subtext on every row"
|
|
[[ $CALLS == *"omarchy-plugin-enable tester.clock"* ]] \
|
|
|| fail "picker acts on the row that was picked, not the one that shares its name" "$CALLS"
|
|
pass "picker acts on the row that was picked, not the one that shares its name"
|
|
|
|
pick remove "$(printf 'Clock\ttester.clock')"
|
|
[[ $CALLS == *"omarchy-plugin-remove tester.clock"* ]] \
|
|
|| fail "picker removes the plugin whose row was picked" "$CALLS"
|
|
pass "picker removes the plugin whose row was picked"
|
|
|
|
cat >"$TMPDIR/plugins.json" <<'JSON'
|
|
[
|
|
{"id": "acme.weather", "name": "Weather", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false}
|
|
]
|
|
JSON
|
|
|
|
pick enable "$(printf 'Weather\tacme.weather')"
|
|
[[ $CALLS == *"omarchy-plugin-enable acme.weather"* ]] \
|
|
|| fail "picker delegates plugin enablement to the plugin command" "$CALLS"
|
|
pass "picker delegates plugin enablement to the plugin command"
|
|
|
|
# Clone offers only first-party plugins that no installed clone points back at,
|
|
# then hands the pick to the clone command, which opens the result in $EDITOR.
|
|
cat >"$TMPDIR/plugins.json" <<'JSON'
|
|
[
|
|
{"id": "omarchy.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": true, "active": false, "canDisable": true, "firstParty": true},
|
|
{"id": "acme.weather", "name": "Weather", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false}
|
|
]
|
|
JSON
|
|
|
|
pick clone "$(printf 'Clock\tomarchy.clock')"
|
|
[[ $ROWS == *"Clock"* && $ROWS != *"Weather"* ]] ||
|
|
fail "clone picker offers only built-in plugins" "$ROWS"
|
|
pass "clone picker offers built-in plugins"
|
|
[[ $CALLS == *"terminal: omarchy-plugin-clone --edit omarchy.clock"* ]] ||
|
|
fail "clone picker delegates cloning and editing to the clone command" "$CALLS"
|
|
pass "clone picker clones and opens the personal plugin"
|
|
|
|
# Once a clone pointing back at the source is discovered, whatever it is named,
|
|
# the source no longer belongs in Clone.
|
|
cat >"$TMPDIR/plugins.json" <<'JSON'
|
|
[
|
|
{"id": "omarchy.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": true, "active": false, "canDisable": true, "firstParty": true},
|
|
{"id": "tester.clock", "name": "My Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false, "clonedFrom": "omarchy.clock"}
|
|
]
|
|
JSON
|
|
|
|
pick clone ""
|
|
[[ $CALLS == *"notification: No plugin to clone"* ]] ||
|
|
fail "clone picker offers an already cloned plugin" "$CALLS"
|
|
pass "clone picker omits plugins already cloned locally"
|
|
|
|
# The picker treats every plugin alike and leaves kind-specific behavior to the
|
|
# plugin command.
|
|
cat >"$TMPDIR/plugins.json" <<'JSON'
|
|
[
|
|
{"id": "acme.fancy", "name": "Fancy", "kinds": ["bar", "bar-widget"], "enabled": false, "active": false, "canDisable": false, "firstParty": false}
|
|
]
|
|
JSON
|
|
|
|
pick enable "$(printf 'Fancy\tacme.fancy')"
|
|
[[ $CALLS == *"omarchy-plugin-enable acme.fancy"* && $CALLS != *"--section"* ]] \
|
|
|| fail "picker delegates kind-specific enablement" "$CALLS"
|
|
pass "picker delegates kind-specific enablement"
|
|
|
|
# A bar has no off, so it is never offered under disable -- including this one,
|
|
# which is a widget too.
|
|
cat >"$TMPDIR/plugins.json" <<'JSON'
|
|
[
|
|
{"id": "acme.fancy", "name": "Fancy", "kinds": ["bar", "bar-widget"], "enabled": true, "active": true, "canDisable": false, "firstParty": false},
|
|
{"id": "omarchy.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": true, "active": false, "canDisable": true, "firstParty": true}
|
|
]
|
|
JSON
|
|
|
|
pick disable "$(printf 'Clock\tomarchy.clock')"
|
|
[[ $ROWS == *"Clock"* && $ROWS != *"Fancy"* ]] \
|
|
|| fail "picker keeps a bar out of disable" "$ROWS"
|
|
pass "picker keeps a bar out of disable"
|
|
|
|
# The bar in use is the row absent from enable; every other bar is one pick away.
|
|
cat >"$TMPDIR/plugins.json" <<'JSON'
|
|
[
|
|
{"id": "omarchy.bar", "name": "Bar", "kinds": ["bar"], "enabled": false, "active": false, "canDisable": false, "firstParty": true},
|
|
{"id": "tester.neon-bar", "name": "Neon Bar", "kinds": ["bar"], "enabled": true, "active": true, "canDisable": false, "firstParty": false}
|
|
]
|
|
JSON
|
|
|
|
pick enable "$(printf 'Bar\tomarchy.bar')"
|
|
[[ $ROWS == *"Bar"* && $ROWS != *"Neon Bar"* ]] \
|
|
|| fail "picker offers every bar except the one already running" "$ROWS"
|
|
pass "picker offers every bar except the one already running"
|
|
[[ $CALLS == *"omarchy-plugin-enable omarchy.bar"* ]] \
|
|
|| fail "picker returns to the built-in bar by enabling it" "$CALLS"
|
|
pass "picker returns to the built-in bar by enabling it"
|
|
|
|
# Nothing the verb can act on is said out loud, not opened as an empty list.
|
|
cat >"$TMPDIR/plugins.json" <<'JSON'
|
|
[
|
|
{"id": "omarchy.bar", "name": "Bar", "kinds": ["bar"], "enabled": true, "active": true, "canDisable": false, "firstParty": true}
|
|
]
|
|
JSON
|
|
|
|
pick enable ""
|
|
[[ $CALLS == *"notification: No plugin to enable"* ]] \
|
|
|| fail "picker says when a verb has nothing to act on" "$CALLS"
|
|
pass "picker says when a verb has nothing to act on"
|