Get more formal about testing

This commit is contained in:
David Heinemeier Hansson
2026-05-25 13:08:56 +02:00
parent 162e6ce006
commit 81f4896879
5 changed files with 33 additions and 264 deletions
+12 -5
View File
@@ -46,16 +46,16 @@ Supported metadata keys:
- `# omarchy:hidden=true` - hide from default command listings
- `# omarchy:requires-sudo=true` - mark commands that require sudo
Only use `omarchy:examples` where there are args that need explaining.
Prefer explicit metadata for user-facing commands. Keep routes consistent with the filename unless there is a deliberate alias or compatibility route.
Example:
```bash
# omarchy:summary=Take a screenshot
# omarchy:group=capture
# omarchy:args=[smart|region|windows|fullscreen] [slurp|copy]
# omarchy:examples=omarchy screenshot | omarchy capture screenshot region
# omarchy:aliases=omarchy screenshot
```
# Runtime Environment
@@ -83,7 +83,7 @@ Raw `command -v`, `pacman`, and `pacman-key` are acceptable in bootstrap/preflig
Use these instead of raw shell commands:
- `omarchy-cmd-missing` / `omarchy-cmd-present` - check for commands
- `omarchy-pkg-missing` / `omarchy-pkg-present` - check for packages
- `omarchy-pkg-missing` / `omarchy-pkg-present` - check for packages (don't use these if you can just use `omarchy-pkg-add`/`omarchy-pkg-drop`)
- `omarchy-pkg-add` - install packages (handles both pacman and AUR)
- `omarchy-pkg-drop` - remove packages; use this instead of raw `pacman -R*`
- `omarchy-notification-send` - send desktop notifications; do not call `notify-send` directly
@@ -97,9 +97,16 @@ Exceptions are allowed for bootstrap, preflight, migration, and package-helper s
- `default/themed/*.tpl` - templates with `{{ variable }}` placeholders for theme colors
- `themes/*/colors.toml` - theme color definitions (accent, background, foreground, color0-15)
# Visual Changes
# Tests
When making visual changes, such as omarchy-shell styling or desktop appearance, always take and analyze a screenshot after applying the change to verify the result. Use `omarchy capture screenshot fullscreen save` for fullscreen screenshots.
Run focused automated tests for the area you changed. Current test entry points:
- `bash test/cli.sh` - CLI routing, command metadata, theme helpers, and safe dispatch coverage
- `bash test/shell.sh` - all Omarchy shell tests under `test/shell/`
New Omarchy shell tests should live in `test/shell/*-test.sh` so `test/shell.sh` picks them up automatically.
For visual changes, such as omarchy-shell styling, desktop appearance, screenshots, or screen recording flows, verify with the running UI in addition to automated tests. Take and analyze screenshots with `omarchy capture screenshot fullscreen save`. For animation, transitions, capture, or screen recording behavior, make a short recording with `omarchy screenrecord --fullscreen`, stop it with `omarchy screenrecord --stop-recording`, and review the output before finishing.
For interactive UI work, use `wtype` to simulate keyboard input when available. Example: start the UI in the background, wait briefly for focus, then run `wtype -k Right -k Return` to exercise keyboard selection and confirm the resulting command output or state change. Prefer this over manual-only verification when a UI returns a selected value or changes a symlink/config.
-258
View File
@@ -1,258 +0,0 @@
#!/bin/bash
set -euo pipefail
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
TMPDIR=""
export PATH="$ROOT/bin:$PATH"
pass() {
printf 'ok - %s\n' "$1"
}
fail() {
printf 'not ok - %s\n' "$1" >&2
exit 1
}
assert_file_contains() {
local description="$1"
local file="$2"
local expected="$3"
if ! grep -Fq "$expected" "$file"; then
printf 'Expected %s to contain: %s\n' "$file" "$expected" >&2
printf 'Actual file:\n' >&2
sed -n '1,120p' "$file" >&2
fail "$description"
fi
pass "$description"
}
cleanup() {
[[ -n $TMPDIR && -d $TMPDIR ]] && rm -rf "$TMPDIR"
}
trap cleanup EXIT
TMPDIR=$(mktemp -d)
HOME="$TMPDIR/home" "$ROOT/bin/omarchy-npm-install" @openai/codex codex
wrapper="$TMPDIR/home/.local/bin/codex"
runtime="$ROOT/bin/omarchy-npm-run"
[[ -x $wrapper ]] || fail "npm wrapper is generated"
pass "npm wrapper is generated"
assert_file_contains "npm wrapper defaults bin to command name" "$wrapper" 'exec omarchy-npm-run "@openai/codex" "codex" "codex" "$@"'
if grep -q "pnpm dlx" "$wrapper"; then
fail "npm wrapper does not inline pnpm runtime"
fi
pass "npm wrapper does not inline pnpm runtime"
HOME="$TMPDIR/home" "$ROOT/bin/omarchy-npm-install" playwright playwright-cli playwright
assert_file_contains "npm wrapper records explicit package bin" "$TMPDIR/home/.local/bin/playwright-cli" 'exec omarchy-npm-run "playwright" "playwright-cli" "playwright" "$@"'
assert_file_contains "npm runtime defines pin ttl" "$runtime" "pin_ttl=7200"
assert_file_contains "npm runtime configures pnpm minimum release age" "$runtime" 'npm_config_minimum_release_age=$pin_ttl'
assert_file_contains "npm runtime configures pnpm dlx cache max age" "$runtime" 'npm_config_dlx_cache_max_age=$pin_ttl'
if grep -q "PNPM_CONFIG_MINIMUM_RELEASE_AGE" "$runtime"; then
fail "npm runtime does not use ignored PNPM_CONFIG env vars"
fi
pass "npm runtime does not use ignored PNPM_CONFIG env vars"
removed_flag="--force""-update"
if grep -q -- "$removed_flag" "$runtime"; then
fail "npm runtime does not expose removed force update flag"
fi
pass "npm runtime does not expose removed force update flag"
if grep -q " which " "$runtime"; then
fail "npm runtime does not discover package bins dynamically"
fi
pass "npm runtime does not discover package bins dynamically"
stub_bin="$TMPDIR/bin"
node_root="$TMPDIR/node"
state_home="$TMPDIR/state"
pnpm_log="$TMPDIR/pnpm.log"
package_args="$TMPDIR/package-args"
version_file="$state_home/omarchy/npm-wrappers/codex.version"
mkdir -p "$stub_bin" "$node_root/bin"
cat >"$stub_bin/mise" <<'SH'
#!/bin/bash
if [[ $1 == "where" && $2 == "node@latest" ]]; then
printf '%s\n' "$OMARCHY_NPM_TEST_NODE_ROOT"
exit 0
fi
exit 1
SH
cat >"$stub_bin/omarchy-cmd-missing" <<'SH'
#!/bin/bash
exit 1
SH
cat >"$stub_bin/pnpm" <<'SH'
#!/bin/bash
printf 'min_age=%s dlx_cache=%s args=%s\n' "${npm_config_minimum_release_age:-}" "${npm_config_dlx_cache_max_age:-}" "$*" >>"$OMARCHY_NPM_TEST_PNPM_LOG"
if [[ $1 == "view" ]]; then
printf '1.2.3\n'
exit 0
fi
if [[ $1 == "dlx" ]]; then
if [[ $4 == "true" ]]; then
exit 0
fi
shift 4
printf '%s\n' "$*" >"$OMARCHY_NPM_TEST_PACKAGE_ARGS"
exit 0
fi
exit 1
SH
chmod +x "$stub_bin/mise" "$stub_bin/omarchy-cmd-missing" "$stub_bin/pnpm"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" -s danger-full-access update alpha beta
if ! grep -Fq "args=dlx --package @openai/codex codex -s danger-full-access update alpha beta" "$pnpm_log"; then
fail "non-leading update is forwarded to package bin"
fi
pass "non-leading update is forwarded to package bin"
if ! grep -q "dlx_cache=7200" "$pnpm_log"; then
fail "normal run uses pnpm dlx cache age"
fi
pass "normal run uses pnpm dlx cache age"
if ! grep -q "min_age=7200" "$pnpm_log"; then
fail "normal run uses pnpm minimum release age"
fi
pass "normal run uses pnpm minimum release age"
if [[ $(<"$package_args") != "-s danger-full-access update alpha beta" ]]; then
fail "normal run forwards package args"
fi
pass "normal run forwards package args"
if [[ -f $version_file ]]; then
fail "non-leading update does not pin wrapper version"
fi
pass "non-leading update does not pin wrapper version"
rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" update alpha
if ! grep -Fq "args=dlx --package @openai/codex codex update alpha" "$pnpm_log"; then
fail "update with extra args is forwarded to package bin"
fi
pass "update with extra args is forwarded to package bin"
if [[ -f $version_file ]]; then
fail "update with extra args does not pin wrapper version"
fi
pass "update with extra args does not pin wrapper version"
rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" update
if ! grep -q "dlx_cache=0" "$pnpm_log"; then
fail "wrapper update refreshes pnpm dlx cache"
fi
pass "wrapper update refreshes pnpm dlx cache"
if ! grep -q "min_age=0" "$pnpm_log"; then
fail "wrapper update bypasses pnpm minimum release age"
fi
pass "wrapper update bypasses pnpm minimum release age"
if ! grep -Fq "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then
fail "wrapper update uses resolved latest package version"
fi
pass "wrapper update uses resolved latest package version"
if [[ -f $package_args ]]; then
fail "wrapper update does not run package bin"
fi
pass "wrapper update does not run package bin"
if [[ $(<"$version_file") != "1.2.3" ]]; then
fail "wrapper update persists resolved version"
fi
pass "wrapper update persists resolved version"
rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" gamma
if ! grep -Fq "args=dlx --package @openai/codex@1.2.3 codex gamma" "$pnpm_log"; then
fail "wrapper reuses pinned update version"
fi
pass "wrapper reuses pinned update version"
if ! grep -q "min_age=0" "$pnpm_log"; then
fail "wrapper bypasses minimum release age for pinned version"
fi
pass "wrapper bypasses minimum release age for pinned version"
if [[ $(<"$package_args") != "gamma" ]]; then
fail "wrapper forwards args after pinned update"
fi
pass "wrapper forwards args after pinned update"
rm -f "$pnpm_log" "$package_args"
touch -d "@$(($(date +%s) - 7201))" "$version_file"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" delta
if ! grep -Fq "args=dlx --package @openai/codex codex delta" "$pnpm_log"; then
fail "wrapper drops expired pinned update version"
fi
pass "wrapper drops expired pinned update version"
if ! grep -q "min_age=7200" "$pnpm_log"; then
fail "wrapper restores minimum release age after pin expiry"
fi
pass "wrapper restores minimum release age after pin expiry"
if [[ -f $version_file ]]; then
fail "wrapper removes expired pinned version file"
fi
pass "wrapper removes expired pinned version file"
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
set -euo pipefail
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
TEST_DIR="$ROOT/test/shell"
shopt -s nullglob
tests=("$TEST_DIR"/*-test.sh)
shopt -u nullglob
if (( ${#tests[@]} == 0 )); then
echo "No shell tests found in $TEST_DIR" >&2
exit 1
fi
for test in "${tests[@]}"; do
printf '==> %s\n' "${test#$ROOT/}"
bash "$test"
done
@@ -2,7 +2,7 @@
set -euo pipefail
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)
export ROOT
node <<'JS'