test(hooks): replace static string-match with a runtime same-head test (#2421)

The PR's test only asserted the guard line exists in the source — the exact
static-assertion anti-pattern #2126/#2641 removed for providing zero coverage.
Replace it with a runtime test that runs the real emitted post-checkout script
under sh up to the guard (with a sentinel, before the launch): same-head skips,
different-head falls through, file-checkout skips at the earlier guard. Adds the
CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
safishamsi
2026-08-17 17:53:43 +01:00
co-authored by Claude Opus 4.8
parent 5c88af7617
commit 355b6628b4
2 changed files with 25 additions and 7 deletions
+1
View File
@@ -4,6 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu
## 0.9.46 (unreleased)
- Fix: the `post-checkout` hook skips its rebuild when HEAD is unchanged (e.g. `git checkout -b` with no start point), so creating a branch no longer triggers a full graph rebuild (#2421, thanks @nothariharan).
- Feature: Markdown nodes now carry a `node_kind` (`page` vs `heading`) attribute so a docs corpus can be filtered by kind, and leading YAML frontmatter is parsed onto the page node as bounded, sanitized attributes; a `#` comment inside frontmatter is no longer mis-extracted as a heading (thanks @evanthomasgelders). Node ids are unchanged, so existing markdown graphs are not re-keyed.
- Feature: Common Lisp `.lisp`/`.cl`/`.lsp`/`.asd` extraction via tree-sitter-commonlisp (optional `[commonlisp]` extra) — packages, classes, functions, methods, generics, macros, variable definers, and same-file calls; `open`ed/`:use`d packages resolve cross-file (thanks @fade).
+24 -7
View File
@@ -614,13 +614,30 @@ def test_hooks_honor_skip_env(name, script):
)
def test_checkout_hook_skips_same_head_noop():
"""`git checkout -b` with no start point passes identical PREV/NEW heads.
Rebuild must short-circuit ΓÇö PREV_HEAD/NEW_HEAD were previously assigned
and never read (#2421 / leftover from #1809)."""
assert "PREV_HEAD=$1" in _CHECKOUT_SCRIPT
assert "NEW_HEAD=$2" in _CHECKOUT_SCRIPT
assert '[ "$PREV_HEAD" = "$NEW_HEAD" ] && exit 0' in _CHECKOUT_SCRIPT
def test_checkout_hook_skips_same_head_noop_at_runtime():
"""`git checkout -b` with no start point reports a branch switch (flag=1) but
passes identical PREV/NEW heads, so the rebuild must short-circuit (#2421).
Prove BEHAVIOR by running the real emitted script under sh up to the guard
with a sentinel, not by matching the source string (per the #2126/#2641
convention that static assertions provided zero coverage)."""
from graphify.hooks import _CHECKOUT_SCRIPT
guard = '[ "$PREV_HEAD" = "$NEW_HEAD" ] && exit 0'
assert guard in _CHECKOUT_SCRIPT, "guard missing from the checkout script"
# Real script through the same-head guard, then a sentinel — stops before the
# graphify-out check / detached launch so nothing is actually rebuilt.
prefix = _CHECKOUT_SCRIPT.split(guard)[0] + guard + "\necho RAN\n"
def run(prev, new, flag):
# sh -c CMD name arg1 arg2 arg3 -> $0=name $1=prev $2=new $3=flag
return subprocess.run(["sh", "-c", prefix, "hook", prev, new, flag],
capture_output=True, text=True)
# branch switch (flag=1), SAME head -> short-circuit, sentinel not reached
assert "RAN" not in run("abc123", "abc123", "1").stdout
# branch switch (flag=1), DIFFERENT head -> falls through to the sentinel
assert "RAN" in run("abc123", "def456", "1").stdout
# file checkout (flag != 1) -> skips at the earlier BRANCH_SWITCH guard
assert "RAN" not in run("abc123", "def456", "0").stdout
@pytest.mark.parametrize("name,script", _HOOK_SCRIPTS)