mirror of
https://github.com/safishamsi/graphify.git
synced 2026-09-22 21:45:58 +00:00
fix(extract_dart): use _file_stem instead of str(path) for child node IDs to prevent machine-specific absolute paths in graph.json (#999)
This commit is contained in:
+4
-2
@@ -3110,6 +3110,8 @@ def extract_dart(path: Path) -> dict:
|
||||
except OSError:
|
||||
return {"error": f"cannot read {path}"}
|
||||
|
||||
# Use stem (not str(path)) for child IDs to keep them machine-independent.
|
||||
stem = _file_stem(path)
|
||||
file_nid = _make_id(str(path))
|
||||
nodes = [{"id": file_nid, "label": path.name, "file_type": "code",
|
||||
"source_file": str(path), "source_location": None}]
|
||||
@@ -3118,7 +3120,7 @@ def extract_dart(path: Path) -> dict:
|
||||
|
||||
# Classes and mixins
|
||||
for m in re.finditer(r"^\s*(?:abstract\s+)?(?:class|mixin)\s+(\w+)", src, re.MULTILINE):
|
||||
nid = _make_id(str(path), m.group(1))
|
||||
nid = _make_id(stem, m.group(1))
|
||||
if nid not in defined:
|
||||
nodes.append({"id": nid, "label": m.group(1), "file_type": "code",
|
||||
"source_file": str(path), "source_location": None})
|
||||
@@ -3132,7 +3134,7 @@ def extract_dart(path: Path) -> dict:
|
||||
name = m.group(1)
|
||||
if name in {"if", "for", "while", "switch", "catch", "return"}:
|
||||
continue
|
||||
nid = _make_id(str(path), name)
|
||||
nid = _make_id(stem, name)
|
||||
if nid not in defined:
|
||||
nodes.append({"id": nid, "label": name, "file_type": "code",
|
||||
"source_file": str(path), "source_location": None})
|
||||
|
||||
@@ -1022,3 +1022,41 @@ def test_pure_export_no_from_not_treated_as_reexport():
|
||||
result = extract_js(Path(f.name))
|
||||
reexports = [e for e in result["edges"] if e["relation"] == "re_exports"]
|
||||
assert reexports == [], f"Pure export should not create re_exports: {reexports}"
|
||||
|
||||
|
||||
def test_dart_child_node_ids_are_stem_based(tmp_path):
|
||||
"""Dart child node IDs must be built from _file_stem rather than absolute path."""
|
||||
from graphify.extract import extract_dart, _file_stem, _make_id
|
||||
|
||||
src_file = tmp_path / "mydir" / "sample.dart"
|
||||
src_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
src_file.write_bytes(b"class MyClass {}\nvoid myFunc() {}\n")
|
||||
|
||||
result = extract_dart(src_file)
|
||||
|
||||
stem = _file_stem(src_file) # -> "mydir.sample"
|
||||
expected_class_nid = _make_id(stem, "MyClass") # -> "mydir_sample_myclass"
|
||||
expected_func_nid = _make_id(stem, "myFunc") # -> "mydir_sample_myfunc"
|
||||
|
||||
node_ids = {n["id"] for n in result["nodes"]}
|
||||
|
||||
assert expected_class_nid in node_ids, (
|
||||
f"Class node ID '{expected_class_nid}' not found in {node_ids}. "
|
||||
"extract_dart may still be using str(path) instead of _file_stem(path)."
|
||||
)
|
||||
assert expected_func_nid in node_ids, (
|
||||
f"Function node ID '{expected_func_nid}' not found in {node_ids}. "
|
||||
"extract_dart may still be using str(path) instead of _file_stem(path)."
|
||||
)
|
||||
|
||||
# Sanity-check: no child node ID should contain any path separator fragment.
|
||||
file_nid = next(n["id"] for n in result["nodes"] if n.get("label") == src_file.name)
|
||||
for node in result["nodes"]:
|
||||
if node["id"] == file_nid:
|
||||
continue
|
||||
assert "_" + stem.replace(".", "_") in node["id"] or node["id"].startswith(stem.replace(".", "_")), (
|
||||
f"Child node ID '{node['id']}' does not start with the expected stem prefix '{stem}'. "
|
||||
"This suggests an absolute path is still leaking into the ID."
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user