fix(memory): test covers CLAUDE.global.md guard entry; doctor asserts exact global symlink target

This commit is contained in:
Bastien Chanot
2026-07-14 16:19:29 +02:00
parent 0f23f10767
commit e9a38a0268
3 changed files with 33 additions and 18 deletions
+21 -18
View File
@@ -6,7 +6,7 @@
# single-occurrence + column-0 closing brace) so drift in install-plugins.sh
# propagates into this test instead of testing a stale copy. GUARDED_CONFIGS,
# CFG_SNAPSHOT, REPO and an info() stub are defined here — the array literal
# at install-plugins.sh:41 is outside the extracted range.
# at install-plugins.sh:43-44 is outside the extracted range.
set -u
INSTALL_SH="$(cd "$(dirname "$0")/../.." && pwd)/install-plugins.sh"
pass=0; fail=0
@@ -19,13 +19,14 @@ awk '/^restore_curated_configs\(\) \{/,/^\}/' "$INSTALL_SH" > "$SUT"
REPO="$(mktemp -d)"
CFG_SNAPSHOT="$(mktemp -d)"
EXPECT="$(mktemp -d)" # our own reference copy — independent of CFG_SNAPSHOT (SUT rm -rf's it)
GUARDED_CONFIGS=("CLAUDE.md" ".claude/settings.json" "settings.json")
GUARDED_CONFIGS=("CLAUDE.md" "CLAUDE.global.md" ".claude/settings.json" "settings.json")
info() { :; } # stub — extracted body calls info(), irrelevant to the assertions
mkdir -p "$REPO/.claude"
printf 'CLAUDE original\n' > "$REPO/CLAUDE.md"
printf '{"a":1}\n' > "$REPO/.claude/settings.json"
printf '{"b":2}\n' > "$REPO/settings.json"
printf 'CLAUDE original\n' > "$REPO/CLAUDE.md"
printf 'CLAUDE.global original\n' > "$REPO/CLAUDE.global.md"
printf '{"a":1}\n' > "$REPO/.claude/settings.json"
printf '{"b":2}\n' > "$REPO/settings.json"
for f in "${GUARDED_CONFIGS[@]}"; do
mkdir -p "$CFG_SNAPSHOT/$(dirname "$f")" "$EXPECT/$(dirname "$f")"
@@ -33,7 +34,7 @@ for f in "${GUARDED_CONFIGS[@]}"; do
cp "$REPO/$f" "$EXPECT/$f"
done
# simulate installer drift: mutate ONE guarded file, leave the other two alone
# simulate installer drift: mutate ONE guarded file, leave the other three alone
printf 'CLAUDE CLOBBERED BY INSTALLER\n' > "$REPO/CLAUDE.md"
# shellcheck source=/dev/null
@@ -42,20 +43,22 @@ restore_curated_configs
cmp -s "$REPO/CLAUDE.md" "$EXPECT/CLAUDE.md"
check T1-mutated-file-restored "$?" 0
cmp -s "$REPO/CLAUDE.global.md" "$EXPECT/CLAUDE.global.md"
check T2-untouched-global-md-unchanged "$?" 0
cmp -s "$REPO/.claude/settings.json" "$EXPECT/.claude/settings.json"
check T2-untouched-local-settings-unchanged "$?" 0
check T3-untouched-local-settings-unchanged "$?" 0
cmp -s "$REPO/settings.json" "$EXPECT/settings.json"
check T3-untouched-settings-unchanged "$?" 0
if [ -d "$CFG_SNAPSHOT" ]; then r4=present; else r4=gone; fi
check T4-snapshot-dir-removed "$r4" gone
check T4-untouched-settings-unchanged "$?" 0
if [ -d "$CFG_SNAPSHOT" ]; then r5=present; else r5=gone; fi
check T5-snapshot-dir-removed "$r5" gone
# --- T5: mktemp failure -> fail-closed (install-plugins.sh, the header block
# --- T6: mktemp failure -> fail-closed (install-plugins.sh, the header block
# that builds CFG_SNAPSHOT) — refuses to run unguarded instead of warning and
# continuing. Extracted with a WIDER range than the SUT above: this logic
# lives in the top-level if/else, outside restore_curated_configs().
SUT2="$(mktemp)"
awk '/^GUARDED_CONFIGS=/,/^fi$/' "$INSTALL_SH" > "$SUT2"
ERR5="$(mktemp)"
ERR6="$(mktemp)"
(
# shellcheck disable=SC2329 # invoked indirectly by the sourced snippet below
mktemp() { return 1; } # force the header's CFG_SNAPSHOT creation to fail
@@ -68,11 +71,11 @@ ERR5="$(mktemp)"
REPO="$(command mktemp -d)"
# shellcheck source=/dev/null
source "$SUT2"
) >/dev/null 2>"$ERR5"
rc5=$?
check T5-mktemp-failure-aborts "$rc5" 1
if grep -qi 'mktemp failed' "$ERR5"; then r5msg=yes; else r5msg=no; fi
check T5-mktemp-failure-loud "$r5msg" yes
rm -f "$ERR5" "$SUT2"
) >/dev/null 2>"$ERR6"
rc6=$?
check T6-mktemp-failure-aborts "$rc6" 1
if grep -qi 'mktemp failed' "$ERR6"; then r6msg=yes; else r6msg=no; fi
check T6-mktemp-failure-loud "$r6msg" yes
rm -f "$ERR6" "$SUT2"
printf 'PASS=%s FAIL=%s\n' "$pass" "$fail"; [ "$fail" -eq 0 ]