test(kyberforge): cover sync-marketplace-mirror.sh drift-guard
Its sibling sync-plugin-content.sh has thorough coverage (tests/test-sync-plugin-content.sh) but this drift guard -- wired into pre-commit as check-marketplace-mirror-sync, keeping .claude-plugin/marketplace.json and .github/plugin/marketplace.json in sync -- had none. A silent regression here would let the two marketplace manifests drift without any test catching it. Covers: missing-source no-op in both real-sync and --check modes, drift detection when the mirror is missing or stale, real sync producing a byte-identical mirror, --check clean immediately after sync, drift from an edited source cleared by re-sync, an already-in-sync mirror reporting no drift, usage-error rejection of unrecognized/extra arguments, and idempotency of repeated syncs.
This commit is contained in:
184
tests/test-sync-marketplace-mirror.sh
Executable file
184
tests/test-sync-marketplace-mirror.sh
Executable file
@@ -0,0 +1,184 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
SCRIPT="$REPO_ROOT/scripts/sync-marketplace-mirror.sh"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
|
||||
fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
|
||||
|
||||
# Minimal fixture: a bare directory with no .git of its own. Since
|
||||
# scripts/sync-marketplace-mirror.sh resolves REPO_ROOT via
|
||||
# `git rev-parse --show-toplevel 2>/dev/null || pwd`, and mktemp -d creates
|
||||
# directories outside any git worktree, cd'ing into the fixture before
|
||||
# invoking the script makes REPO_ROOT resolve to the fixture itself -- so
|
||||
# every test runs against an isolated .claude-plugin/ + .github/plugin/ pair
|
||||
# instead of this repo's real marketplace.json files.
|
||||
make_fixture() {
|
||||
mktemp -d
|
||||
}
|
||||
|
||||
SRC_REL=".claude-plugin/marketplace.json"
|
||||
DST_REL=".github/plugin/marketplace.json"
|
||||
CONTENT_A='{"plugins":[{"name":"demo","version":"1.0.0"}]}'
|
||||
CONTENT_B='{"plugins":[{"name":"demo","version":"2.0.0"}]}'
|
||||
|
||||
write_src() {
|
||||
local dir="$1" content="$2"
|
||||
mkdir -p "$dir/.claude-plugin"
|
||||
printf '%s' "$content" > "$dir/$SRC_REL"
|
||||
}
|
||||
|
||||
write_dst() {
|
||||
local dir="$1" content="$2"
|
||||
mkdir -p "$dir/.github/plugin"
|
||||
printf '%s' "$content" > "$dir/$DST_REL"
|
||||
}
|
||||
|
||||
run_script() {
|
||||
local dir="$1"
|
||||
shift
|
||||
(cd "$dir" && bash "$SCRIPT" "$@")
|
||||
}
|
||||
|
||||
CLEANUP_DIRS=()
|
||||
trap 'rm -rf "${CLEANUP_DIRS[@]}"' EXIT
|
||||
track() { CLEANUP_DIRS+=("$1"); }
|
||||
|
||||
# --- 1. No .claude-plugin/marketplace.json at all: real-sync mode is a no-op, exit 0 ---
|
||||
echo ""
|
||||
echo "--- missing source: real sync exits 0 and creates nothing ---"
|
||||
FIXTURE1="$(make_fixture)"; track "$FIXTURE1"
|
||||
if run_script "$FIXTURE1" > /dev/null 2>&1 && [[ ! -e "$FIXTURE1/$DST_REL" ]]; then
|
||||
pass "missing source exits 0 in real-sync mode without creating a mirror"
|
||||
else
|
||||
fail "missing source should exit 0 and create nothing in real-sync mode"
|
||||
fi
|
||||
|
||||
# --- 2. No source: --check mode is also a no-op, exit 0 (nothing to drift-check) ---
|
||||
echo ""
|
||||
echo "--- missing source: --check exits 0 (nothing to compare) ---"
|
||||
FIXTURE2="$(make_fixture)"; track "$FIXTURE2"
|
||||
if run_script "$FIXTURE2" --check > /dev/null 2>&1; then
|
||||
pass "missing source exits 0 in --check mode"
|
||||
else
|
||||
fail "missing source should exit 0 in --check mode, not report drift"
|
||||
fi
|
||||
|
||||
# --- 3. Source exists, mirror missing entirely: --check reports drift (exit 1) ---
|
||||
echo ""
|
||||
echo "--- --check reports drift when the mirror file does not exist yet ---"
|
||||
FIXTURE3="$(make_fixture)"; track "$FIXTURE3"
|
||||
write_src "$FIXTURE3" "$CONTENT_A"
|
||||
if run_script "$FIXTURE3" --check > /dev/null 2>&1; then
|
||||
fail "exited 0 with no mirror file present -- expected drift (exit 1)"
|
||||
else
|
||||
pass "missing mirror file is reported as drift"
|
||||
fi
|
||||
|
||||
# --- 4. Real sync creates the mirror (and its parent dir) byte-identical to the source ---
|
||||
echo ""
|
||||
echo "--- real sync creates .github/plugin/marketplace.json byte-identical to source ---"
|
||||
FIXTURE4="$(make_fixture)"; track "$FIXTURE4"
|
||||
write_src "$FIXTURE4" "$CONTENT_A"
|
||||
if run_script "$FIXTURE4" > /dev/null 2>&1 \
|
||||
&& [[ -f "$FIXTURE4/$DST_REL" ]] \
|
||||
&& diff -q "$FIXTURE4/$SRC_REL" "$FIXTURE4/$DST_REL" > /dev/null 2>&1; then
|
||||
pass "real sync creates the mirror file identical to the source"
|
||||
else
|
||||
fail "real sync did not create a byte-identical mirror file"
|
||||
fi
|
||||
|
||||
# --- 5. --check is clean immediately after a real sync ---
|
||||
echo ""
|
||||
echo "--- --check is clean right after syncing ---"
|
||||
if run_script "$FIXTURE4" --check > /dev/null 2>&1; then
|
||||
pass "no drift reported immediately after syncing"
|
||||
else
|
||||
fail "drift reported right after syncing -- sync and check disagree"
|
||||
fi
|
||||
|
||||
# --- 6. Editing the source after a sync introduces drift; re-sync clears it ---
|
||||
echo ""
|
||||
echo "--- source edited after sync is detected as drift, cleared by re-sync ---"
|
||||
write_src "$FIXTURE4" "$CONTENT_B"
|
||||
if run_script "$FIXTURE4" --check > /dev/null 2>&1; then
|
||||
fail "no drift reported after editing the source -- expected drift"
|
||||
else
|
||||
pass "editing the source after a sync is detected as drift"
|
||||
run_script "$FIXTURE4" > /dev/null 2>&1
|
||||
if run_script "$FIXTURE4" --check > /dev/null 2>&1; then
|
||||
pass "re-sync clears the drift"
|
||||
else
|
||||
fail "re-sync did not clear the drift"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- 7. A mirror that was hand-seeded already identical to the source: --check is clean ---
|
||||
echo ""
|
||||
echo "--- --check is clean when the mirror already matches, without ever syncing ---"
|
||||
FIXTURE7="$(make_fixture)"; track "$FIXTURE7"
|
||||
write_src "$FIXTURE7" "$CONTENT_A"
|
||||
write_dst "$FIXTURE7" "$CONTENT_A"
|
||||
if run_script "$FIXTURE7" --check > /dev/null 2>&1; then
|
||||
pass "an already-in-sync mirror reports no drift"
|
||||
else
|
||||
fail "an already-in-sync mirror should report no drift"
|
||||
fi
|
||||
|
||||
# --- 8. A stale, pre-existing mirror that differs from source: --check flags it, sync fixes it ---
|
||||
echo ""
|
||||
echo "--- a stale pre-existing mirror is flagged by --check and overwritten by sync ---"
|
||||
FIXTURE8="$(make_fixture)"; track "$FIXTURE8"
|
||||
write_src "$FIXTURE8" "$CONTENT_A"
|
||||
write_dst "$FIXTURE8" "$CONTENT_B"
|
||||
if run_script "$FIXTURE8" --check > /dev/null 2>&1; then
|
||||
fail "a stale mirror was not flagged as drift"
|
||||
else
|
||||
pass "a stale pre-existing mirror is flagged as drift"
|
||||
fi
|
||||
run_script "$FIXTURE8" > /dev/null 2>&1
|
||||
if diff -q "$FIXTURE8/$SRC_REL" "$FIXTURE8/$DST_REL" > /dev/null 2>&1; then
|
||||
pass "real sync overwrites the stale mirror to match the source"
|
||||
else
|
||||
fail "real sync did not overwrite the stale mirror"
|
||||
fi
|
||||
|
||||
# --- 9. An unknown/extra positional argument is rejected with a usage error ---
|
||||
echo ""
|
||||
echo "--- an unrecognized argument is rejected (usage, exit 1) ---"
|
||||
FIXTURE9="$(make_fixture)"; track "$FIXTURE9"
|
||||
write_src "$FIXTURE9" "$CONTENT_A"
|
||||
if run_script "$FIXTURE9" --bogus > /dev/null 2>&1; then
|
||||
fail "exited 0 with an unrecognized argument -- expected a usage error"
|
||||
else
|
||||
pass "an unrecognized argument is rejected"
|
||||
fi
|
||||
|
||||
# --- 10. --check followed by a stray extra argument is also rejected ---
|
||||
echo ""
|
||||
echo "--- --check plus a trailing extra argument is rejected (usage, exit 1) ---"
|
||||
if run_script "$FIXTURE9" --check extra > /dev/null 2>&1; then
|
||||
fail "exited 0 with --check plus a trailing argument -- expected a usage error"
|
||||
else
|
||||
pass "--check plus a trailing extra argument is rejected"
|
||||
fi
|
||||
|
||||
# --- 11. Real sync is idempotent: running it twice in a row leaves the mirror unchanged ---
|
||||
echo ""
|
||||
echo "--- running real sync twice in a row is idempotent ---"
|
||||
FIXTURE11="$(make_fixture)"; track "$FIXTURE11"
|
||||
write_src "$FIXTURE11" "$CONTENT_A"
|
||||
run_script "$FIXTURE11" > /dev/null 2>&1
|
||||
run_script "$FIXTURE11" > /dev/null 2>&1
|
||||
if run_script "$FIXTURE11" --check > /dev/null 2>&1; then
|
||||
pass "running sync twice in a row is idempotent"
|
||||
else
|
||||
fail "a second sync run introduced unexpected drift"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
[[ $FAIL -eq 0 ]]
|
||||
Reference in New Issue
Block a user