@@ -65,7 +65,18 @@ def session(self):
6565 return self ._session
6666
6767
68- def _make_graph_builder (session : Optional [_RecordingSession ] = None ):
68+ class _FakeDBManager :
69+ """Minimal stub that satisfies GraphWriter's backend detection."""
70+
71+ def __init__ (self , backend : str = "neo4j" ):
72+ self ._backend = backend
73+
74+ def get_backend_type (self ) -> str :
75+ return self ._backend
76+
77+
78+ def _make_graph_builder (session : Optional [_RecordingSession ] = None ,
79+ backend : str = "neo4j" ):
6980 """Return a GraphBuilder with a fake driver. Skips full __init__ setup."""
7081 from codegraphcontext .tools .graph_builder import GraphBuilder
7182 from codegraphcontext .tools .indexing .persistence .writer import GraphWriter
@@ -74,7 +85,8 @@ def _make_graph_builder(session: Optional[_RecordingSession] = None):
7485 if session is None :
7586 session = _RecordingSession ()
7687 gb .driver = _FakeDriver (session )
77- gb ._writer = GraphWriter (gb .driver )
88+ dm = _FakeDBManager (backend )
89+ gb ._writer = GraphWriter (gb .driver , db_manager = dm )
7890 gb .parsers = {}
7991 return gb , session
8092
@@ -527,10 +539,13 @@ def test_non_javascript_import_rows_are_schema_complete(self):
527539# ---------------------------------------------------------------------------
528540
529541class _DeleteRepoSession (_RecordingSession ):
530- """RecordingSession that intercepts `CALL db.labels()` queries and
542+ """RecordingSession that intercepts label-discovery queries and
531543 returns a fixed label list without consuming a slot in the responses
532544 queue, so positional fixtures stay focused on deletion counts and
533- aren't disturbed by the new label-discovery query in the implementation."""
545+ aren't disturbed by the label-discovery query in the implementation.
546+
547+ Supports both Neo4j (``CALL db.labels()``) and KuzuDB/LadybugDB
548+ (``MATCH (n) RETURN DISTINCT label(n)``) discovery patterns."""
534549
535550 def __init__ (self , labels , responses = None ):
536551 super ().__init__ (responses = responses )
@@ -540,6 +555,8 @@ def run(self, query: str, **kwargs):
540555 self .calls .append ({"query" : query , "kwargs" : kwargs })
541556 if "db.labels()" in query :
542557 return _FakeResult ([{"label" : lbl } for lbl in self ._labels ])
558+ if "RETURN DISTINCT label(n)" in query :
559+ return _FakeResult ([[lbl ] for lbl in self ._labels ])
543560 if self ._call_idx < len (self ._responses ):
544561 result = self ._responses [self ._call_idx ]
545562 else :
@@ -685,46 +702,49 @@ def test_calls_db_labels_after_existence_check(self):
685702
686703 def test_finds_repo_stored_with_backslash_path (self ):
687704 """Fallback should find a Repository stored with Windows backslash paths."""
688- session = _DeleteRepoSession ( labels = self . _DEFAULT_DB_LABELS , responses = [
705+ session = _RecordingSession ( responses = [
689706 _FakeResult ([{"cnt" : 0 }]), # normalized (forward-slash) fails
690707 _FakeResult ([{"cnt" : 1 }]), # fallback (original backslash) succeeds
691- ] + [_FakeResult ([{"deleted" : 0 }])] * 20 )
708+ * ([_FakeResult ([{"deleted" : 0 }])] * 20 ), # drain loops
709+ ])
692710 gb , _ = _make_graph_builder (session )
693711 result = gb .delete_repository_from_graph ("C:\\ Users\\ test\\ repo" )
694712 assert result is True
695713
696- # Verify that fallback path was used for subsequent operations
697- # Should use backslash path prefix for STARTS WITH queries
698- assert any (c ["kwargs" ].get ("prefix" ) == "C:\\ Users\\ test\\ repo\\ " for c in session .calls ), \
699- "Expected backslash path prefix in STARTS WITH queries after fallback"
714+ # Verify that fallback path was used in subsequent parameterised queries.
715+ # The implementation uses $prefix / $path bindings, so we inspect kwargs
716+ # rather than the query string.
717+ prefix_values = [
718+ c ["kwargs" ].get ("prefix" , "" ) for c in session .calls
719+ if "STARTS WITH" in c ["query" ]
720+ ]
721+ assert any ("C:\\ Users\\ test\\ repo\\ " in p for p in prefix_values ), \
722+ f"Expected backslash path prefix in $prefix kwargs, got: { prefix_values } "
700723
701724 def test_uses_matching_path_format_for_deletion (self ):
702725 """When fallback triggers, deletion queries should use the path format that matched."""
703- session = _DeleteRepoSession ( labels = self . _DEFAULT_DB_LABELS , responses = [
726+ session = _RecordingSession ( responses = [
704727 _FakeResult ([{"cnt" : 0 }]), # normalized (forward-slash) fails
705728 _FakeResult ([{"cnt" : 1 }]), # fallback (original backslash) succeeds
706- ] + [_FakeResult ([{"deleted" : 0 }])] * 20 )
729+ * ([_FakeResult ([{"deleted" : 0 }])] * 20 ), # drain loops
730+ ])
707731 gb , _ = _make_graph_builder (session )
708732 gb .delete_repository_from_graph ("D:\\ WorkPlace\\ AI\\ MinerU\\ pipeline" )
709733
710- # Check that all deletion queries use the backslash path
734+ # Check that parameterised queries use backslash paths (not forward-slash).
735+ # The implementation passes paths via $prefix / $path bindings.
711736 for c in session .calls :
712- q = c ["query" ]
713- kwargs = c ["kwargs" ]
714- if "STARTS WITH" in q or "DETACH DELETE" in q :
715- # Should use backslash path, not forward-slash
716- prefix = kwargs .get ("prefix" )
717- path = kwargs .get ("path" )
718- if prefix :
719- assert "D:/WorkPlace/AI/MinerU/pipeline" not in prefix , \
720- "Should not use normalized forward-slash path after fallback"
721- assert "D:\\ WorkPlace\\ AI\\ MinerU\\ pipeline" in prefix or "D:\\ WorkPlace\\ AI\\ MinerU\\ pipeline\\ " in prefix , \
722- "Should use original backslash path after fallback"
723- if path :
724- assert "D:/WorkPlace/AI/MinerU/pipeline" not in path , \
725- "Should not use normalized forward-slash path after fallback"
726- assert "D:\\ WorkPlace\\ AI\\ MinerU\\ pipeline" in path , \
727- "Should use original backslash path after fallback"
737+ if "STARTS WITH" in c ["query" ] or "DETACH DELETE" in c ["query" ]:
738+ kwargs = c ["kwargs" ]
739+ for key in ("prefix" , "path" ):
740+ val = kwargs .get (key , "" )
741+ if val :
742+ assert "D:/WorkPlace/AI/MinerU/pipeline" not in val , \
743+ f"Should not use forward-slash path in ${ key } after fallback, got: { val } "
744+ assert (
745+ "D:\\ WorkPlace\\ AI\\ MinerU\\ pipeline" in val
746+ or "D:\\ WorkPlace\\ AI\\ MinerU\\ pipeline\\ " in val
747+ ), f"Should use backslash path in ${ key } , got: { val } "
728748
729749
730750# ---------------------------------------------------------------------------
0 commit comments