2d25e69632
Isolated per-test $HOME sandboxing via tests/helpers/common.bash. Covers both plugins' wrapper scripts, their setup.sh, and git-manager's two PreToolUse hooks (53 tests). Verified the suite catches regressions by temporarily reintroducing the recently-fixed vault_search.sh -g/-- ordering bug and confirming it fails.
105 lines
3.1 KiB
Bash
105 lines
3.1 KiB
Bash
# Shared helpers for this repo's bats suites. Loaded with `load
|
|
# '../helpers/common'` at the top of each .bats file.
|
|
#
|
|
# The core trick used throughout: point $HOME at a fresh
|
|
# $BATS_TEST_TMPDIR/home before each test, so every script under test that
|
|
# reads/writes ~/.agent-skills/... or ~/.claude/settings.json is fully
|
|
# sandboxed and cleaned up automatically by bats after the test — no shared
|
|
# state between tests, and never touches the real machine's config.
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
|
|
# Call from a test file's setup() after exporting HOME.
|
|
sandbox_home() {
|
|
export HOME="$BATS_TEST_TMPDIR/home"
|
|
mkdir -p "$HOME"
|
|
}
|
|
|
|
# make_test_repo <dir> — git-init a throwaway repo with one commit so
|
|
# `git status`/`log`/etc have something real to operate on.
|
|
make_test_repo() {
|
|
local dir="$1"
|
|
mkdir -p "$dir"
|
|
git -C "$dir" init -q
|
|
git -C "$dir" -c user.email=test@test -c user.name=test \
|
|
commit -q --allow-empty -m "init"
|
|
}
|
|
|
|
# write_git_manager_config <config_file> <name>=<path> [<name>=<path> ...]
|
|
# Writes a git-manager config.json registering the given repos.
|
|
write_git_manager_config() {
|
|
local config_file="$1"; shift
|
|
mkdir -p "$(dirname "$config_file")"
|
|
python3 - "$config_file" "$@" << 'PYEOF'
|
|
import json, sys
|
|
config_file, pairs = sys.argv[1], sys.argv[2:]
|
|
repos = []
|
|
for p in pairs:
|
|
name, path = p.split("=", 1)
|
|
repos.append({"name": name, "path": path})
|
|
with open(config_file, "w") as f:
|
|
json.dump({"repos": repos}, f)
|
|
PYEOF
|
|
}
|
|
|
|
# make_test_vault <dir> — a small Obsidian-shaped vault: two notes with
|
|
# frontmatter tags that wikilink each other, plus .obsidian/.git noise and
|
|
# a non-markdown attachment, so exclusion behavior is exercisable.
|
|
make_test_vault() {
|
|
local dir="$1"
|
|
mkdir -p "$dir/Notes" "$dir/.obsidian" "$dir/.git"
|
|
|
|
cat > "$dir/Notes/dns-setup.md" << 'EOF'
|
|
---
|
|
tags: [networking, dns]
|
|
---
|
|
# DNS Setup
|
|
|
|
Configured pihole as the primary resolver. See [[homelab-overview]].
|
|
EOF
|
|
|
|
cat > "$dir/Notes/homelab-overview.md" << 'EOF'
|
|
---
|
|
tags: [homelab, overview]
|
|
---
|
|
# Homelab Overview
|
|
|
|
Links to [[dns-setup]] and other topics.
|
|
EOF
|
|
|
|
echo "obsidian-internal-marker" > "$dir/.obsidian/config"
|
|
echo "attachment-only-marker" > "$dir/Notes/attachment.pdf"
|
|
}
|
|
|
|
# write_vault_config <config_file> <mode> <name>=<path> [<name>=<path> ...]
|
|
write_vault_config() {
|
|
local config_file="$1"; local mode="$2"; shift 2
|
|
mkdir -p "$(dirname "$config_file")"
|
|
python3 - "$config_file" "$mode" "$@" << 'PYEOF'
|
|
import json, sys
|
|
config_file, mode, pairs = sys.argv[1], sys.argv[2], sys.argv[3:]
|
|
vaults = []
|
|
for p in pairs:
|
|
name, path = p.split("=", 1)
|
|
vaults.append({"name": name, "path": path})
|
|
with open(config_file, "w") as f:
|
|
json.dump({"vaults": vaults, "mode": mode}, f)
|
|
PYEOF
|
|
}
|
|
|
|
# json_get <file> <dotted.path> — small helper for assertions against JSON
|
|
# written by setup.sh, without needing jq as a test dependency.
|
|
json_get() {
|
|
local file="$1" path="$2"
|
|
python3 -c '
|
|
import json, sys
|
|
with open(sys.argv[1]) as f:
|
|
data = json.load(f)
|
|
for key in sys.argv[2].split("."):
|
|
if key == "":
|
|
continue
|
|
data = data[int(key)] if key.isdigit() else data[key]
|
|
print(json.dumps(data))
|
|
' "$file" "$path"
|
|
}
|