#!/usr/bin/env bash set -u SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" source "$SCRIPT_DIR/lib/common.sh" FAILURES=0 assert_eq() { if [ "$1" = "$2" ]; then echo "PASS: $3"; else echo "FAIL: $3 (expected '$1', got '$2')"; FAILURES=$((FAILURES + 1)); fi } # Setup: temp dir with fake `claude` CLI # CORRECTION B: real subcommand structure is `claude plugin marketplace add` and # `claude plugin install` (NOT `claude marketplace add`). Mock matches real shape. tmpdir=$(mktemp -d) mkdir "$tmpdir/bin" cat > "$tmpdir/bin/claude" <<'CLAUDE_EOF' #!/usr/bin/env bash # Mock claude CLI: records calls to /tmp/claude-calls.log, then dispatches. # Real subcommand shapes used by install-plugins.sh: # claude plugin marketplace list -> stdout: existing marketplaces # claude plugin marketplace add -> exit 0 on success # claude plugin install -> exit 0 on success # claude plugin info --json -> stdout: JSON with gitCommitSha echo "claude $*" >> /tmp/claude-calls.log # Dispatch on first 3 args (plugin/marketplace family) if [ "$1" = "plugin" ] && [ "$2" = "marketplace" ]; then case "$3" in list) ;; # print nothing (empty marketplace list) add) exit 0 ;; # marketplace add success esac elif [ "$1" = "plugin" ] && [ "$2" = "install" ]; then exit 0 # plugin install success elif [ "$1" = "plugin" ] && [ "$2" = "info" ]; then # Expect: claude plugin info --json echo '{"gitCommitSha": "f2cbfbefebbfef77321e4c9abc9e949826bea9d7"}' fi exit 0 CLAUDE_EOF chmod +x "$tmpdir/bin/claude" # Create fixtures cat > "$tmpdir/marketplaces.json" < "$tmpdir/plugins-manifest.json" <