51 lines
2.0 KiB
Python
51 lines
2.0 KiB
Python
"""A node whose source_file equals the scan root must not crash build (#1618).
|
|
|
|
`_norm_source_file` relativizes an absolute source_file that equals the scan root
|
|
to `Path('.')`. `_semantic_id_remap` then fed that into `_file_stem`, whose
|
|
`path.with_suffix("")` raises `ValueError: '.' has an empty name` — crashing the
|
|
final graph assembly AFTER all LLM extraction cost was spent, writing no graph at
|
|
all. A project-level node (source_file == root) has no per-file identity to remap,
|
|
so its id is left untouched.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from graphify.build import _semantic_id_remap, build_from_json
|
|
from graphify.extractors.base import _file_stem
|
|
|
|
|
|
def test_file_stem_handles_dot_path():
|
|
assert _file_stem(Path(".")) == "" # no raise
|
|
assert _file_stem(Path("src/foo.py")) == "src/foo"
|
|
|
|
|
|
def test_semantic_id_remap_root_equal_source_file_no_crash():
|
|
root = "/some/project/root"
|
|
node = {"id": "some_concept", "source_file": root, "_origin": "semantic"}
|
|
remap = _semantic_id_remap([node], root) # must not raise
|
|
# a root-equal node has no file stem, so its id is left untouched (not remapped)
|
|
assert "some_concept" not in remap
|
|
|
|
|
|
def test_build_from_json_with_root_level_concept_node():
|
|
root = "/proj"
|
|
combined = {
|
|
"nodes": [
|
|
{"id": "proj_concept", "label": "Project", "file_type": "concept",
|
|
"source_file": root, "_origin": "semantic"},
|
|
{"id": "src_foo", "label": "foo", "file_type": "code",
|
|
"source_file": "src/foo.py", "_origin": "ast"},
|
|
],
|
|
"edges": [],
|
|
}
|
|
G = build_from_json(combined, root=root) # previously crashed here
|
|
assert G.number_of_nodes() == 2
|
|
|
|
|
|
def test_normal_semantic_remap_still_works():
|
|
# regression guard: a real per-file node still gets remap consideration (#1504)
|
|
remap = _semantic_id_remap(
|
|
[{"id": "foo", "source_file": "src/foo.py", "_origin": "semantic"}], "/proj")
|
|
assert isinstance(remap, dict)
|