From b6a59155200834f277d7e44eda0e0749bb9cb1be Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Fri, 25 Sep 2026 13:45:25 +0000 Subject: [PATCH] fix(tests): exclude build/ from bats test discovery Why tests/run-bats.sh's discovery walk already excludes apm_modules/ and .claude/skills/ because those hold apm-installed copies of the same *.bats files one directory level shallower than their plugins/*/.apm/ source, which overshoots the hardcoded six-levels-up REPO_ROOT walk each test's setup() does and fails to find the bats-support helper. build/ was missing the same exclusion: apm pack stages an identical copy under build/-/ before archiving, hitting the exact same failure mode from a different apm subcommand. A stray local `apm pack` run leaves that directory on disk (gitignored, regenerable) and silently doubles the suite (846 tests instead of 423) with 423 of them failing. Implementation Notes Added `-not -path "*/build/*"` to the find walk and the matching git ls-files grep exclusion, mirroring the existing apm_modules/ and .claude/skills/ entries. Extended tests/test-run-bats.sh with a case following the same pattern as the existing exclusion-bug fixtures. Impact Unblocks the run-tests pre-commit/pre-push hook for any checkout that has ever run a bare `apm pack` locally. --- tests/run-bats.sh | 14 +++++++++++++- tests/test-run-bats.sh | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/tests/run-bats.sh b/tests/run-bats.sh index 9cf171e..4fd0ff7 100755 --- a/tests/run-bats.sh +++ b/tests/run-bats.sh @@ -46,6 +46,17 @@ fi # which is ADR-0024 consequence 2 arriving here. Keeping the exclusion now is # what stops that landing as a mystery double-run on the merge that enables it. # +# build/ is excluded for the same reason again, one layer further out: `apm +# pack` stages a full copy of a package's tree (including its skills' tests/ +# directories) under build/-/ before archiving it. Those +# staged .bats files carry the same six-levels-up REPO_ROOT walk-up as any +# other copy, which resolves past this repo's actual root and fails on a +# missing bats-support helper -- the same failure mode apm_modules/ and +# .claude/skills/ above already guard against, just from a different apm +# subcommand. build/ is gitignored and regenerated on demand, so nothing here +# depends on its contents; the exclusion only stops a stray local `apm pack` +# output from being discovered and double-run. +# # The walk runs from inside REPO_ROOT so the exclusions match paths RELATIVE to # it, the same universe the `git ls-files` grep below sees. Matched against # absolute paths, `*/.claude/worktrees/*` excluded every file whenever the @@ -61,6 +72,7 @@ done < <( -not -path "*/.claude/worktrees/*" \ -not -path "*/apm_modules/*" \ -not -path "*/.claude/skills/*" \ + -not -path "*/build/*" \ | sort ) @@ -99,7 +111,7 @@ if [[ -n "$GIT_TOPLEVEL" && "$GIT_TOPLEVEL" == "$REPO_ROOT" ]]; then [[ -n "$f" ]] && EXPECTED_FILES+=("$REPO_ROOT/$f") done < <( git -C "$REPO_ROOT" ls-files -- '*.bats' \ - | grep -Ev '(^|/)tests/bats/|(^|/)test_helper/|(^|/)\.claude/worktrees/|(^|/)apm_modules/|(^|/)\.claude/skills/' \ + | grep -Ev '(^|/)tests/bats/|(^|/)test_helper/|(^|/)\.claude/worktrees/|(^|/)apm_modules/|(^|/)\.claude/skills/|(^|/)build/' \ | sort || true ) else diff --git a/tests/test-run-bats.sh b/tests/test-run-bats.sh index e28eedf..c60906c 100644 --- a/tests/test-run-bats.sh +++ b/tests/test-run-bats.sh @@ -476,6 +476,40 @@ else fail "the plan-shortfall run failed with the wrong count: $FAKE_OUT" fi +# --- 12. A build/ directory (apm pack's staging output) is excluded, the same +# way apm_modules/ and .claude/skills/ above are. A stray local `apm pack` run +# leaves build/-/ on disk holding a full copy of every packaged +# skill's tests/ directory, gitignored and regenerable, but discoverable by a +# bare `find` all the same. Those staged .bats files carry the same +# several-levels-up REPO_ROOT walk-up as any other copy, which overshoots this +# fixture's root, so an unexcluded build/ turns into the same +# bats-support-not-found failure apm_modules/ and .claude/skills/ already guard +# against -- this was caught live with 423 duplicate failures against a real +# checkout holding a stray build/holocron-*/ from an earlier `apm pack`. +echo "" +echo "--- a build/ directory holding staged .bats copies is excluded ---" +DIR12="$(make_fake_repo)" +FIXTURES+=("$DIR12") +seed_bats_files "$DIR12" +mkdir -p "$DIR12/build/some-pkg-1.0.0/tests" +printf '@test "staged" { false; }\n' > "$DIR12/build/some-pkg-1.0.0/tests/staged.bats" +install_stub_bats "$DIR12" <<'EOF' +#!/usr/bin/env bash +echo "1..1" +echo "ok 1 first" +exit 0 +EOF +run_fake "$DIR12" +if [[ $FAKE_RC -ne 0 ]]; then + fail "a tree holding a build/ directory failed the run: $FAKE_OUT" +elif grep -q "build/some-pkg-1.0.0" <<< "$FAKE_OUT"; then + fail "a .bats file staged under build/ was discovered and run: $FAKE_OUT" +elif grep -q "^2 tests, 0 failures$" <<< "$FAKE_OUT"; then + pass "a build/ directory's staged .bats copies are excluded from discovery" +else + fail "the build/-exclusion run passed with an unexpected count: $FAKE_OUT" +fi + echo "" echo "Results: $PASS passed, $FAIL failed" [[ $FAIL -eq 0 ]] -- 2.43.0