06bd74d64f
- vault_index.sh: grep fallback for frontmatter tag extraction when rg is unavailable (had this for vault_search.sh/vault_backlinks.sh, not vault_index.sh). - git_cmd.bats: registered repo path that's a file, not a directory (had the obsidian equivalent, not git-manager's). - git_cmd.bats: missing python3 in resolve_repo_path (previously only tested via setup.sh/vault_index.sh, not git_cmd.sh's own _lib.sh). 76 tests now (was 73). kcov: 87.84% (260/296 lines), up from 86.15% -- both target files (vault_index.sh, git-manager _lib.sh) now at 100%. Remaining gap is entirely kcov's inability to trace multi-line python3/awk/jq blocks and bash 'case pattern) ;;' no-op branches, confirmed by checking hit counts on the surrounding lines -- not further closeable by adding tests.
149 lines
4.5 KiB
Bash
149 lines
4.5 KiB
Bash
#!/usr/bin/env bats
|
|
# Tests for skills/git-manager/scripts/git_cmd.sh + _lib.sh.
|
|
|
|
load '../helpers/common'
|
|
|
|
setup() {
|
|
sandbox_home
|
|
SCRIPT="$REPO_ROOT/skills/git-manager/scripts/git_cmd.sh"
|
|
CONFIG_FILE="$HOME/.agent-skills/git-manager/config.json"
|
|
REPO="$BATS_TEST_TMPDIR/repo"
|
|
make_test_repo "$REPO"
|
|
}
|
|
|
|
# --- subcommand allowlist ---
|
|
|
|
@test "allowed subcommand (status) runs and returns real git output" {
|
|
write_git_manager_config "$CONFIG_FILE" "myrepo=$REPO"
|
|
run "$SCRIPT" status --repo myrepo
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"nothing to commit"* ]]
|
|
}
|
|
|
|
@test "disallowed subcommand (stash) is rejected before git ever runs" {
|
|
write_git_manager_config "$CONFIG_FILE" "myrepo=$REPO"
|
|
run "$SCRIPT" stash --repo myrepo
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"is not allowed"* ]]
|
|
}
|
|
|
|
@test "no subcommand at all prints usage and exits 1" {
|
|
run "$SCRIPT"
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"Usage:"* ]]
|
|
}
|
|
|
|
# --- repo resolution ---
|
|
|
|
@test "no config file at all errors" {
|
|
run "$SCRIPT" status
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"no configuration found"* ]]
|
|
}
|
|
|
|
@test "zero repos registered errors" {
|
|
write_git_manager_config "$CONFIG_FILE"
|
|
run "$SCRIPT" status
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"no repos registered"* ]]
|
|
}
|
|
|
|
@test "exactly one repo registered auto-resolves without --repo" {
|
|
write_git_manager_config "$CONFIG_FILE" "myrepo=$REPO"
|
|
run "$SCRIPT" status
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"$REPO"* ]]
|
|
}
|
|
|
|
@test "multiple repos registered without --repo errors and lists names" {
|
|
REPO2="$BATS_TEST_TMPDIR/repo2"
|
|
make_test_repo "$REPO2"
|
|
write_git_manager_config "$CONFIG_FILE" "myrepo=$REPO" "other=$REPO2"
|
|
run "$SCRIPT" status
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"multiple repos configured"* ]]
|
|
[[ "$output" == *"myrepo"* ]]
|
|
[[ "$output" == *"other"* ]]
|
|
}
|
|
|
|
@test "--repo selects the named repo among several registered" {
|
|
REPO2="$BATS_TEST_TMPDIR/repo2"
|
|
make_test_repo "$REPO2"
|
|
write_git_manager_config "$CONFIG_FILE" "myrepo=$REPO" "other=$REPO2"
|
|
run "$SCRIPT" status --repo other
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"$REPO2"* ]]
|
|
}
|
|
|
|
@test "unknown --repo name errors and lists registered names" {
|
|
write_git_manager_config "$CONFIG_FILE" "myrepo=$REPO"
|
|
run "$SCRIPT" status --repo doesnotexist
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"no repo named 'doesnotexist'"* ]]
|
|
[[ "$output" == *"myrepo"* ]]
|
|
}
|
|
|
|
# --- canonicalize_and_check_repo ---
|
|
|
|
@test "registered path that no longer exists errors" {
|
|
write_git_manager_config "$CONFIG_FILE" "gone=$BATS_TEST_TMPDIR/does-not-exist"
|
|
run "$SCRIPT" status --repo gone
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"does not exist"* ]]
|
|
}
|
|
|
|
@test "registered path that isn't a git work tree errors" {
|
|
PLAIN_DIR="$BATS_TEST_TMPDIR/not-a-repo"
|
|
mkdir -p "$PLAIN_DIR"
|
|
write_git_manager_config "$CONFIG_FILE" "plain=$PLAIN_DIR"
|
|
run "$SCRIPT" status --repo plain
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"not inside a git work tree"* ]]
|
|
}
|
|
|
|
@test "a registered path nested inside the repo still resolves to the toplevel" {
|
|
mkdir -p "$REPO/subdir"
|
|
write_git_manager_config "$CONFIG_FILE" "nested=$REPO/subdir"
|
|
run "$SCRIPT" status --repo nested
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"== Repo: $REPO =="* ]]
|
|
}
|
|
|
|
@test "a registered path that is a file, not a directory, errors" {
|
|
FILE_PATH="$BATS_TEST_TMPDIR/not-a-dir"
|
|
echo "just a file" > "$FILE_PATH"
|
|
write_git_manager_config "$CONFIG_FILE" "plain=$FILE_PATH"
|
|
run "$SCRIPT" status --repo plain
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"is not a directory"* ]]
|
|
}
|
|
|
|
@test "missing python3 fails with a clear error instead of a silent crash" {
|
|
write_git_manager_config "$CONFIG_FILE" "myrepo=$REPO"
|
|
hide_command python3
|
|
run "$SCRIPT" status --repo myrepo
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"python3 is required"* ]]
|
|
}
|
|
|
|
# --- -- passthrough ---
|
|
|
|
@test "args after -- reach git unmodified" {
|
|
git -C "$REPO" -c user.email=test@test -c user.name=test \
|
|
commit -q --allow-empty -m "second"
|
|
git -C "$REPO" -c user.email=test@test -c user.name=test \
|
|
commit -q --allow-empty -m "third"
|
|
write_git_manager_config "$CONFIG_FILE" "myrepo=$REPO"
|
|
run "$SCRIPT" log --repo myrepo -- --oneline -n2
|
|
[ "$status" -eq 0 ]
|
|
# 2 commit lines + the script's own "== Repo ==" / "== Running ==" banner lines
|
|
commit_lines=$(printf '%s\n' "$output" | grep -c '^[0-9a-f]\{7,\} ')
|
|
[ "$commit_lines" -eq 2 ]
|
|
}
|
|
|
|
@test "an argument outside --repo/-- is rejected" {
|
|
run "$SCRIPT" status extra
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"unexpected argument 'extra'"* ]]
|
|
}
|