@@ -0,0 +1,252 @@
1 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ """Tests for navegador.graph.export — text-based graph export and import."""
2 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
3 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import json
4 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import tempfile
5 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from pathlib import Path
6 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from unittest.mock import MagicMock
7 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
8 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import pytest
9 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
10 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from navegador.graph.export import (
11 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _export_edges,
12 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _export_nodes,
13 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _import_edge,
14 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _import_node,
15 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ export_graph,
16 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import_graph,
17 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
18 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
19 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
20 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def _mock_store(nodes=None, edges=None):
21 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
22 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
23 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def query_side_effect(cypher, params=None):
24 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = MagicMock()
25 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if "labels(n)" in cypher and "properties" in cypher:
26 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result.result_set = nodes or []
27 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ elif "type(r)" in cypher:
28 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result.result_set = edges or []
29 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ elif "DETACH DELETE" in cypher:
30 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result.result_set = []
31 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else:
32 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result.result_set = []
33 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return result
34 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
35 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.side_effect = query_side_effect
36 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.clear = MagicMock()
37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return store
38 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
39 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
40 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # ── export_graph ─────────────────────────────────────────────────────────────
41 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
42 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestExportGraph:
43 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_creates_output_file(self):
44 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _mock_store(nodes=[], edges=[])
45 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
46 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ output = Path(tmpdir) / "graph.jsonl"
47 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ export_graph(store, output)
48 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert output.exists()
49 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
50 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_returns_counts(self):
51 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ nodes = [["Function", {"name": "foo", "file_path": "app.py"}]]
52 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _mock_store(nodes=nodes, edges=[])
53 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
54 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ stats = export_graph(store, Path(tmpdir) / "graph.jsonl")
55 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert stats["nodes"] == 1
56 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert stats["edges"] == 0
57 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
58 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_writes_valid_jsonl(self):
59 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ nodes = [
60 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ["Function", {"name": "foo", "file_path": "app.py"}],
61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ["Class", {"name": "Bar", "file_path": "bar.py"}],
62 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ]
63 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ edges = [["CALLS", "Function", "foo", "app.py", "Function", "bar", "bar.py"]]
64 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _mock_store(nodes=nodes, edges=edges)
65 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
66 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ output = Path(tmpdir) / "graph.jsonl"
67 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ export_graph(store, output)
68 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ lines = output.read_text().strip().split("\n")
69 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(lines) == 3 # 2 nodes + 1 edge
70 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for line in lines:
71 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ record = json.loads(line)
72 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert record["kind"] in ("node", "edge")
73 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
74 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_output_is_sorted(self):
75 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ nodes = [
76 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ["Function", {"name": "z_func", "file_path": "z.py"}],
77 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ["Class", {"name": "a_class", "file_path": "a.py"}],
78 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ]
79 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _mock_store(nodes=nodes, edges=[])
80 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
81 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ output = Path(tmpdir) / "graph.jsonl"
82 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ export_graph(store, output)
83 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ lines = output.read_text().strip().split("\n")
84 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ labels = [json.loads(line)["label"] for line in lines]
85 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Class comes before Function alphabetically
86 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert labels[0] == "Class"
87 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert labels[1] == "Function"
88 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
89 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_creates_parent_dirs(self):
90 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _mock_store(nodes=[], edges=[])
91 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
92 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ output = Path(tmpdir) / "sub" / "dir" / "graph.jsonl"
93 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ export_graph(store, output)
94 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert output.exists()
95 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
97 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # ── import_graph ─────────────────────────────────────────────────────────────
98 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestImportGraph:
100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_raises_on_missing_file(self):
101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with pytest.raises(FileNotFoundError):
103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import_graph(store, "/nonexistent/graph.jsonl")
104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_clears_graph_by_default(self):
106 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
107 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
109 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f = Path(tmpdir) / "graph.jsonl"
110 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.write_text("")
111 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import_graph(store, f)
112 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.clear.assert_called_once()
113 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
114 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_no_clear_flag(self):
115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f = Path(tmpdir) / "graph.jsonl"
119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.write_text("")
120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import_graph(store, f, clear=False)
121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.clear.assert_not_called()
122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_imports_nodes(self):
124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
127 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f = Path(tmpdir) / "graph.jsonl"
128 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ node = {"kind": "node", "label": "Function", "props": {"name": "foo", "file_path": "app.py"}}
129 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.write_text(json.dumps(node) + "\n")
130 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ stats = import_graph(store, f)
131 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert stats["nodes"] == 1
132 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
133 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_imports_edges(self):
134 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
135 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
137 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f = Path(tmpdir) / "graph.jsonl"
138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ edge = {
139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "kind": "edge",
140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "type": "CALLS",
141 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "from": {"label": "Function", "name": "foo", "path": "app.py"},
142 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "to": {"label": "Function", "name": "bar", "path": "bar.py"},
143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
144 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.write_text(json.dumps(edge) + "\n")
145 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ stats = import_graph(store, f)
146 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert stats["edges"] == 1
147 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
148 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_returns_counts(self):
149 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
150 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
151 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
152 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f = Path(tmpdir) / "graph.jsonl"
153 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ lines = [
154 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ json.dumps({"kind": "node", "label": "Function", "props": {"name": "foo", "file_path": "app.py"}}),
155 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ json.dumps({"kind": "node", "label": "Class", "props": {"name": "Bar", "file_path": "bar.py"}}),
156 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ json.dumps({"kind": "edge", "type": "CALLS",
157 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "from": {"label": "Function", "name": "foo", "path": ""},
158 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "to": {"label": "Class", "name": "Bar", "path": ""}}),
159 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ]
160 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.write_text("\n".join(lines) + "\n")
161 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ stats = import_graph(store, f)
162 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert stats["nodes"] == 2
163 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert stats["edges"] == 1
164 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
165 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_skips_blank_lines(self):
166 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
167 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
168 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with tempfile.TemporaryDirectory() as tmpdir:
169 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f = Path(tmpdir) / "graph.jsonl"
170 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ node = json.dumps({"kind": "node", "label": "Function", "props": {"name": "foo", "file_path": ""}})
171 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.write_text(f"\n{node}\n\n")
172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ stats = import_graph(store, f)
173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert stats["nodes"] == 1
174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
175 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
176 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # ── _export_nodes / _export_edges ────────────────────────────────────────────
177 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
178 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestExportHelpers:
179 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_export_nodes_handles_non_dict_props(self):
180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[["Function", "not_a_dict"]])
182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ nodes = _export_nodes(store)
183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(nodes) == 1
184 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert nodes[0]["props"] == {}
185 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
186 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_export_edges_returns_structured_data(self):
187 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
188 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(
189 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result_set=[["CALLS", "Function", "foo", "app.py", "Function", "bar", "bar.py"]]
190 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
191 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ edges = _export_edges(store)
192 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(edges) == 1
193 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert edges[0]["type"] == "CALLS"
194 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert edges[0]["from"]["name"] == "foo"
195 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert edges[0]["to"]["name"] == "bar"
196 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
197 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
198 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # ── _import_node / _import_edge ──────────────────────────────────────────────
199 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
200 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestImportHelpers:
201 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_import_node_adds_missing_file_path(self):
202 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
203 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
204 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ record = {"kind": "node", "label": "Concept", "props": {"name": "JWT"}}
205 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _import_node(store, record)
206 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.assert_called_once()
207 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cypher = store.query.call_args[0][0]
208 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "MERGE" in cypher
209 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
210 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_import_node_adds_missing_name(self):
211 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
212 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
213 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ record = {"kind": "node", "label": "Domain", "props": {"description": "Auth domain"}}
214 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _import_node(store, record)
215 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Should have added name="" to props
216 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.assert_called_once()
217 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ params = store.query.call_args[0][1]
218 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert params["name"] == ""
219 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
220 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_import_node_uses_path_key_for_repos(self):
221 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
222 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
223 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ record = {"kind": "node", "label": "Repository", "props": {"name": "myrepo", "path": "/code/myrepo"}}
224 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _import_node(store, record)
225 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cypher = store.query.call_args[0][0]
226 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "path" in cypher
227 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
228 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_import_edge_with_paths(self):
229 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
230 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
231 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ record = {
232 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "kind": "edge",
233 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "type": "CALLS",
234 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "from": {"label": "Function", "name": "foo", "path": "app.py"},
235 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "to": {"label": "Function", "name": "bar", "path": "bar.py"},
236 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
237 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _import_edge(store, record)
238 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.assert_called_once()
239 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
240 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_import_edge_without_paths(self):
241 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = MagicMock()
242 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.return_value = MagicMock(result_set=[])
243 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ record = {
244 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "kind": "edge",
245 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "type": "RELATED_TO",
246 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "from": {"label": "Concept", "name": "JWT", "path": ""},
247 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "to": {"label": "Concept", "name": "OAuth", "path": ""},
248 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
249 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _import_edge(store, record)
250 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.query.assert_called_once()
251 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cypher = store.query.call_args[0][0]
252 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "file_path" not in cypher