Simplify bar plugin management (#6435)
This commit is contained in:
+62
-108
@@ -208,14 +208,27 @@ pass "Hyprland bootstrap reloads cached Omarchy config modules"
|
||||
TMPDIR=$(mktemp -d)
|
||||
mkdir -p "$TMPDIR/home/.config/omarchy"
|
||||
|
||||
ipc_mock_bin="$TMPDIR/ipc-mock"
|
||||
mkdir -p "$ipc_mock_bin"
|
||||
cat >"$ipc_mock_bin/omarchy-shell" <<'SH'
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
mkdir -p "$HOME/.local/state/omarchy"
|
||||
printf '%s\n' "$*" >>"$HOME/.local/state/omarchy/shell-ipc-calls"
|
||||
printf 'ok\n'
|
||||
SH
|
||||
chmod +x "$ipc_mock_bin/omarchy-shell"
|
||||
export PATH="$ipc_mock_bin:$PATH"
|
||||
|
||||
cat >"$TMPDIR/home/.config/omarchy/shell.json" <<'JSON'
|
||||
{
|
||||
"version": 1,
|
||||
"bar": {
|
||||
"layout": {
|
||||
"left": [{ "id": "omarchy.menu" }, { "id": "omarchy.workspaces" }],
|
||||
"center": [{ "id": "omarchy.clock" }, { "id": "omarchy.weather" }],
|
||||
"right": [{ "id": "omarchy.tray" }, { "id": "omarchy.bluetooth" }]
|
||||
"left": [{ "id": "omarchy.menu" }, { "id": "omarchy.workspaces" }, { "id": "omarchy.active-window" }],
|
||||
"center": [{ "id": "omarchy.clock" }, { "id": "omarchy.weather" }, { "id": "omarchy.system-update" }, { "id": "omarchy.tailscale" }],
|
||||
"right": [{ "id": "omarchy.tray" }, { "id": "omarchy.microphone" }, { "id": "omarchy.bluetooth" }]
|
||||
}
|
||||
},
|
||||
"plugins": []
|
||||
@@ -250,75 +263,20 @@ HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar reset
|
||||
jq -e '.bar.id == null' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config resets to built-in bar option"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin add omarchy.tailscale
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
.bar.layout.center | ids == ["omarchy.clock", "omarchy.weather", "omarchy.tailscale"]
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config defaults widgets without a section to center"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar move omarchy.active-window right
|
||||
grep -Fqx 'shell moveBarWidget omarchy.active-window {"section":"right"}' \
|
||||
"$TMPDIR/home/.local/state/omarchy/shell-ipc-calls"
|
||||
pass "bar move accepts a positional target section"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin add omarchy.active-window
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
.bar.layout.left | ids == ["omarchy.menu", "omarchy.workspaces", "omarchy.active-window"]
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config uses a widget's default section"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar move omarchy.active-window left
|
||||
grep -Fqx 'shell moveBarWidget omarchy.active-window {"section":"left"}' \
|
||||
"$TMPDIR/home/.local/state/omarchy/shell-ipc-calls"
|
||||
pass "bar move can restore a widget with positional syntax"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin add omarchy.media
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
.bar.layout.center | ids == ["omarchy.clock", "omarchy.weather", "omarchy.media", "omarchy.tailscale"]
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin remove omarchy.media >/dev/null
|
||||
pass "shell config honors a center default section"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin add omarchy.dropbox
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
.bar.layout.right | ids == ["omarchy.tray", "omarchy.dropbox", "omarchy.bluetooth"]
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin remove omarchy.dropbox >/dev/null
|
||||
pass "shell config honors a right default section"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin add omarchy.system-update center
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
.bar.layout.center | ids == ["omarchy.clock", "omarchy.weather", "omarchy.system-update", "omarchy.tailscale"]
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config appends center widgets after weather"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin add omarchy.microphone right
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
.bar.layout.right | ids == ["omarchy.tray", "omarchy.microphone", "omarchy.bluetooth"]
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config moves existing widgets without duplicates"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin move omarchy.active-window right
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
(.bar.layout.left | ids == ["omarchy.menu", "omarchy.workspaces"]) and
|
||||
(.bar.layout.right | ids == ["omarchy.tray", "omarchy.active-window", "omarchy.microphone", "omarchy.bluetooth"])
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "bar plugin move accepts a positional target section"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin move omarchy.active-window left
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
(.bar.layout.left | ids == ["omarchy.menu", "omarchy.workspaces", "omarchy.active-window"]) and
|
||||
(.bar.layout.right | ids == ["omarchy.tray", "omarchy.microphone", "omarchy.bluetooth"])
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "bar plugin move can restore a widget with positional syntax"
|
||||
|
||||
if HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin move omarchy.active-window left --section right 2>/dev/null; then
|
||||
fail "bar plugin move accepted positional and flagged target sections"
|
||||
if HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar move omarchy.active-window left --section right 2>/dev/null; then
|
||||
fail "bar move accepted positional and flagged target sections"
|
||||
fi
|
||||
pass "bar plugin move rejects conflicting target section syntax"
|
||||
|
||||
if HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin add local.nonexistent-widget 2>/dev/null; then
|
||||
fail "bar plugin add accepted an unknown widget"
|
||||
fi
|
||||
pass "bar plugin add rejects an unknown widget"
|
||||
pass "bar move rejects conflicting target section syntax"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar position bottom
|
||||
jq -e '
|
||||
@@ -339,43 +297,25 @@ HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar transparent toggle
|
||||
jq -e '.bar.transparent == false' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config toggles bar transparency"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin drop omarchy.active-window
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
(.bar.layout.left | ids == ["omarchy.menu", "omarchy.workspaces"]) and
|
||||
(.bar.layout.center | ids == ["omarchy.clock", "omarchy.weather", "omarchy.system-update", "omarchy.tailscale"]) and
|
||||
(.bar.layout.right | ids == ["omarchy.tray", "omarchy.microphone", "omarchy.bluetooth"])
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config drops widgets from any section"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar set omarchy.bluetooth enabled false --json
|
||||
grep -Fqx 'shell setBarWidget omarchy.bluetooth enabled false {}' \
|
||||
"$TMPDIR/home/.local/state/omarchy/shell-ipc-calls"
|
||||
pass "bar set accepts false JSON values"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin remove omarchy.system-update
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
.bar.layout.center | ids == ["omarchy.clock", "omarchy.weather", "omarchy.tailscale"]
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config removes widgets with remove alias"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar set omarchy.bluetooth optional null --json
|
||||
grep -Fqx 'shell setBarWidget omarchy.bluetooth optional null {}' \
|
||||
"$TMPDIR/home/.local/state/omarchy/shell-ipc-calls"
|
||||
pass "bar set accepts null JSON values"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin set omarchy.bluetooth enabled false --json
|
||||
jq -e '
|
||||
any(.bar.layout.right[]; .id == "omarchy.bluetooth" and .enabled == false)
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "bar plugin set accepts false JSON values"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin set omarchy.bluetooth optional null --json
|
||||
jq -e '
|
||||
any(.bar.layout.right[]; .id == "omarchy.bluetooth" and has("optional") and .optional == null)
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "bar plugin set accepts null JSON values"
|
||||
|
||||
if HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin set omarchy.bluetooth broken '{' --json 2>/dev/null; then
|
||||
fail "bar plugin set accepted malformed JSON"
|
||||
if HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar set omarchy.bluetooth broken '{' --json 2>/dev/null; then
|
||||
fail "bar set accepted malformed JSON"
|
||||
fi
|
||||
pass "bar plugin set rejects malformed JSON"
|
||||
pass "bar set rejects malformed JSON"
|
||||
|
||||
if HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar-plugin set omarchy.bluetooth broken 'false null' --json 2>/dev/null; then
|
||||
fail "bar plugin set accepted multiple JSON values"
|
||||
if HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar set omarchy.bluetooth broken 'false null' --json 2>/dev/null; then
|
||||
fail "bar set accepted multiple JSON values"
|
||||
fi
|
||||
pass "bar plugin set rejects multiple JSON values"
|
||||
pass "bar set rejects multiple JSON values"
|
||||
|
||||
mock_bin="$TMPDIR/mock-bin"
|
||||
mkdir -p "$mock_bin"
|
||||
@@ -400,7 +340,8 @@ SH
|
||||
|
||||
cat >"$mock_bin/omarchy-shell" <<'SH'
|
||||
#!/bin/bash
|
||||
exit 0
|
||||
[[ ${OMARCHY_TEST_SHELL_DOWN:-0} == "1" ]] && exit 1
|
||||
printf 'ok\n'
|
||||
SH
|
||||
|
||||
cat >"$mock_bin/omarchy-installed-service-dropbox" <<'SH'
|
||||
@@ -430,10 +371,22 @@ pass "bar defaults restores the stock bar"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" PATH="$mock_path" OMARCHY_TEST_DROPBOX=1 OMARCHY_TEST_TAILSCALE=1 omarchy-bar defaults
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
(.bar.layout.right | ids | index("omarchy.dropbox") != null) and
|
||||
(.bar.layout.center | ids | index("omarchy.tailscale") != null)
|
||||
(.bar.layout.center | ids) as $center |
|
||||
(.bar.layout.right | ids | index("omarchy.dropbox") == 1) and
|
||||
($center | index("omarchy.tailscale") == (($center | index("omarchy.weather")) + 1))
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "bar defaults adds widgets for running optional services"
|
||||
pass "bar defaults places plugins for running optional services"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" PATH="$mock_path" \
|
||||
OMARCHY_TEST_SHELL_DOWN=1 OMARCHY_TEST_DROPBOX=1 OMARCHY_TEST_TAILSCALE=1 \
|
||||
omarchy-bar defaults
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
(.bar.layout.center | ids) as $center |
|
||||
(.bar.layout.right | ids | index("omarchy.dropbox") == 1) and
|
||||
($center | index("omarchy.tailscale") == (($center | index("omarchy.weather")) + 1))
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "bar defaults places service widgets without a running shell"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" PATH="$mock_path" OMARCHY_TEST_DROPBOX=0 OMARCHY_TEST_TAILSCALE=0 omarchy-refresh-shell
|
||||
jq -e '
|
||||
@@ -446,11 +399,12 @@ pass "shell refresh keeps optional service widgets absent when services are unav
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" PATH="$mock_path" OMARCHY_TEST_DROPBOX=1 OMARCHY_TEST_TAILSCALE=1 omarchy-refresh-shell
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
(.bar.layout.right | ids | index("omarchy.dropbox") != null) and
|
||||
(.bar.layout.center | ids | index("omarchy.tailscale") != null)
|
||||
(.bar.layout.center | ids) as $center |
|
||||
(.bar.layout.right | ids | index("omarchy.dropbox") == 1) and
|
||||
($center | index("omarchy.tailscale") == (($center | index("omarchy.weather")) + 1))
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
[[ -f $TMPDIR/home/.local/state/omarchy/restart-shell-called ]] || fail "shell refresh restarts shell"
|
||||
pass "shell refresh adds optional service widgets when services are available"
|
||||
pass "shell refresh places optional service widgets when services are available"
|
||||
|
||||
if grep -RIl 'upgrade-to-quattro\|Omarchy 4\.0 is upgraded' "$ROOT/migrations" >/dev/null; then
|
||||
fail "4.0 upgrade is not modeled as a migration"
|
||||
|
||||
@@ -85,9 +85,20 @@ ShellRoot {
|
||||
scan += block("firstparty", "/first/hybrid", manifest("omarchy.hybrid", ["menu", "bar-widget"], { menu: "Menu.qml", barWidget: "Widget.qml" }))
|
||||
scan += block("thirdparty", "/third/panel", manifest("third.panel", ["panel"], { panel: "Panel.qml" }))
|
||||
scan += block("thirdparty", "/third/widget", manifest("third.widget", ["bar-widget"], { barWidget: "Widget.qml" }, { defaultSection: "left" }))
|
||||
scan += block("thirdparty", "/third/center-widget", manifest("third.center-widget", ["bar-widget"], { barWidget: "Widget.qml" }))
|
||||
scan += block("thirdparty", "/third/right-widget", manifest("third.right-widget", ["bar-widget"], { barWidget: "Widget.qml" }, { defaultSection: "right" }))
|
||||
var localWidget = manifest("local.first-widget", ["bar-widget"], { barWidget: "Widget.qml" })
|
||||
localWidget.omarchy = { clonedFrom: "omarchy.first-widget" }
|
||||
scan += block("thirdparty", "/third/local-widget", localWidget)
|
||||
var localHybrid = manifest("local.hybrid", ["menu", "bar-widget"], { menu: "Menu.qml", barWidget: "Widget.qml" })
|
||||
localHybrid.omarchy = { clonedFrom: "omarchy.hybrid" }
|
||||
scan += block("thirdparty", "/third/local-hybrid", localHybrid)
|
||||
var localPanel = manifest("local.grouped-panel", ["panel"], { panel: "Panel.qml" })
|
||||
localPanel.omarchy = { clonedFrom: "omarchy.grouped-panel" }
|
||||
scan += block("thirdparty", "/third/local-panel", localPanel)
|
||||
var localBar = manifest("local.bar", ["bar"], { bar: "Bar.qml" })
|
||||
localBar.omarchy = { clonedFrom: "omarchy.bar" }
|
||||
scan += block("thirdparty", "/third/local-bar", localBar)
|
||||
scan += block("thirdparty", "/third/bar", manifest("third.bar", ["bar"], { bar: "Bar.qml" }))
|
||||
scan += block("thirdparty", "/third/shadow", manifest("omarchy.first-widget", ["panel"], { panel: "Panel.qml" }))
|
||||
scan += block("thirdparty", "/third/reserved", manifest("omarchy.reserved", ["panel"], { panel: "Panel.qml" }))
|
||||
@@ -100,13 +111,18 @@ ShellRoot {
|
||||
registry.parseScanOutput(scan)
|
||||
|
||||
root.assertDeepEqual(pluginIds(), [
|
||||
"local.bar",
|
||||
"local.first-widget",
|
||||
"local.grouped-panel",
|
||||
"local.hybrid",
|
||||
"omarchy.bar",
|
||||
"omarchy.first-widget",
|
||||
"omarchy.grouped-panel",
|
||||
"omarchy.hybrid",
|
||||
"third.bar",
|
||||
"third.center-widget",
|
||||
"third.panel",
|
||||
"third.right-widget",
|
||||
"third.widget"
|
||||
], "registry merges valid first-party and third-party manifests")
|
||||
|
||||
@@ -148,9 +164,126 @@ ShellRoot {
|
||||
registry.setEnabled("third.widget", false)
|
||||
root.assertDeepEqual(root.config.bar.layout.left, [], "disabling bar widgets removes layout entry")
|
||||
|
||||
root.config = {
|
||||
version: 1,
|
||||
bar: {
|
||||
layout: {
|
||||
left: [{ id: "omarchy.workspaces" }, { id: "omarchy.menu" }],
|
||||
center: [{ id: "omarchy.weather" }, { id: "omarchy.clock" }],
|
||||
right: [{ id: "omarchy.tray" }]
|
||||
}
|
||||
},
|
||||
plugins: []
|
||||
}
|
||||
registry.setEnabled("third.widget", true)
|
||||
root.assertDeepEqual(
|
||||
root.config.bar.layout.left,
|
||||
[{ id: "omarchy.workspaces" }, { id: "third.widget" }, { id: "omarchy.menu" }],
|
||||
"enabling a widget inserts it after its section anchor"
|
||||
)
|
||||
registry.setEnabled("third.center-widget", true)
|
||||
root.assertDeepEqual(
|
||||
root.config.bar.layout.center,
|
||||
[{ id: "omarchy.weather" }, { id: "third.center-widget" }, { id: "omarchy.clock" }],
|
||||
"widgets without a default section use the center anchor"
|
||||
)
|
||||
registry.setEnabled("third.right-widget", true)
|
||||
root.assertDeepEqual(
|
||||
root.config.bar.layout.right,
|
||||
[{ id: "omarchy.tray" }, { id: "third.right-widget" }],
|
||||
"right widgets use the right anchor"
|
||||
)
|
||||
|
||||
root.config = { version: 1, bar: { layout: { left: [], center: [], right: [] } }, plugins: [] }
|
||||
registry.setEnabled("third.right-widget", true)
|
||||
root.assertDeepEqual(root.config.bar.layout.right, [{ id: "third.right-widget" }], "widgets append when their section anchor is absent")
|
||||
|
||||
root.config = {
|
||||
version: 1,
|
||||
bar: { layout: { left: [{ id: "third.widget", size: 3 }], center: [], right: [] } },
|
||||
plugins: []
|
||||
}
|
||||
root.assertEqual(registry.moveBarWidget("third.widget", { section: "right" }), "", "registry moves widgets")
|
||||
root.assertDeepEqual(root.config.bar.layout.right, [{ id: "third.widget", size: 3 }], "registry move preserves widget settings")
|
||||
root.assertEqual(registry.setBarWidget("third.widget", "size", 7, {}), "", "registry sets widget options")
|
||||
root.assertEqual(root.config.bar.layout.right[0].size, 7, "registry persists widget options")
|
||||
|
||||
root.config = { version: 1, bar: { layout: { left: [], center: [], right: [] } }, plugins: [] }
|
||||
registry.setEnabled("third.widget", true, { section: "right", index: 0 })
|
||||
root.assertDeepEqual(root.config.bar.layout.right, [{ id: "third.widget" }], "enabling with placement is one registry transition")
|
||||
|
||||
root.config = {
|
||||
version: 1,
|
||||
bar: { layout: { left: [], center: [{ id: "omarchy.first-widget", size: 4 }], right: [] } },
|
||||
plugins: []
|
||||
}
|
||||
registry.setEnabled("local.first-widget", true)
|
||||
root.assertDeepEqual(
|
||||
root.config.bar.layout.center,
|
||||
[{ id: "local.first-widget", size: 4 }],
|
||||
"enabling a widget clone replaces its source in place"
|
||||
)
|
||||
root.assertEqual(registry.resolveEnabledId("omarchy.first-widget"), "local.first-widget", "enabled clones receive calls made to their source id")
|
||||
registry.setEnabled("omarchy.first-widget", true)
|
||||
root.assertDeepEqual(
|
||||
root.config.bar.layout.center,
|
||||
[{ id: "omarchy.first-widget", size: 4 }],
|
||||
"enabling a clone source switches back without duplicates"
|
||||
)
|
||||
registry.setEnabled("local.first-widget", true)
|
||||
registry.setEnabled("local.first-widget", false)
|
||||
root.assertDeepEqual(
|
||||
root.config.bar.layout.center,
|
||||
[{ id: "omarchy.first-widget", size: 4 }],
|
||||
"disabling a widget clone restores its source in place"
|
||||
)
|
||||
|
||||
root.config = {
|
||||
version: 1,
|
||||
bar: { layout: { left: [], center: ["omarchy.first-widget"], right: [] } },
|
||||
plugins: []
|
||||
}
|
||||
registry.setEnabled("local.first-widget", true)
|
||||
root.assertDeepEqual(root.config.bar.layout.center, [{ id: "local.first-widget" }], "clone replacement normalizes string entries")
|
||||
registry.setEnabled("local.first-widget", false)
|
||||
root.assertDeepEqual(root.config.bar.layout.center, [{ id: "omarchy.first-widget" }], "clone restoration normalizes string entries")
|
||||
|
||||
root.config = {
|
||||
version: 1,
|
||||
bar: { layout: { left: [{ id: "omarchy.hybrid" }], center: [], right: [] } },
|
||||
plugins: []
|
||||
}
|
||||
registry.setEnabled("local.hybrid", true)
|
||||
root.assertDeepEqual(root.config.bar.layout.left, [{ id: "local.hybrid" }], "enabling a multi-kind clone replaces its widget")
|
||||
root.assertDeepEqual(root.config.disabledPlugins, ["omarchy.hybrid"], "enabling a multi-kind clone disables the source")
|
||||
registry.setEnabled("local.hybrid", false)
|
||||
root.assertDeepEqual(root.config.bar.layout.left, [{ id: "omarchy.hybrid" }], "disabling a multi-kind clone restores its widget")
|
||||
root.assertTrue(root.config.disabledPlugins === undefined, "disabling a multi-kind clone enables the source")
|
||||
|
||||
root.config = { version: 1, bar: { layout: { left: [], center: [], right: [] } }, plugins: [] }
|
||||
registry.setEnabled("local.grouped-panel", true)
|
||||
root.assertDeepEqual(root.config.plugins, [{ id: "local.grouped-panel" }], "enabling an ordinary clone adds it")
|
||||
root.assertDeepEqual(root.config.disabledPlugins, ["omarchy.grouped-panel"], "enabling an ordinary clone disables the source")
|
||||
registry.setEnabled("local.grouped-panel", false)
|
||||
root.assertDeepEqual(root.config.plugins, [], "disabling an ordinary clone removes it")
|
||||
root.assertTrue(root.config.disabledPlugins === undefined, "disabling an ordinary clone restores the source")
|
||||
|
||||
root.config = {
|
||||
version: 1,
|
||||
bar: { layout: { left: [], center: [], right: [] } },
|
||||
plugins: [],
|
||||
disabledPlugins: ["omarchy.grouped-panel"]
|
||||
}
|
||||
registry.setEnabled("local.grouped-panel", true)
|
||||
root.assertDeepEqual(root.config.disabledPlugins, ["omarchy.grouped-panel"], "cloning an already-disabled source keeps it disabled")
|
||||
root.assertTrue(root.config.cloneSourceRestores === undefined, "an already-disabled source is not marked for restoration")
|
||||
registry.setEnabled("local.grouped-panel", false)
|
||||
root.assertDeepEqual(root.config.disabledPlugins, ["omarchy.grouped-panel"], "disabling the clone preserves the source's prior disabled state")
|
||||
|
||||
registry.setEnabled("local.bar", true)
|
||||
root.assertEqual(root.config.bar.id, "local.bar", "enabling a cloned bar selects it")
|
||||
registry.setEnabled("local.bar", false)
|
||||
root.assertTrue(root.config.bar.id === undefined, "disabling a cloned built-in bar restores it")
|
||||
|
||||
root.config = {
|
||||
version: 1,
|
||||
@@ -201,8 +334,8 @@ ShellRoot {
|
||||
}
|
||||
registry.setEnabled("omarchy.hybrid", false)
|
||||
root.assertDeepEqual(root.config.bar.layout.left, [], "disabling a multi-kind built-in removes its widget")
|
||||
root.assertDeepEqual(root.config.disabledPlugins, ["omarchy.hybrid"], "disabling a multi-kind built-in unloads its other kinds")
|
||||
root.assertTrue(!registry.isEnabled("omarchy.hybrid"), "a disabled multi-kind built-in is not loadable")
|
||||
root.assertTrue(root.config.disabledPlugins === undefined, "disabling a multi-kind widget records nothing else")
|
||||
root.assertTrue(registry.isEnabled("omarchy.hybrid"), "a multi-kind built-in remains loadable without its widget")
|
||||
|
||||
var localBase = registry.pluginsDir + "/local.clock"
|
||||
root.assertEqual(registry.localPluginIdForPath(localBase + "/BarWidget.qml"), "local.clock", "local clone changes are watched")
|
||||
|
||||
@@ -221,7 +221,7 @@ const pluginAdd = fs.readFileSync(path.join(root, 'bin/omarchy-plugin-add'), 'ut
|
||||
const pluginEnable = fs.readFileSync(path.join(root, 'bin/omarchy-plugin-enable'), 'utf8')
|
||||
assert(
|
||||
/Now using \$id as the bar/.test(pluginEnable)
|
||||
&& /Now using \$id as the bar[\s\S]*?place_bar_widget/.test(pluginAdd),
|
||||
&& /omarchy-plugin-enable "\$id" "\$\{ENABLE_PLACEMENT\[@\]\}"/.test(pluginAdd),
|
||||
'plugin enable reports a bar as replacing the one in use, whether enabled or freshly added'
|
||||
)
|
||||
assert(
|
||||
|
||||
@@ -24,19 +24,14 @@ elif [[ $* == *"listPlugins"* ]]; then
|
||||
find "$HOME/.config/omarchy/plugins" -mindepth 2 -maxdepth 2 -name manifest.json -print0 |
|
||||
xargs -0 -r jq -s 'map({id: .id, enabled: true})'
|
||||
fi
|
||||
elif [[ $* == *"setPluginEnabled"* ]]; then
|
||||
printf 'omarchy-shell %s\n' "$*" >>"$FAKE_CALLS"
|
||||
printf 'ok\n'
|
||||
fi
|
||||
exit 0
|
||||
SH
|
||||
|
||||
for command in omarchy-bar omarchy-bar-plugin; do
|
||||
cat >"$TMPDIR/bin/$command" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s %s\n' "${0##*/}" "$*" >>"$FAKE_CALLS"
|
||||
exec "$OMARCHY_TEST_ROOT/bin/${0##*/}" "$@"
|
||||
SH
|
||||
done
|
||||
|
||||
for command in omarchy-plugin-enable omarchy-plugin-disable omarchy-notification-send; do
|
||||
for command in omarchy-plugin-enable omarchy-notification-send; do
|
||||
cat >"$TMPDIR/bin/$command" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s %s\n' "${0##*/}" "$*" >>"$FAKE_CALLS"
|
||||
@@ -87,36 +82,16 @@ jq -e '
|
||||
' "$clock/manifest.json" >/dev/null || fail "clock clone manifest is incorrect"
|
||||
pass "clone updates identity without replacing the manifest"
|
||||
|
||||
grep -qx 'omarchy-bar-plugin replace omarchy.clock local.clock' "$CALLS" ||
|
||||
fail "clone does not replace an active bar widget"
|
||||
grep -qx 'omarchy-plugin-enable local.clock' "$CALLS" ||
|
||||
fail "clone does not enable the editable copy"
|
||||
grep -qx 'omarchy-notification-send -g Editing Cloned Plugin Original plugin has been replace by clone.' "$CALLS" ||
|
||||
fail "clone does not notify that the editable clone is active"
|
||||
jq -e '
|
||||
any(.bar.layout.center[];
|
||||
.id == "local.clock" and
|
||||
.format == "dddd HH:mm" and
|
||||
.formatAlt == "d MMMM \u0027W\u0027ww yyyy")
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null ||
|
||||
fail "clone does not preserve the active widget's placement and settings"
|
||||
pass "clone switches bar widgets in place and confirms the editable clone"
|
||||
pass "clone enables bar widgets and confirms the editable clone"
|
||||
|
||||
jq '.bar.layout.center += ["omarchy.keyboard-layout"]' \
|
||||
"$TMPDIR/home/.config/omarchy/shell.json" >"$TMPDIR/shell.json"
|
||||
mv "$TMPDIR/shell.json" "$TMPDIR/home/.config/omarchy/shell.json"
|
||||
FAKE_CLONE_CONFIG='{
|
||||
"bar": {
|
||||
"layout": {
|
||||
"left": [],
|
||||
"center": ["omarchy.keyboard-layout"],
|
||||
"right": []
|
||||
}
|
||||
}
|
||||
}' clone_plugin omarchy.keyboard-layout >/dev/null
|
||||
jq -e '
|
||||
any(.bar.layout.center[]; .id == "local.keyboard-layout")
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null ||
|
||||
fail "clone does not replace a string-form bar entry"
|
||||
pass "clone replaces legacy string-form bar entries"
|
||||
clone_plugin omarchy.keyboard-layout >/dev/null
|
||||
grep -qx 'omarchy-plugin-enable local.keyboard-layout' "$CALLS" ||
|
||||
fail "clone does not enable a clone of a legacy string-form bar entry"
|
||||
pass "clone enables clones of legacy string-form bar entries"
|
||||
|
||||
clone_plugin omarchy.menu >/dev/null
|
||||
menu="$TMPDIR/home/.config/omarchy/plugins/local.menu"
|
||||
@@ -130,29 +105,26 @@ jq -e '
|
||||
.entryPoints.menu == "Menu.qml" and
|
||||
.entryPoints.barWidget == "BarWidget.qml"
|
||||
' "$menu/manifest.json" >/dev/null || fail "menu clone loses plugin kinds"
|
||||
grep -qx 'omarchy-plugin-disable omarchy.menu' "$CALLS" ||
|
||||
fail "clone leaves the built-in half of a multi-kind plugin enabled"
|
||||
pass "clone preserves multi-kind plugins"
|
||||
grep -qx 'omarchy-plugin-enable local.menu' "$CALLS" ||
|
||||
fail "clone does not enable a multi-kind plugin"
|
||||
pass "clone preserves and enables multi-kind plugins"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" PATH="$TMPDIR/bin:$ROOT/bin:$PATH" \
|
||||
remove_output=$(HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" PATH="$TMPDIR/bin:$ROOT/bin:$PATH" \
|
||||
FAKE_CALLS="$CALLS" OMARCHY_TEST_ROOT="$ROOT" \
|
||||
omarchy-plugin-remove local.menu --yes >/dev/null
|
||||
grep -qx 'omarchy-bar-plugin replace local.menu omarchy.menu' "$CALLS" &&
|
||||
grep -qx 'omarchy-plugin-enable omarchy.menu' "$CALLS" ||
|
||||
fail "removing a clone does not restore its built-in source"
|
||||
pass "removing a clone restores its built-in source"
|
||||
omarchy-plugin-remove local.menu --yes)
|
||||
grep -qx 'omarchy-shell shell setPluginEnabled local.menu false' "$CALLS" ||
|
||||
fail "removing an enabled clone does not disable it first"
|
||||
grep -q 'Restored omarchy.menu.' <<<"$remove_output" ||
|
||||
fail "removing a clone does not report its restored source"
|
||||
pass "removing an enabled clone goes through plugin disable and reports its source"
|
||||
|
||||
clone_plugin omarchy.active-window >/dev/null
|
||||
[[ -f $TMPDIR/home/.config/omarchy/plugins/local.active-window/ActiveWindow.qml ]] ||
|
||||
fail "flat bar plugin clone is incomplete"
|
||||
pass "flat bar plugins clone from adjacent manifests"
|
||||
|
||||
grep -qx 'omarchy-bar-plugin add local.active-window' "$CALLS" ||
|
||||
grep -qx 'omarchy-plugin-enable local.active-window' "$CALLS" ||
|
||||
fail "clone does not activate a bar widget whose source is absent"
|
||||
jq -e '
|
||||
any(.bar.layout.left[]; .id == "local.active-window")
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null ||
|
||||
fail "clone does not add the absent widget using its default placement"
|
||||
pass "clone activates an absent bar widget"
|
||||
|
||||
clone_plugin omarchy.indicators >/dev/null
|
||||
@@ -170,17 +142,13 @@ clone_plugin omarchy.tray >/dev/null
|
||||
pass "flat bar plugins keep local script dependencies"
|
||||
|
||||
clone_plugin omarchy.bar >/dev/null
|
||||
grep -qx 'omarchy-bar use local.bar' "$CALLS" ||
|
||||
grep -qx 'omarchy-plugin-enable local.bar' "$CALLS" ||
|
||||
fail "clone does not select a cloned bar"
|
||||
jq -e '.bar.id == "local.bar"' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null ||
|
||||
fail "clone does not persist the cloned bar as active"
|
||||
pass "clone switches full bars"
|
||||
|
||||
clone_plugin omarchy.background >/dev/null
|
||||
grep -qx 'omarchy-plugin-enable local.background' "$CALLS" ||
|
||||
fail "clone does not enable an ordinary cloned plugin"
|
||||
grep -qx 'omarchy-plugin-disable omarchy.background' "$CALLS" ||
|
||||
fail "clone does not disable the ordinary source plugin"
|
||||
pass "clone switches ordinary plugins"
|
||||
|
||||
mkdir -p "$TMPDIR/home/.config/omarchy/plugins/acme.example"
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMPDIR"' EXIT
|
||||
mkdir -p "$TMPDIR/home" "$TMPDIR/bin"
|
||||
calls="$TMPDIR/calls"
|
||||
|
||||
cat >"$TMPDIR/bin/omarchy-shell" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s\n' "$*" >>"$OMARCHY_TEST_CALLS"
|
||||
printf 'ok\n'
|
||||
SH
|
||||
chmod +x "$TMPDIR/bin/omarchy-shell"
|
||||
|
||||
run_enable() {
|
||||
HOME="$TMPDIR/home" \
|
||||
OMARCHY_PATH="$ROOT" \
|
||||
OMARCHY_TEST_CALLS="$calls" \
|
||||
PATH="$TMPDIR/bin:$ROOT/bin:$PATH" \
|
||||
omarchy-plugin-enable "$@"
|
||||
}
|
||||
|
||||
run_enable omarchy.active-window --section right >/dev/null
|
||||
grep -Fqx 'shell enablePlugin omarchy.active-window {"section":"right"}' "$calls" ||
|
||||
fail "plugin enable did not combine activation and placement"
|
||||
pass "plugin enable combines activation and placement in one shell mutation"
|
||||
|
||||
run_enable omarchy.clock --before omarchy.weather >/dev/null
|
||||
grep -Fqx 'shell enablePlugin omarchy.clock {"before":"omarchy.weather"}' "$calls" ||
|
||||
fail "plugin enable did not preserve relative placement"
|
||||
pass "plugin enable forwards relative placement"
|
||||
|
||||
run_enable omarchy.dropbox >/dev/null
|
||||
grep -Fqx 'shell enablePlugin omarchy.dropbox {}' "$calls" ||
|
||||
fail "plugin enable did not use manifest-default placement"
|
||||
pass "plugin enable leaves default placement to the registry"
|
||||
|
||||
if run_enable omarchy.bar --section right >/dev/null 2>&1; then
|
||||
fail "plugin enable accepted placement for a full bar"
|
||||
fi
|
||||
pass "plugin enable rejects placement for full bars"
|
||||
@@ -296,7 +296,7 @@ if (( worst > screens - 1 )); then
|
||||
fi
|
||||
pass "each widget registers its IPC handler once per screen"
|
||||
|
||||
HOME="$test_home" OMARCHY_PATH="$test_root" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-bar-plugin" remove omarchy.audio
|
||||
HOME="$test_home" OMARCHY_PATH="$test_root" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-plugin-disable" omarchy.audio
|
||||
|
||||
for _ in {1..80}; do
|
||||
shell_config=$(shell_ipc shell listShellConfig 2>/dev/null || true)
|
||||
@@ -313,7 +313,7 @@ done
|
||||
|
||||
jq -e 'all(.bar.layout.right[]; (.id // .) != "omarchy.audio")' <<<"$shell_config" >/dev/null || {
|
||||
printf 'Shell config after reload:\n%s\n' "$shell_config" | jq . >&2
|
||||
fail_with_log "bar remove reloads shell config"
|
||||
fail_with_log "plugin disable reloads shell config"
|
||||
}
|
||||
|
||||
jq -e 'all(.[]; .id != "omarchy.audio")' <<<"$geometry" >/dev/null || {
|
||||
|
||||
Reference in New Issue
Block a user