@@ -0,0 +1,252 @@
1 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ """Tests for graph query engine."""
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!
+ from unittest.mock import MagicMock
5 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
6 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import pytest
7 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
8 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.integrators.graph_query import GraphQueryEngine, QueryResult
9 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.integrators.graph
10 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
11 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
12 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def _make_populated_store():
13 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ """Create a store with test data."""
14 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = InMemoryStore()
15 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Python", "technology", ["A programming language"])
16 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Django", "technology", ["A web framework"])
17 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Alice", "person", ["Software engineer"])
18 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Bob", "person", ["Product manager"])
19 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Acme Corp", "organization", ["A tech company"])
20 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.add_relationship("Alice", "Python", "uses")
21 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.add_relationship("Alice", "Bob", "works_with")
22 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.add_relationship("Django", "Python", "built_on")
23 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.add_relationship("Alice", "Acme Corp", "employed_by")
24 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return store
25 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
26 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
27 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestQueryResultToText:
28 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_text_with_dict_data(self):
29 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ r = QueryResult(
30 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ data={"entity_count": 5, "relationship_count": 3},
31 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ query_type="filter",
32 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ explanation="Stats",
33 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
34 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ text = r.to_text()
35 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "entity_count: 5" in text
36 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "relationship_count: 3" in text
37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
38 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_text_with_list_of_entities(self):
39 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ r = QueryResult(
40 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ data=[{"name": "Python", "type": "technology", "descriptions": ["A language"]}],
41 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ query_type="filter",
42 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
43 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ text = r.to_text()
44 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "Python" in text
45 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "technology" in text
46 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
47 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_text_with_empty_list(self):
48 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ r = QueryResult(data=[], query_type="filter")
49 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "No results" in r.to_text()
50 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
51 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_text_with_relationships(self):
52 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ r = QueryResult(
53 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ data=[{"source": "A", "target": "B", "type": "knows"}],
54 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ query_type="filter",
55 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
56 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ text = r.to_text()
57 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "A" in text
58 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "B" in text
59 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "knows" in text
60 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
62 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestQueryResultToJson:
63 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_json_roundtrip(self):
64 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ r = QueryResult(data={"key": "val"}, query_type="filter", raw_query="test()")
65 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ parsed = json.loads(r.to_json())
66 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert parsed["query_type"] == "filter"
67 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert parsed["data"]["key"] == "val"
68 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert parsed["raw_query"] == "test()"
69 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
70 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
71 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestQueryResultToMermaid:
72 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_mermaid_with_entities_and_rels(self):
73 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ r = QueryResult(
74 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ data=[
75 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {"name": "Alice", "type": "person"},
76 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {"name": "Bob", "type": "person"},
77 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {"source": "Alice", "target": "Bob", "type": "knows"},
78 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ],
79 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ query_type="filter",
80 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
81 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ mermaid = r.to_mermaid()
82 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "graph LR" in mermaid
83 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "Alice" in mermaid
84 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "Bob" in mermaid
85 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "knows" in mermaid
86 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
87 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_mermaid_empty(self):
88 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ r = QueryResult(data=[], query_type="filter")
89 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ mermaid = r.to_mermaid()
90 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "graph LR" in mermaid
91 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
92 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
93 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestDirectMode:
94 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_stats(self):
95 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
97 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.stats()
98 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert result.data["entity_count"] == 5
99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert result.data["relationship_count"] == 4
100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert result.data["entity_types"]["technology"] == 2
101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert result.data["entity_types"]["person"] == 2
102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_entities_no_filter(self):
104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
106 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.entities()
107 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 5
108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
109 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_entities_filter_by_name(self):
110 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
111 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
112 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.entities(name="python")
113 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 1
114 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert result.data[0]["name"] == "Python"
115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_entities_filter_by_type(self):
117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.entities(entity_type="person")
120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 2
121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ names = {e["name"] for e in result.data}
122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert names == {"Alice", "Bob"}
123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_entities_filter_by_both(self):
125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
127 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.entities(name="ali", entity_type="person")
128 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 1
129 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert result.data[0]["name"] == "Alice"
130 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
131 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_entities_case_insensitive(self):
132 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
133 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
134 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.entities(name="PYTHON")
135 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 1
136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
137 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_relationships_no_filter(self):
138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.relationships()
141 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 4
142 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_relationships_filter_by_source(self):
144 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
145 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
146 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.relationships(source="alice")
147 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 3
148 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
149 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_relationships_filter_by_type(self):
150 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
151 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
152 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.relationships(rel_type="uses")
153 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 1
154 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
155 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_neighbors(self):
156 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
157 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
158 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.neighbors("Alice")
159 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Alice connects to Python, Bob, Acme Corp
160 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ entities = [item for item in result.data if "name" in item]
161 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ rels = [item for item in result.data if "source" in item and "target" in item]
162 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(entities) >= 2 # Alice + neighbors
163 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(rels) >= 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_neighbors_not_found(self):
166 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
167 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
168 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.neighbors("Ghost")
169 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert result.data == []
170 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "not found" in result.explanation
171 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_cypherplanation
173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_sql_raises_on_inmemory(self):
175 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = InMemoryStore()
176 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
177 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with pcypher("MATCH (n) RETURN n")""
178 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
179 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import json
180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from uni"""Tests for graph query engine."""
181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import json
183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from unittest.mock import MagicMock
184 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
185 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import pytest
186 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
187 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.integrators.graph_query import GraphQueryEngine, QueryResult
188 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ from video_processor.integrators.graph_store import InMemoryStore, SQLiteStore
189 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
190 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
191 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def _make_populated_store():
192 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ """Create a store with test data."""
193 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = InMemoryStore()
194 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Python", "technology", ["A programming language"])
195 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Django", "technology", ["A web framework"])
196 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Alice", "person", ["Software engineer"])
197 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Bob", "person", ["Product manager"])
198 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.merge_entity("Acme Corp", "organization", ["A tech company"])
199 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.add_relationship("Alice", "Python", "uses")
200 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.add_relationship("Alice", "Bob", "works_with")
201 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store.add_relationship("Django", "Python", "bu# Conditional FalkorDB tests
202 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _falkordb_available = False
203 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ try:
204 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import redislite # noqa: F401
205 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
206 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _falkordb_available = True
207 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ except ImportError:
208 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pass
209 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
210 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
211 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ @pytest.mark.skipif(not _falkordb_available, reason="falkordblite not installed")
212 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestFalkorDBulated_store()
213 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cyphertore)
214 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ phQueryEngine, QueryResulFalkorDBStore
215 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ""Tests for graphery engi # Alice connects to Python, Bob, Acme Corp
216 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ entities = [item for item in result.data if "name" in item]
217 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ rels = [item for item in result.data if "source" in item and "target" in item]
218 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(entities) >= 2 # Alice + neighbors
219 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(rels) >= 1
220 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
221 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_neighbors_not_found(self):
222 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
223 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
224 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.neighbors("Ghost")
225 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert result.data == []
226 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert "not found" in result.explanation
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_sql_raises_on_inmemory(self):
229 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = InMemoryStore()
230 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
231 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ with pytest.raises(NotImplementedError):
232 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine.sql("SELECT * FROM entities")
233 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
234 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_entities_limit(self):
235 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ store = _make_populated_store()
236 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ engine = GraphQueryEngine(store)
237 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ result = engine.entities(limit=2)
238 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert len(result.data) == 2
239 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
240 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
241 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ class TestFromJsonPath:
242 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ def test_load_from_json(self, tmp_path):
243 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ data = {
244 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "nodes": [
245 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {"name": "Python", "type": "technology", "descriptions": ["A language"]},
246 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {"name": "Alice", "type": "person", "descriptions": ["Engineer"]},
247 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ],
248 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "relationships": [
249 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ {"source": "Alice", "target": "Python", "type": "uses"},
250 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ],
251 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
252 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ jf = tmp_path / "kg.json