Navegador

navegador / tests / test_context.py
Source Blame History 575 lines
b663b12… lmata 1 """Tests for ContextBundle serialization and ContextLoader with mock store."""
5e4b8e4… anonymous 2
b663b12… lmata 3 import json
b663b12… lmata 4 from unittest.mock import MagicMock
5e4b8e4… anonymous 5
b663b12… lmata 6 from navegador.context.loader import ContextBundle, ContextLoader, ContextNode
b663b12… lmata 7
b663b12… lmata 8 # ── Fixtures ──────────────────────────────────────────────────────────────────
5e4b8e4… anonymous 9
5e4b8e4… anonymous 10 def _make_bundle():
5e4b8e4… anonymous 11 target = ContextNode(
5e4b8e4… anonymous 12 type="Function",
5e4b8e4… anonymous 13 name="get_user",
5e4b8e4… anonymous 14 file_path="src/auth.py",
5e4b8e4… anonymous 15 line_start=42,
5e4b8e4… anonymous 16 docstring="Return a user by ID.",
5e4b8e4… anonymous 17 signature="def get_user(user_id: int) -> User:",
5e4b8e4… anonymous 18 )
5e4b8e4… anonymous 19 nodes = [
5e4b8e4… anonymous 20 ContextNode(type="Function", name="validate_token", file_path="src/auth.py", line_start=10),
5e4b8e4… anonymous 21 ContextNode(type="Class", name="User", file_path="src/models.py", line_start=5),
5e4b8e4… anonymous 22 ]
b663b12… lmata 23 edges = [{"from": "get_user", "type": "CALLS", "to": "validate_token"}]
b663b12… lmata 24 return ContextBundle(target=target, nodes=nodes, edges=edges,
b663b12… lmata 25 metadata={"query": "function_context"})
b663b12… lmata 26
b663b12… lmata 27
b663b12… lmata 28 def _make_knowledge_bundle():
b663b12… lmata 29 target = ContextNode(
b663b12… lmata 30 type="Concept", name="JWT", description="Stateless token auth", domain="auth"
b663b12… lmata 31 )
b663b12… lmata 32 nodes = [
b663b12… lmata 33 ContextNode(type="Rule", name="Tokens must expire"),
b663b12… lmata 34 ContextNode(type="WikiPage", name="Auth Overview"),
b663b12… lmata 35 ]
5e4b8e4… anonymous 36 edges = [
b663b12… lmata 37 {"from": "Tokens must expire", "type": "GOVERNS", "to": "JWT"},
b663b12… lmata 38 {"from": "Auth Overview", "type": "DOCUMENTS", "to": "JWT"},
5e4b8e4… anonymous 39 ]
5e4b8e4… anonymous 40 return ContextBundle(target=target, nodes=nodes, edges=edges)
5e4b8e4… anonymous 41
5e4b8e4… anonymous 42
b663b12… lmata 43 def _mock_store(rows=None):
b663b12… lmata 44 store = MagicMock()
b663b12… lmata 45 result = MagicMock()
b663b12… lmata 46 result.result_set = rows or []
b663b12… lmata 47 store.query.return_value = result
b663b12… lmata 48 return store
b663b12… lmata 49
b663b12… lmata 50
b663b12… lmata 51 # ── ContextNode ───────────────────────────────────────────────────────────────
b663b12… lmata 52
b663b12… lmata 53 class TestContextNode:
b663b12… lmata 54 def test_defaults(self):
b663b12… lmata 55 n = ContextNode(type="Function", name="foo")
b663b12… lmata 56 assert n.file_path == ""
b663b12… lmata 57 assert n.line_start is None
b663b12… lmata 58 assert n.docstring is None
b663b12… lmata 59 assert n.domain is None
b663b12… lmata 60
b663b12… lmata 61 def test_knowledge_fields(self):
b663b12… lmata 62 n = ContextNode(type="Concept", name="Payment", description="A payment", domain="billing")
b663b12… lmata 63 assert n.description == "A payment"
b663b12… lmata 64 assert n.domain == "billing"
b663b12… lmata 65
b663b12… lmata 66
b663b12… lmata 67 # ── ContextBundle.to_dict ─────────────────────────────────────────────────────
b663b12… lmata 68
b663b12… lmata 69 class TestContextBundleDict:
b663b12… lmata 70 def test_structure(self):
b663b12… lmata 71 b = _make_bundle()
b663b12… lmata 72 d = b.to_dict()
b663b12… lmata 73 assert d["target"]["name"] == "get_user"
b663b12… lmata 74 assert len(d["nodes"]) == 2
b663b12… lmata 75 assert len(d["edges"]) == 1
b663b12… lmata 76 assert d["metadata"]["query"] == "function_context"
b663b12… lmata 77
b663b12… lmata 78 def test_roundtrip(self):
b663b12… lmata 79 b = _make_bundle()
b663b12… lmata 80 d = b.to_dict()
b663b12… lmata 81 assert d["target"]["type"] == "Function"
b663b12… lmata 82 assert d["nodes"][0]["name"] == "validate_token"
b663b12… lmata 83
b663b12… lmata 84
b663b12… lmata 85 # ── ContextBundle.to_json ─────────────────────────────────────────────────────
b663b12… lmata 86
b663b12… lmata 87 class TestContextBundleJson:
b663b12… lmata 88 def test_valid_json(self):
b663b12… lmata 89 b = _make_bundle()
b663b12… lmata 90 data = json.loads(b.to_json())
b663b12… lmata 91 assert data["target"]["name"] == "get_user"
b663b12… lmata 92
b663b12… lmata 93 def test_indent(self):
b663b12… lmata 94 b = _make_bundle()
b663b12… lmata 95 raw = b.to_json(indent=4)
b663b12… lmata 96 assert " " in raw # 4-space indent
b663b12… lmata 97
b663b12… lmata 98
b663b12… lmata 99 # ── ContextBundle.to_markdown ─────────────────────────────────────────────────
b663b12… lmata 100
b663b12… lmata 101 class TestContextBundleMarkdown:
b663b12… lmata 102 def test_contains_name(self):
b663b12… lmata 103 b = _make_bundle()
b663b12… lmata 104 md = b.to_markdown()
b663b12… lmata 105 assert "get_user" in md
b663b12… lmata 106
b663b12… lmata 107 def test_contains_edge(self):
b663b12… lmata 108 md = _make_bundle().to_markdown()
b663b12… lmata 109 assert "CALLS" in md
b663b12… lmata 110 assert "validate_token" in md
b663b12… lmata 111
b663b12… lmata 112 def test_contains_docstring(self):
b663b12… lmata 113 md = _make_bundle().to_markdown()
b663b12… lmata 114 assert "Return a user by ID." in md
b663b12… lmata 115
b663b12… lmata 116 def test_contains_signature(self):
b663b12… lmata 117 md = _make_bundle().to_markdown()
b663b12… lmata 118 assert "def get_user" in md
b663b12… lmata 119
b663b12… lmata 120 def test_knowledge_bundle(self):
b663b12… lmata 121 md = _make_knowledge_bundle().to_markdown()
b663b12… lmata 122 assert "JWT" in md
b663b12… lmata 123 assert "auth" in md
b663b12… lmata 124 assert "GOVERNS" in md
b663b12… lmata 125
b663b12… lmata 126 def test_empty_nodes(self):
b663b12… lmata 127 target = ContextNode(type="File", name="empty.py", file_path="empty.py")
b663b12… lmata 128 b = ContextBundle(target=target)
b663b12… lmata 129 md = b.to_markdown()
b663b12… lmata 130 assert "empty.py" in md
b663b12… lmata 131
b663b12… lmata 132
b663b12… lmata 133 # ── ContextLoader ─────────────────────────────────────────────────────────────
b663b12… lmata 134
b663b12… lmata 135 class TestContextLoaderFile:
b663b12… lmata 136 def test_load_file_empty(self):
b663b12… lmata 137 store = _mock_store([])
b663b12… lmata 138 loader = ContextLoader(store)
b663b12… lmata 139 bundle = loader.load_file("src/auth.py")
b663b12… lmata 140 assert bundle.target.name == "auth.py"
b663b12… lmata 141 assert bundle.target.type == "File"
b663b12… lmata 142 assert bundle.nodes == []
b663b12… lmata 143
b663b12… lmata 144 def test_load_file_with_rows(self):
b663b12… lmata 145 rows = [["Function", "get_user", 10, "Get a user", "def get_user()"]]
b663b12… lmata 146 store = _mock_store(rows)
b663b12… lmata 147 loader = ContextLoader(store)
b663b12… lmata 148 bundle = loader.load_file("src/auth.py")
b663b12… lmata 149 assert len(bundle.nodes) == 1
b663b12… lmata 150 assert bundle.nodes[0].name == "get_user"
b663b12… lmata 151 assert bundle.nodes[0].type == "Function"
b663b12… lmata 152
b663b12… lmata 153
b663b12… lmata 154 class TestContextLoaderFunction:
b663b12… lmata 155 def test_load_function_no_results(self):
b663b12… lmata 156 store = _mock_store([])
b663b12… lmata 157 loader = ContextLoader(store)
b663b12… lmata 158 bundle = loader.load_function("get_user", file_path="src/auth.py")
b663b12… lmata 159 assert bundle.target.name == "get_user"
b663b12… lmata 160 assert bundle.nodes == []
b663b12… lmata 161 assert bundle.edges == []
b663b12… lmata 162
b663b12… lmata 163 def test_load_function_with_callee(self):
b663b12… lmata 164 def side_effect(query, params):
b663b12… lmata 165 result = MagicMock()
b663b12… lmata 166 if "CALLEES" in query or "callee" in query.lower():
b663b12… lmata 167 result.result_set = [["Function", "validate_token", "src/auth.py", 5]]
b663b12… lmata 168 elif "CALLERS" in query or "caller" in query.lower():
b663b12… lmata 169 result.result_set = []
b663b12… lmata 170 else:
b663b12… lmata 171 result.result_set = []
b663b12… lmata 172 return result
b663b12… lmata 173
b663b12… lmata 174 store = MagicMock()
b663b12… lmata 175 store.query.side_effect = side_effect
b663b12… lmata 176 loader = ContextLoader(store)
b663b12… lmata 177 loader.load_function("get_user")
b663b12… lmata 178 # Should have called query multiple times
b663b12… lmata 179 assert store.query.called
b663b12… lmata 180
b663b12… lmata 181 def test_load_function_default_file_path(self):
b663b12… lmata 182 store = _mock_store([])
b663b12… lmata 183 loader = ContextLoader(store)
b663b12… lmata 184 bundle = loader.load_function("foo")
b663b12… lmata 185 assert bundle.target.file_path == ""
b663b12… lmata 186
b663b12… lmata 187
b663b12… lmata 188 class TestContextLoaderClass:
b663b12… lmata 189 def test_load_class_empty(self):
b663b12… lmata 190 store = _mock_store([])
b663b12… lmata 191 loader = ContextLoader(store)
b663b12… lmata 192 bundle = loader.load_class("AuthService")
b663b12… lmata 193 assert bundle.target.name == "AuthService"
b663b12… lmata 194 assert bundle.target.type == "Class"
b663b12… lmata 195
b663b12… lmata 196 def test_load_class_with_parent(self):
b663b12… lmata 197 call_count = [0]
b663b12… lmata 198
b663b12… lmata 199 def side_effect(query, params=None):
b663b12… lmata 200 result = MagicMock()
b663b12… lmata 201 call_count[0] += 1
b663b12… lmata 202 if call_count[0] == 1:
b663b12… lmata 203 result.result_set = [["BaseService", "src/base.py"]]
b663b12… lmata 204 else:
b663b12… lmata 205 result.result_set = []
b663b12… lmata 206 return result
b663b12… lmata 207
b663b12… lmata 208 store = MagicMock()
b663b12… lmata 209 store.query.side_effect = side_effect
b663b12… lmata 210 loader = ContextLoader(store)
b663b12… lmata 211 bundle = loader.load_class("AuthService")
b663b12… lmata 212 assert len(bundle.nodes) >= 1
b663b12… lmata 213
b663b12… lmata 214
b663b12… lmata 215 class TestContextLoaderExplain:
b663b12… lmata 216 def test_explain_empty(self):
b663b12… lmata 217 store = _mock_store([])
b663b12… lmata 218 loader = ContextLoader(store)
b663b12… lmata 219 bundle = loader.explain("get_user")
b663b12… lmata 220 assert bundle.target.name == "get_user"
b663b12… lmata 221 assert bundle.metadata["query"] == "explain"
b663b12… lmata 222
b663b12… lmata 223
b663b12… lmata 224 class TestContextLoaderSearch:
b663b12… lmata 225 def test_search_empty(self):
b663b12… lmata 226 store = _mock_store([])
b663b12… lmata 227 loader = ContextLoader(store)
b663b12… lmata 228 results = loader.search("auth")
b663b12… lmata 229 assert results == []
b663b12… lmata 230
b663b12… lmata 231 def test_search_returns_nodes(self):
b663b12… lmata 232 rows = [["Function", "authenticate", "src/auth.py", 10, "Authenticate a user"]]
b663b12… lmata 233 store = _mock_store(rows)
b663b12… lmata 234 loader = ContextLoader(store)
b663b12… lmata 235 results = loader.search("auth")
b663b12… lmata 236 assert len(results) == 1
b663b12… lmata 237 assert results[0].name == "authenticate"
b663b12… lmata 238 assert results[0].type == "Function"
b663b12… lmata 239
b663b12… lmata 240 def test_search_all(self):
b663b12… lmata 241 rows = [["Concept", "Authentication", "", None, "The auth concept"]]
b663b12… lmata 242 store = _mock_store(rows)
b663b12… lmata 243 loader = ContextLoader(store)
b663b12… lmata 244 results = loader.search_all("auth")
b663b12… lmata 245 assert len(results) == 1
b663b12… lmata 246
b663b12… lmata 247 def test_search_by_docstring(self):
b663b12… lmata 248 rows = [["Function", "login", "src/auth.py", 5, "Log in a user"]]
b663b12… lmata 249 store = _mock_store(rows)
b663b12… lmata 250 loader = ContextLoader(store)
b663b12… lmata 251 results = loader.search_by_docstring("log in")
b663b12… lmata 252 assert len(results) == 1
b663b12… lmata 253
b663b12… lmata 254 def test_decorated_by(self):
b663b12… lmata 255 rows = [["Function", "protected_view", "src/views.py", 20]]
b663b12… lmata 256 store = _mock_store(rows)
b663b12… lmata 257 loader = ContextLoader(store)
b663b12… lmata 258 results = loader.decorated_by("login_required")
b663b12… lmata 259 assert len(results) == 1
b663b12… lmata 260 assert results[0].name == "protected_view"
b663b12… lmata 261
b663b12… lmata 262
b663b12… lmata 263 class TestContextLoaderConcept:
b663b12… lmata 264 def test_load_concept_not_found(self):
b663b12… lmata 265 store = _mock_store([])
b663b12… lmata 266 loader = ContextLoader(store)
b663b12… lmata 267 bundle = loader.load_concept("Unknown")
b663b12… lmata 268 assert bundle.metadata.get("found") is False
b663b12… lmata 269
b663b12… lmata 270 def test_load_concept_found(self):
b663b12… lmata 271 rows = [["JWT", "Stateless token auth", "active", "auth", [], [], [], []]]
b663b12… lmata 272 store = _mock_store(rows)
b663b12… lmata 273 loader = ContextLoader(store)
b663b12… lmata 274 bundle = loader.load_concept("JWT")
b663b12… lmata 275 assert bundle.target.name == "JWT"
b663b12… lmata 276 assert bundle.target.description == "Stateless token auth"
b663b12… lmata 277
b663b12… lmata 278 def test_load_domain(self):
b663b12… lmata 279 rows = [["Function", "login", "src/auth.py", "Log in"]]
b663b12… lmata 280 store = _mock_store(rows)
b663b12… lmata 281 loader = ContextLoader(store)
b663b12… lmata 282 bundle = loader.load_domain("auth")
b663b12… lmata 283 assert bundle.target.name == "auth"
b663b12… lmata 284 assert bundle.target.type == "Domain"
7ae0080… lmata 285
7ae0080… lmata 286
7ae0080… lmata 287 # ── to_markdown with status and node docstrings ───────────────────────────────
7ae0080… lmata 288
7ae0080… lmata 289 class TestContextBundleMarkdownBranches:
7ae0080… lmata 290 def test_markdown_includes_status(self):
7ae0080… lmata 291 target = ContextNode(type="Concept", name="JWT", status="active")
7ae0080… lmata 292 b = ContextBundle(target=target)
7ae0080… lmata 293 md = b.to_markdown()
7ae0080… lmata 294 assert "active" in md
7ae0080… lmata 295
7ae0080… lmata 296 def test_markdown_node_with_docstring(self):
7ae0080… lmata 297 target = ContextNode(type="File", name="app.py", file_path="app.py")
7ae0080… lmata 298 node = ContextNode(type="Function", name="foo", file_path="app.py",
7ae0080… lmata 299 docstring="Does something useful.")
7ae0080… lmata 300 b = ContextBundle(target=target, nodes=[node])
7ae0080… lmata 301 md = b.to_markdown()
7ae0080… lmata 302 assert "Does something useful." in md
7ae0080… lmata 303
7ae0080… lmata 304 def test_markdown_node_with_description_fallback(self):
7ae0080… lmata 305 target = ContextNode(type="Concept", name="JWT")
7ae0080… lmata 306 node = ContextNode(type="Rule", name="must_expire",
7ae0080… lmata 307 description="Tokens must expire.")
7ae0080… lmata 308 b = ContextBundle(target=target, nodes=[node])
7ae0080… lmata 309 md = b.to_markdown()
7ae0080… lmata 310 assert "Tokens must expire." in md
7ae0080… lmata 311
7ae0080… lmata 312
7ae0080… lmata 313 # ── load_function with callers and decorators ─────────────────────────────────
7ae0080… lmata 314
7ae0080… lmata 315 class TestContextLoaderFunctionBranches:
7ae0080… lmata 316 def test_load_function_with_callers(self):
7ae0080… lmata 317 call_count = [0]
7ae0080… lmata 318
7ae0080… lmata 319 def side_effect(query, params):
7ae0080… lmata 320 result = MagicMock()
7ae0080… lmata 321 call_count[0] += 1
7ae0080… lmata 322 if call_count[0] == 1:
7ae0080… lmata 323 result.result_set = [] # callees empty
7ae0080… lmata 324 elif call_count[0] == 2:
7ae0080… lmata 325 result.result_set = [["Function", "caller_fn", "src/x.py", 5]]
7ae0080… lmata 326 else:
7ae0080… lmata 327 result.result_set = [] # decorators empty
7ae0080… lmata 328 return result
7ae0080… lmata 329
7ae0080… lmata 330 store = MagicMock()
7ae0080… lmata 331 store.query.side_effect = side_effect
7ae0080… lmata 332 loader = ContextLoader(store)
7ae0080… lmata 333 bundle = loader.load_function("get_user", file_path="src/auth.py")
7ae0080… lmata 334 assert any(n.name == "caller_fn" for n in bundle.nodes)
7ae0080… lmata 335 assert any(e["type"] == "CALLS" for e in bundle.edges)
7ae0080… lmata 336
7ae0080… lmata 337 def test_load_function_with_decorators(self):
7ae0080… lmata 338 call_count = [0]
7ae0080… lmata 339
7ae0080… lmata 340 def side_effect(query, params):
7ae0080… lmata 341 result = MagicMock()
7ae0080… lmata 342 call_count[0] += 1
7ae0080… lmata 343 if call_count[0] <= 2:
7ae0080… lmata 344 result.result_set = [] # callees and callers empty
7ae0080… lmata 345 else:
7ae0080… lmata 346 result.result_set = [["login_required", "src/decorators.py"]]
7ae0080… lmata 347 return result
7ae0080… lmata 348
7ae0080… lmata 349 store = MagicMock()
7ae0080… lmata 350 store.query.side_effect = side_effect
7ae0080… lmata 351 loader = ContextLoader(store)
7ae0080… lmata 352 bundle = loader.load_function("my_view", file_path="src/views.py")
7ae0080… lmata 353 assert any(n.name == "login_required" for n in bundle.nodes)
7ae0080… lmata 354
7ae0080… lmata 355
7ae0080… lmata 356 # ── load_class with subs and refs ─────────────────────────────────────────────
7ae0080… lmata 357
7ae0080… lmata 358 class TestContextLoaderClassBranches:
7ae0080… lmata 359 def test_load_class_with_subclasses(self):
7ae0080… lmata 360 call_count = [0]
7ae0080… lmata 361
7ae0080… lmata 362 def side_effect(query, params):
7ae0080… lmata 363 result = MagicMock()
7ae0080… lmata 364 call_count[0] += 1
7ae0080… lmata 365 if call_count[0] == 1:
7ae0080… lmata 366 result.result_set = [] # parents empty
7ae0080… lmata 367 elif call_count[0] == 2:
7ae0080… lmata 368 result.result_set = [["ChildService", "src/child.py"]]
7ae0080… lmata 369 else:
7ae0080… lmata 370 result.result_set = [] # refs empty
7ae0080… lmata 371 return result
7ae0080… lmata 372
7ae0080… lmata 373 store = MagicMock()
7ae0080… lmata 374 store.query.side_effect = side_effect
7ae0080… lmata 375 loader = ContextLoader(store)
7ae0080… lmata 376 bundle = loader.load_class("BaseService")
7ae0080… lmata 377 assert any(n.name == "ChildService" for n in bundle.nodes)
7ae0080… lmata 378 assert any(e["type"] == "INHERITS" for e in bundle.edges)
7ae0080… lmata 379
7ae0080… lmata 380 def test_load_class_with_references(self):
7ae0080… lmata 381 call_count = [0]
7ae0080… lmata 382
7ae0080… lmata 383 def side_effect(query, params):
7ae0080… lmata 384 result = MagicMock()
7ae0080… lmata 385 call_count[0] += 1
7ae0080… lmata 386 if call_count[0] <= 2:
7ae0080… lmata 387 result.result_set = [] # parents and subs empty
7ae0080… lmata 388 else:
7ae0080… lmata 389 result.result_set = [["Function", "use_service", "src/x.py", 10]]
7ae0080… lmata 390 return result
7ae0080… lmata 391
7ae0080… lmata 392 store = MagicMock()
7ae0080… lmata 393 store.query.side_effect = side_effect
7ae0080… lmata 394 loader = ContextLoader(store)
7ae0080… lmata 395 bundle = loader.load_class("AuthService")
7ae0080… lmata 396 assert any(n.name == "use_service" for n in bundle.nodes)
7ae0080… lmata 397
7ae0080… lmata 398
7ae0080… lmata 399 # ── explain with data ─────────────────────────────────────────────────────────
7ae0080… lmata 400
7ae0080… lmata 401 class TestContextLoaderExplainBranches:
7ae0080… lmata 402 def test_explain_with_outbound_data(self):
7ae0080… lmata 403 call_count = [0]
7ae0080… lmata 404
7ae0080… lmata 405 def side_effect(query, params):
7ae0080… lmata 406 result = MagicMock()
7ae0080… lmata 407 call_count[0] += 1
7ae0080… lmata 408 if call_count[0] == 1:
7ae0080… lmata 409 result.result_set = [["CALLS", "Function", "helper", "src/utils.py"]]
7ae0080… lmata 410 else:
7ae0080… lmata 411 result.result_set = []
7ae0080… lmata 412 return result
7ae0080… lmata 413
7ae0080… lmata 414 store = MagicMock()
7ae0080… lmata 415 store.query.side_effect = side_effect
7ae0080… lmata 416 loader = ContextLoader(store)
7ae0080… lmata 417 bundle = loader.explain("main_fn")
7ae0080… lmata 418 assert any(n.name == "helper" for n in bundle.nodes)
7ae0080… lmata 419 assert any(e["type"] == "CALLS" for e in bundle.edges)
7ae0080… lmata 420
7ae0080… lmata 421 def test_explain_with_inbound_data(self):
7ae0080… lmata 422 call_count = [0]
7ae0080… lmata 423
7ae0080… lmata 424 def side_effect(query, params):
7ae0080… lmata 425 result = MagicMock()
7ae0080… lmata 426 call_count[0] += 1
7ae0080… lmata 427 if call_count[0] == 1:
7ae0080… lmata 428 result.result_set = []
7ae0080… lmata 429 else:
7ae0080… lmata 430 result.result_set = [["CALLS", "Function", "caller", "src/main.py"]]
7ae0080… lmata 431 return result
7ae0080… lmata 432
7ae0080… lmata 433 store = MagicMock()
7ae0080… lmata 434 store.query.side_effect = side_effect
7ae0080… lmata 435 loader = ContextLoader(store)
7ae0080… lmata 436 bundle = loader.explain("helper_fn")
7ae0080… lmata 437 assert any(n.name == "caller" for n in bundle.nodes)
7ae0080… lmata 438
7ae0080… lmata 439
7ae0080… lmata 440 # ── load_concept with populated related nodes ─────────────────────────────────
7ae0080… lmata 441
7ae0080… lmata 442 class TestContextLoaderConceptBranches:
7ae0080… lmata 443 def test_load_concept_with_related_concepts_rules_wiki_implements(self):
7ae0080… lmata 444 rows = [[
7ae0080… lmata 445 "JWT",
7ae0080… lmata 446 "Stateless token auth",
7ae0080… lmata 447 "active",
7ae0080… lmata 448 "auth",
7ae0080… lmata 449 ["OAuth"], # related concepts
7ae0080… lmata 450 ["Tokens must expire"], # rules
7ae0080… lmata 451 ["Auth Overview"], # wiki pages
7ae0080… lmata 452 ["validate_token"], # implementing code
7ae0080… lmata 453 ]]
7ae0080… lmata 454 store = _mock_store(rows)
7ae0080… lmata 455 loader = ContextLoader(store)
7ae0080… lmata 456 bundle = loader.load_concept("JWT")
7ae0080… lmata 457 names = {n.name for n in bundle.nodes}
7ae0080… lmata 458 assert "OAuth" in names
7ae0080… lmata 459 assert "Tokens must expire" in names
7ae0080… lmata 460 assert "Auth Overview" in names
7ae0080… lmata 461 assert "validate_token" in names
7ae0080… lmata 462 types = {e["type"] for e in bundle.edges}
7ae0080… lmata 463 assert "RELATED_TO" in types
7ae0080… lmata 464 assert "GOVERNS" in types
7ae0080… lmata 465 assert "DOCUMENTS" in types
7ae0080… lmata 466 assert "IMPLEMENTS" in types
ece88ca… lmata 467
ece88ca… lmata 468
ece88ca… lmata 469 # ── load_decision ───────────────────────────────────────────────────────────
ece88ca… lmata 470
ece88ca… lmata 471 class TestContextLoaderDecision:
ece88ca… lmata 472 def test_load_decision_not_found(self):
ece88ca… lmata 473 store = _mock_store([])
ece88ca… lmata 474 loader = ContextLoader(store)
ece88ca… lmata 475 bundle = loader.load_decision("Nonexistent")
ece88ca… lmata 476 assert bundle.metadata.get("found") is False
ece88ca… lmata 477 assert bundle.target.type == "Decision"
ece88ca… lmata 478
ece88ca… lmata 479 def test_load_decision_found(self):
ece88ca… lmata 480 rows = [[
ece88ca… lmata 481 "Use FalkorDB",
ece88ca… lmata 482 "Graph DB for navegador",
ece88ca… lmata 483 "Cypher queries, SQLite backend",
ece88ca… lmata 484 "Neo4j, ArangoDB",
ece88ca… lmata 485 "accepted",
ece88ca… lmata 486 "2026-03-01",
ece88ca… lmata 487 "infrastructure",
ece88ca… lmata 488 [], # documents
ece88ca… lmata 489 [], # decided_by
ece88ca… lmata 490 [], # domains
ece88ca… lmata 491 ]]
ece88ca… lmata 492 store = _mock_store(rows)
ece88ca… lmata 493 loader = ContextLoader(store)
ece88ca… lmata 494 bundle = loader.load_decision("Use FalkorDB")
ece88ca… lmata 495 assert bundle.target.name == "Use FalkorDB"
ece88ca… lmata 496 assert bundle.target.rationale == "Cypher queries, SQLite backend"
ece88ca… lmata 497 assert bundle.target.alternatives == "Neo4j, ArangoDB"
ece88ca… lmata 498 assert bundle.target.status == "accepted"
ece88ca… lmata 499
ece88ca… lmata 500 def test_load_decision_with_related_nodes(self):
ece88ca… lmata 501 rows = [[
ece88ca… lmata 502 "Use FalkorDB",
ece88ca… lmata 503 "Graph DB",
ece88ca… lmata 504 "Cypher",
ece88ca… lmata 505 "Neo4j",
ece88ca… lmata 506 "accepted",
ece88ca… lmata 507 "2026-03-01",
ece88ca… lmata 508 "infra",
ece88ca… lmata 509 ["GraphStore"], # documents
ece88ca… lmata 510 ["Alice"], # decided_by
ece88ca… lmata 511 ["infrastructure"], # domains
ece88ca… lmata 512 ]]
ece88ca… lmata 513 store = _mock_store(rows)
ece88ca… lmata 514 loader = ContextLoader(store)
ece88ca… lmata 515 bundle = loader.load_decision("Use FalkorDB")
ece88ca… lmata 516 names = {n.name for n in bundle.nodes}
ece88ca… lmata 517 assert "GraphStore" in names
ece88ca… lmata 518 assert "Alice" in names
ece88ca… lmata 519 edge_types = {e["type"] for e in bundle.edges}
ece88ca… lmata 520 assert "DOCUMENTS" in edge_types
ece88ca… lmata 521 assert "DECIDED_BY" in edge_types
ece88ca… lmata 522
ece88ca… lmata 523
ece88ca… lmata 524 # ── find_owners ──────────────────────────────────────────────────────────────
ece88ca… lmata 525
ece88ca… lmata 526 class TestContextLoaderFindOwners:
ece88ca… lmata 527 def test_find_owners_empty(self):
ece88ca… lmata 528 store = _mock_store([])
ece88ca… lmata 529 loader = ContextLoader(store)
ece88ca… lmata 530 results = loader.find_owners("AuthService")
ece88ca… lmata 531 assert results == []
ece88ca… lmata 532
ece88ca… lmata 533 def test_find_owners_returns_people(self):
ece88ca… lmata 534 rows = [["Class", "AuthService", "Alice", "[email protected]", "lead", "auth"]]
ece88ca… lmata 535 store = _mock_store(rows)
ece88ca… lmata 536 loader = ContextLoader(store)
ece88ca… lmata 537 results = loader.find_owners("AuthService")
ece88ca… lmata 538 assert len(results) == 1
ece88ca… lmata 539 assert results[0].name == "Alice"
ece88ca… lmata 540 assert results[0].type == "Person"
ece88ca… lmata 541
ece88ca… lmata 542 def test_find_owners_passes_file_path(self):
ece88ca… lmata 543 store = _mock_store([])
ece88ca… lmata 544 loader = ContextLoader(store)
ece88ca… lmata 545 loader.find_owners("foo", file_path="src/foo.py")
ece88ca… lmata 546 store.query.assert_called_once()
ece88ca… lmata 547 args = store.query.call_args
ece88ca… lmata 548 assert args[0][1]["file_path"] == "src/foo.py"
ece88ca… lmata 549
ece88ca… lmata 550
ece88ca… lmata 551 # ── search_knowledge ────────────────────────────────────────────────────────
ece88ca… lmata 552
ece88ca… lmata 553 class TestContextLoaderSearchKnowledge:
ece88ca… lmata 554 def test_search_knowledge_empty(self):
ece88ca… lmata 555 store = _mock_store([])
ece88ca… lmata 556 loader = ContextLoader(store)
ece88ca… lmata 557 results = loader.search_knowledge("xyz")
ece88ca… lmata 558 assert results == []
ece88ca… lmata 559
ece88ca… lmata 560 def test_search_knowledge_returns_nodes(self):
ece88ca… lmata 561 rows = [["Concept", "JWT", "Stateless token auth", "auth", "active"]]
ece88ca… lmata 562 store = _mock_store(rows)
ece88ca… lmata 563 loader = ContextLoader(store)
ece88ca… lmata 564 results = loader.search_knowledge("JWT")
ece88ca… lmata 565 assert len(results) == 1
ece88ca… lmata 566 assert results[0].name == "JWT"
ece88ca… lmata 567 assert results[0].type == "Concept"
ece88ca… lmata 568 assert results[0].domain == "auth"
ece88ca… lmata 569
ece88ca… lmata 570 def test_search_knowledge_passes_limit(self):
ece88ca… lmata 571 store = _mock_store([])
ece88ca… lmata 572 loader = ContextLoader(store)
ece88ca… lmata 573 loader.search_knowledge("auth", limit=5)
ece88ca… lmata 574 args = store.query.call_args
ece88ca… lmata 575 assert args[0][1]["limit"] == 5

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button