# Tests A [bats-core](https://bats-core.readthedocs.io/) suite covering both plugins' wrapper scripts, their `setup.sh`, and git-manager's two `PreToolUse` hooks. Plain bats assertions only (`run` + `[ ]`/`[[ ]]`) — no extra helper libraries. ## Install ```bash sudo apt install bats ``` ## Run ```bash bats -r tests/ # everything (-r: recurse into subdirs) bats -r tests/git-manager/ # one plugin bats tests/obsidian-vault-kb/vault_search.bats # one file ``` ## How it's isolated Every test points `$HOME` at a fresh, bats-managed `$BATS_TEST_TMPDIR/home` (see `tests/helpers/common.bash`, `sandbox_home`) before running any script under test. Since every script here resolves its config from `~/.agent-skills//config.json` and setup.sh writes to `~/.claude/settings.json`, this means: - Tests never read or write your real `~/.agent-skills/` or `~/.claude/settings.json`. - Nothing needs manual cleanup — bats deletes `$BATS_TEST_TMPDIR` after each test automatically. - Tests that exercise a `setup.sh` run the real script end to end (it's what deploys the stable script copies + writes permissions/config), not a mocked version. There's no CI wiring for this suite yet — run it manually before/after touching anything under `skills/` or `vendor/claude-code/plugins/`. ## Coverage ```bash sudo apt install kcov # or a user-local install, as done for bats kcov --include-pattern=/repo/skills/,/repo/vendor/claude-code/plugins/,force-ask-on-chaining.sh,force-ask-on-raw-git.sh \ tests/coverage bats -r tests/ ``` Opens as `tests/coverage/bats./index.html` (not committed — see `.gitignore`). `kcov` follows every bash subprocess `bats` forks, so this covers the actual wrapper/setup/hook scripts, not just `bats` itself. The `--include-pattern` needs three things, not just the two source directories: `git_cmd.sh`/`vault_*.sh`/`setup.sh` run straight from this checkout, so `/repo/skills/` and `/repo/vendor/claude-code/plugins/` catch them (the leading `/repo/` matters — a plain `skills/` would also match this repo's own outer directory name and pull in unrelated files). The two `PreToolUse` hooks are different: `tests/git-manager/hooks.bats` exercises the *deployed* copies under `~/.agent-skills/git-manager/bin/` (matching how Claude Code actually invokes them), which live outside both of those directories — hence matching them by filename instead.