skill.md with full pipeline steps, Obsidian as default output (canvas, tags, dataview, graph colors), two-command install, 71 tests, .gitignore, deps
77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
from pathlib import Path
|
|
from graphify.extract import extract_python, extract, collect_files, _make_id
|
|
|
|
FIXTURES = Path(__file__).parent / "fixtures"
|
|
|
|
|
|
def test_make_id_strips_dots_and_underscores():
|
|
assert _make_id("_auth") == "auth"
|
|
assert _make_id(".httpx._client") == "httpx_client"
|
|
|
|
|
|
def test_make_id_consistent():
|
|
"""Same input always produces same output."""
|
|
assert _make_id("foo", "Bar") == _make_id("foo", "Bar")
|
|
|
|
|
|
def test_make_id_no_leading_trailing_underscores():
|
|
result = _make_id("__init__")
|
|
assert not result.startswith("_")
|
|
assert not result.endswith("_")
|
|
|
|
|
|
def test_extract_python_finds_class():
|
|
result = extract_python(FIXTURES / "sample.py")
|
|
labels = [n["label"] for n in result["nodes"]]
|
|
assert "Transformer" in labels
|
|
|
|
|
|
def test_extract_python_finds_methods():
|
|
result = extract_python(FIXTURES / "sample.py")
|
|
labels = [n["label"] for n in result["nodes"]]
|
|
assert any("__init__" in l or "forward" in l for l in labels)
|
|
|
|
|
|
def test_extract_python_no_dangling_edges():
|
|
"""All edge sources must reference a known node (targets may be external imports)."""
|
|
result = extract_python(FIXTURES / "sample.py")
|
|
node_ids = {n["id"] for n in result["nodes"]}
|
|
for edge in result["edges"]:
|
|
assert edge["source"] in node_ids, f"Dangling source: {edge['source']}"
|
|
|
|
|
|
def test_extract_python_edges_are_extracted():
|
|
result = extract_python(FIXTURES / "sample.py")
|
|
for edge in result["edges"]:
|
|
assert edge["confidence"] == "EXTRACTED"
|
|
|
|
|
|
def test_extract_merges_multiple_files():
|
|
files = list(FIXTURES.glob("*.py"))
|
|
result = extract(files)
|
|
assert len(result["nodes"]) > 0
|
|
assert result["input_tokens"] == 0
|
|
|
|
|
|
def test_collect_files_from_dir():
|
|
files = collect_files(FIXTURES)
|
|
assert all(f.suffix == ".py" for f in files)
|
|
assert len(files) > 0
|
|
|
|
|
|
def test_collect_files_skips_hidden():
|
|
files = collect_files(FIXTURES)
|
|
for f in files:
|
|
assert not any(part.startswith(".") for part in f.parts)
|
|
|
|
|
|
def test_no_dangling_edges_on_extract():
|
|
"""After merging multiple files, no internal edges should be dangling."""
|
|
files = list(FIXTURES.glob("*.py"))
|
|
result = extract(files)
|
|
node_ids = {n["id"] for n in result["nodes"]}
|
|
internal_relations = {"contains", "method", "inherits"}
|
|
for edge in result["edges"]:
|
|
if edge["relation"] in internal_relations:
|
|
assert edge["source"] in node_ids, f"Dangling: {edge}"
|