- tests/helpers/common.bash: hide_command hides python3/jq/rg via a per-directory-batched PATH shim (not per-file — that took minutes), making the fail-open/grep-fallback branches testable. - 20 new tests across all 7 .bats files: unknown flags, invalid --settings-scope, missing python3/jq, grep fallback when rg is unavailable, empty/multi-vault config edge cases, a vault path that stops existing or isn't a directory, and the previously-untested tool_name != Bash branch of force-ask-on-raw-git.sh. 53 -> 73 tests. - hooks.bats: deploy the hooks once in setup_file() (BATS_FILE_TMPDIR) instead of per-test (BATS_TEST_TMPDIR) -- faster, and gives kcov one stable path per hook to aggregate coverage against instead of a fragmented copy per test. - .gitignore (first in this repo) + tests/README.md Coverage section documenting the kcov invocation and why --include-pattern needs three entries, not two. Real, tool-measured coverage via kcov: 86.15% (255/296 lines) across all 10 wrapper/setup/hook scripts in both plugins, replacing an earlier manual ~68% branch-coverage estimate.
2.4 KiB
Tests
A bats-core 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
sudo apt install bats
Run
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/<name>/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_TMPDIRafter each test automatically. - Tests that exercise a
setup.shrun 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
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.<hash>/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.