mirror of
https://github.com/safishamsi/graphify.git
synced 2026-08-26 16:26:42 +00:00
test(affected): cover outside-root clean-miss and non-out-dir graph layout (#2706)
Adds the two gaps the deep-dive flagged: an absolute seed outside the derived root must miss cleanly (not resolve to a same-basename in-root node), and a --graph pointing at a graph.json NOT under graphify-out uses the else gp.parent fallback root. Also adds the CHANGELOG entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
243a1801f1
commit
6f1cbe5fda
@@ -4,6 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu
|
||||
|
||||
## 0.9.44 (unreleased)
|
||||
|
||||
- Fix: `graphify affected` resolves an absolute-path seed against the repo root derived from the graph's own location instead of the current working directory, so a blast-radius query with an absolute seed run from anywhere (an editor, a script) no longer silently returns nothing; a seed outside the root still misses cleanly (#2706, thanks @ousamabenyounes).
|
||||
- Fix: a lazy CommonJS `require(...)` inside a function body (the idiom for breaking circular dependencies) now emits the same `imports_from`/`imports` dependency edges as a top-level require, attributed to the enclosing function, instead of being silently dropped; a dynamic `require(variable)` is still skipped (#2700, thanks @rajanpanth).
|
||||
- Fix: a JS/TS identifier bound by an import whose target resolves outside the scanned corpus (e.g. a `lucide-react` icon) is now shadowed, so using it as a value no longer fabricates an INFERRED `indirect_call` onto an unrelated same-named callable elsewhere in the corpus; a relative/in-corpus import still resolves to its real target (#2757, thanks @phudayyy).
|
||||
- Fix: an OCaml qualified call `M.f` to an external module (one not defined in the same file, e.g. Hardcaml's `Reg_spec.create`) no longer binds to a same-named local `let f` — which produced a false `calls` edge and, when the caller was that local `f`, a `f -> f` self-loop. External qualified calls are kept as a distinct target labelled by the full path; unqualified calls and calls into a locally-defined module still resolve locally, and cross-file `Geo.area` still collapses onto another file's `area`.
|
||||
|
||||
@@ -371,3 +371,55 @@ def test_affected_absolute_seed_resolves_via_graph_root_off_cwd(tmp_path, monkey
|
||||
assert "Affected nodes for Foo" in out
|
||||
assert "X()" in out
|
||||
|
||||
|
||||
def test_affected_absolute_seed_outside_root_misses_cleanly(tmp_path, monkeypatch, capsys):
|
||||
"""An absolute seed that is NOT under the derived repo root must report a clean
|
||||
no-match, not silently traverse from a wrong/guessed node (#2706)."""
|
||||
from graphify.paths import GRAPHIFY_OUT_NAME
|
||||
|
||||
repo_root = tmp_path / "repo"
|
||||
out_dir = repo_root / GRAPHIFY_OUT_NAME
|
||||
out_dir.mkdir(parents=True)
|
||||
g = nx.DiGraph()
|
||||
g.add_node("target", label="Foo", source_file="pkg/foo.py", source_location="L1")
|
||||
g.add_node("caller", label="X()", source_file="app.py", source_location="L4")
|
||||
g.add_edge("caller", "target", relation="calls")
|
||||
gp = out_dir / "graph.json"
|
||||
gp.write_text(json.dumps(json_graph.node_link_data(g, edges="links")), encoding="utf-8")
|
||||
|
||||
monkeypatch.chdir(tmp_path)
|
||||
outside_seed = str(tmp_path / "other-repo" / "pkg" / "foo.py") # same basename, different tree
|
||||
monkeypatch.setattr(mainmod, "_check_skill_version", lambda _: None)
|
||||
monkeypatch.setattr(mainmod.sys, "argv",
|
||||
["graphify", "affected", outside_seed, "--graph", str(gp)])
|
||||
mainmod.main()
|
||||
|
||||
out = capsys.readouterr().out
|
||||
assert "Affected nodes for Foo" not in out # must NOT resolve to the in-root Foo
|
||||
|
||||
|
||||
def test_affected_absolute_seed_with_graph_not_under_out_dir(tmp_path, monkeypatch, capsys):
|
||||
"""Fallback layout: when --graph points at a graph.json NOT under the
|
||||
graphify-out dir, the root is the graph's own parent (`else gp.parent`)."""
|
||||
repo_root = tmp_path / "repo"
|
||||
repo_root.mkdir(parents=True)
|
||||
g = nx.DiGraph()
|
||||
g.add_node("target", label="Foo", source_file="pkg/foo.py", source_location="L1")
|
||||
g.add_node("caller", label="X()", source_file="app.py", source_location="L4")
|
||||
g.add_edge("caller", "target", relation="calls")
|
||||
gp = repo_root / "graph.json" # directly under repo_root, not graphify-out/
|
||||
gp.write_text(json.dumps(json_graph.node_link_data(g, edges="links")), encoding="utf-8")
|
||||
|
||||
elsewhere = tmp_path / "elsewhere"
|
||||
elsewhere.mkdir()
|
||||
monkeypatch.chdir(elsewhere)
|
||||
abs_seed = str(repo_root / "pkg" / "foo.py")
|
||||
monkeypatch.setattr(mainmod, "_check_skill_version", lambda _: None)
|
||||
monkeypatch.setattr(mainmod.sys, "argv",
|
||||
["graphify", "affected", abs_seed, "--graph", str(gp)])
|
||||
mainmod.main()
|
||||
|
||||
out = capsys.readouterr().out
|
||||
assert "Affected nodes for Foo" in out
|
||||
assert "X()" in out
|
||||
|
||||
|
||||
Reference in New Issue
Block a user