Files
small-scripts/tests/test-git-identity.sh
Paul O'Reilly f21506af19 Add git-identity: switch git author identity from a saved menu
Identities live in ~/.git-identities (alias|Name|email). Interactive
menu to select, add, or remove identities; direct mode via alias
argument; --global/-g scope flag (defaults to local inside a repo,
global fallback outside); --list/--current helpers. Full --dryrun
support and a 27-assertion test suite driven through dryrun.
GIT_IDENTITIES_FILE env override for testability.
2026-08-18 20:20:45 +12:00

121 lines
4.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
GIT_IDENTITY="$SCRIPT_DIR/scripts/git-identity"
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
pass=0
fail=0
assert_match() {
local desc="$1" pattern="$2" actual="$3"
if [[ "$actual" =~ $pattern ]]; then
echo -e "${GREEN}PASS${NC}: $desc"
((pass++))
else
echo -e "${RED}FAIL${NC}: $desc"
echo " pattern: $pattern"
echo " actual: $actual"
((fail++))
fi
}
assert_exit() {
local desc="$1" expected="$2" actual="$3"
if [[ "$expected" == "$actual" ]]; then
echo -e "${GREEN}PASS${NC}: $desc"
((pass++))
else
echo -e "${RED}FAIL${NC}: $desc (expected exit $expected, got $actual)"
((fail++))
fi
}
# Fixture: temp identities file and a temp git repo
TMPDIR_T=$(mktemp -d)
trap 'rm -rf "$TMPDIR_T"' EXIT
IDFILE="$TMPDIR_T/identities"
cat > "$IDFILE" <<'EOF'
# alias|Name|email
personal|Test Person|test@example.net
work|Test Person|test.person@corp.example
EOF
REPO="$TMPDIR_T/repo"
mkdir -p "$REPO" && git -C "$REPO" init -q
run() { GIT_IDENTITIES_FILE="$IDFILE" "$GIT_IDENTITY" "$@"; }
# --help
out=$(run --help); rc=$?
assert_exit "--help exits 0" 0 "$rc"
assert_match "--help shows usage" "Usage: git-identity" "$out"
# --list
out=$(run --list); rc=$?
assert_exit "--list exits 0" 0 "$rc"
assert_match "--list shows personal" "personal.*test@example\.net" "$out"
assert_match "--list shows work" "work.*test\.person@corp\.example" "$out"
# direct apply, dryrun, inside repo -> local scope
out=$(cd "$REPO" && run -n work); rc=$?
assert_exit "dryrun apply exits 0" 0 "$rc"
assert_match "dryrun apply previews local set" \
"\[dryrun\] Would set user.name 'Test Person' and user.email 'test.person@corp.example' \(--local in " "$out"
# dryrun apply did not change config
name=$(git -C "$REPO" config --local user.name 2>/dev/null || echo "UNSET")
assert_match "dryrun did not write config" "UNSET" "$name"
# direct apply, dryrun, outside repo -> global fallback note
out=$(cd "$TMPDIR_T" && run -n personal); rc=$?
assert_exit "dryrun global fallback exits 0" 0 "$rc"
assert_match "notes global fallback" "not inside a git repository" "$out"
assert_match "previews global set" "\(--global\)" "$out"
# --global flag, dryrun
out=$(cd "$REPO" && run -n -g personal); rc=$?
assert_match "dryrun --global previews global scope" "\(--global\)" "$out"
# unknown alias
out=$(cd "$REPO" && run -n nosuch 2>&1); rc=$?
assert_exit "unknown alias exits 1" 1 "$rc"
assert_match "unknown alias error names file" "No identity 'nosuch'" "$out"
assert_match "unknown alias lists available" "Available: personal work" "$out"
# missing file, direct mode
out=$(GIT_IDENTITIES_FILE="$TMPDIR_T/absent" "$GIT_IDENTITY" -n work 2>&1); rc=$?
assert_exit "missing file exits 1" 1 "$rc"
assert_match "missing file error" "No identities file" "$out"
# interactive menu: select identity 2 via stdin, dryrun
out=$(cd "$REPO" && printf '2\n' | run -n); rc=$?
assert_exit "interactive select exits 0" 0 "$rc"
assert_match "interactive shows menu" "1\) personal" "$out"
assert_match "interactive select previews apply" "\[dryrun\] Would set user.name 'Test Person' and user.email 'test.person@corp.example'" "$out"
# interactive: something else -> add, dryrun
out=$(cd "$REPO" && printf 's\na\nnewalias\nNew Name\nnew@example.net\nn\n' | run -n); rc=$?
assert_exit "interactive add exits 0" 0 "$rc"
assert_match "add previews append" "\[dryrun\] Would append 'newalias\|New Name\|new@example.net'" "$out"
grep -q "newalias" "$IDFILE" && added=yes || added=no
assert_match "dryrun add did not write file" "no" "$added"
# interactive: something else -> remove, dryrun
out=$(cd "$REPO" && printf 's\nr\n1\n' | run -n); rc=$?
assert_exit "interactive remove exits 0" 0 "$rc"
assert_match "remove previews deletion" "\[dryrun\] Would remove identity 'personal'" "$out"
grep -q "^personal|" "$IDFILE" && still=yes || still=no
assert_match "dryrun remove did not write file" "yes" "$still"
# duplicate alias rejected during add (then cancel with empty alias)
out=$(cd "$REPO" && printf 's\na\nwork\n\n' | run -n); rc=$?
assert_match "duplicate alias rejected" "Alias 'work' already exists" "$out"
echo ""
echo "Results: $pass passed, $fail failed"
[[ $fail -eq 0 ]]