Files
graphify/tests/test_hooks.py
T
Safi 387f92d4df v2: confidence scores, hyperedges, rationale extraction, git hooks, Claude Code hooks
- confidence_score required on every edge (INFERRED: 0.4-0.9, EXTRACTED: 1.0, AMBIGUOUS: 0.1-0.3)
- semantically_similar_to edges for non-obvious cross-file conceptual links
- hyperedges for 3+ node group relationships - fixed cache and merge pipeline that was silently dropping them
- check_semantic_cache returns 4-tuple including cached_hyperedges
- extract.py: mine the "why" - module/class/function docstrings and rationale comments (# NOTE: # IMPORTANT: # HACK: # WHY: # RATIONALE: # TODO: # FIXME:) as rationale_for nodes
- skill.md: rationale_for in relation schema, doc files extract design rationale
- obsidian output opt-in (--obsidian flag) - default output is graph.html + graph.json + GRAPH_REPORT.md only
- hooks.py: post-checkout hook added alongside post-commit - graph rebuilds on branch switch
- claude install: writes .claude/settings.json PreToolUse hook on Glob/Grep - Claude checks graph before searching raw files
- README updated with all v2 features

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 00:58:55 +01:00

81 lines
2.2 KiB
Python

"""Tests for hooks.py - git hook install/uninstall."""
import subprocess
from pathlib import Path
import pytest
from graphify.hooks import install, uninstall, status, _HOOK_MARKER
def _make_git_repo(tmp_path: Path) -> Path:
subprocess.run(["git", "init", str(tmp_path)], check=True, capture_output=True)
return tmp_path
def test_install_creates_hook(tmp_path):
repo = _make_git_repo(tmp_path)
result = install(repo)
hook = repo / ".git" / "hooks" / "post-commit"
assert hook.exists()
assert _HOOK_MARKER in hook.read_text()
assert "installed" in result
def test_install_is_executable(tmp_path):
repo = _make_git_repo(tmp_path)
install(repo)
hook = repo / ".git" / "hooks" / "post-commit"
assert hook.stat().st_mode & 0o111 # executable bit set
def test_install_idempotent(tmp_path):
repo = _make_git_repo(tmp_path)
install(repo)
result = install(repo)
assert "already installed" in result
# marker appears only once
hook = repo / ".git" / "hooks" / "post-commit"
assert hook.read_text().count(_HOOK_MARKER) == 1
def test_install_appends_to_existing_hook(tmp_path):
repo = _make_git_repo(tmp_path)
hook = repo / ".git" / "hooks" / "post-commit"
hook.write_text("#!/bin/bash\necho existing\n")
hook.chmod(0o755)
install(repo)
content = hook.read_text()
assert "existing" in content
assert _HOOK_MARKER in content
def test_uninstall_removes_hook(tmp_path):
repo = _make_git_repo(tmp_path)
install(repo)
result = uninstall(repo)
hook = repo / ".git" / "hooks" / "post-commit"
assert not hook.exists()
assert "removed" in result.lower()
def test_uninstall_no_hook(tmp_path):
repo = _make_git_repo(tmp_path)
result = uninstall(repo)
assert "nothing to remove" in result
def test_status_installed(tmp_path):
repo = _make_git_repo(tmp_path)
install(repo)
result = status(repo)
assert "installed" in result
def test_status_not_installed(tmp_path):
repo = _make_git_repo(tmp_path)
result = status(repo)
assert "not installed" in result
def test_no_git_repo_raises(tmp_path):
with pytest.raises(RuntimeError, match="No git repository"):
install(tmp_path / "not_a_repo")