11"""Unit tests for file search middleware."""
22
3- from pathlib import Path
4- from typing import Any
5-
6- import pytest
7-
83from langchain_anthropic .middleware .anthropic_tools import AnthropicToolsState
94from langchain_anthropic .middleware .file_search import (
10- FilesystemFileSearchMiddleware ,
115 StateFileSearchMiddleware ,
126)
137
@@ -56,7 +50,7 @@ def test_glob_basic_pattern(self) -> None:
5650 }
5751
5852 # Call tool function directly (state is injected in real usage)
59- result = middleware .glob_search .func (pattern = "*.py" , state = test_state )
53+ result = middleware .glob_search .func (pattern = "*.py" , state = test_state ) # type: ignore[attr-defined]
6054
6155 assert isinstance (result , str )
6256 assert "/src/main.py" in result
@@ -88,7 +82,7 @@ def test_glob_recursive_pattern(self) -> None:
8882 },
8983 }
9084
91- result = middleware .glob_search .func (pattern = "**/*.py" , state = state )
85+ result = middleware .glob_search .func (pattern = "**/*.py" , state = state ) # type: ignore[attr-defined]
9286
9387 assert isinstance (result , str )
9488 lines = result .split ("\n " )
@@ -115,7 +109,7 @@ def test_glob_with_base_path(self) -> None:
115109 },
116110 }
117111
118- result = middleware .glob_search .func (
112+ result = middleware .glob_search .func ( # type: ignore[attr-defined]
119113 pattern = "**/*.py" , path = "/src" , state = state
120114 )
121115
@@ -138,7 +132,7 @@ def test_glob_no_matches(self) -> None:
138132 },
139133 }
140134
141- result = middleware .glob_search .func (pattern = "*.ts" , state = state )
135+ result = middleware .glob_search .func (pattern = "*.ts" , state = state ) # type: ignore[attr-defined]
142136
143137 assert isinstance (result , str )
144138 assert result == "No files found"
@@ -163,7 +157,7 @@ def test_glob_sorts_by_modified_time(self) -> None:
163157 },
164158 }
165159
166- result = middleware .glob_search .func (pattern = "*.py" , state = state )
160+ result = middleware .glob_search .func (pattern = "*.py" , state = state ) # type: ignore[attr-defined]
167161
168162 lines = result .split ("\n " )
169163 # Most recent first
@@ -199,7 +193,7 @@ def test_grep_files_with_matches_mode(self) -> None:
199193 },
200194 }
201195
202- result = middleware .grep_search .func (pattern = r"def \w+\(\):" , state = state )
196+ result = middleware .grep_search .func (pattern = r"def \w+\(\):" , state = state ) # type: ignore[attr-defined]
203197
204198 assert isinstance (result , str )
205199 assert "/src/main.py" in result
@@ -222,7 +216,7 @@ def test_grep_invalid_include_pattern(self) -> None:
222216 },
223217 }
224218
225- result = middleware .grep_search .func (
219+ result = middleware .grep_search .func ( # type: ignore[attr-defined]
226220 pattern = r"def" , include = "*.{py" , state = state
227221 )
228222
@@ -232,53 +226,6 @@ def test_grep_invalid_include_pattern(self) -> None:
232226class TestFilesystemGrepSearch :
233227 """Tests for filesystem-backed grep search."""
234228
235- def test_grep_invalid_include_pattern (self , tmp_path : Path ) -> None :
236- """Return error when include glob cannot be parsed."""
237-
238- (tmp_path / "example.py" ).write_text ("print('hello')\n " , encoding = "utf-8" )
239-
240- middleware = FilesystemFileSearchMiddleware (
241- root_path = str (tmp_path ), use_ripgrep = False
242- )
243-
244- result = middleware .grep_search .func (pattern = "print" , include = "*.{py" )
245-
246- assert result == "Invalid include pattern"
247-
248- def test_ripgrep_command_uses_literal_pattern (
249- self , tmp_path : Path , monkeypatch : pytest .MonkeyPatch
250- ) -> None :
251- """Ensure ripgrep receives pattern after ``--`` to avoid option parsing."""
252-
253- (tmp_path / "example.py" ).write_text ("print('hello')\n " , encoding = "utf-8" )
254-
255- middleware = FilesystemFileSearchMiddleware (
256- root_path = str (tmp_path ), use_ripgrep = True
257- )
258-
259- captured : dict [str , list [str ]] = {}
260-
261- class DummyResult :
262- stdout = ""
263-
264- def fake_run (* args : Any , ** kwargs : Any ) -> DummyResult :
265- cmd = args [0 ]
266- captured ["cmd" ] = cmd
267- return DummyResult ()
268-
269- monkeypatch .setattr (
270- "langchain_anthropic.middleware.file_search.subprocess.run" , fake_run
271- )
272-
273- middleware ._ripgrep_search ("--pattern" , "/" , None )
274-
275- assert "cmd" in captured
276- cmd = captured ["cmd" ]
277- assert cmd [:2 ] == ["rg" , "--json" ]
278- assert "--" in cmd
279- separator_index = cmd .index ("--" )
280- assert cmd [separator_index + 1 ] == "--pattern"
281-
282229 def test_grep_content_mode (self ) -> None :
283230 """Test grep with content output mode."""
284231 middleware = StateFileSearchMiddleware ()
@@ -294,7 +241,7 @@ def test_grep_content_mode(self) -> None:
294241 },
295242 }
296243
297- result = middleware .grep_search .func (
244+ result = middleware .grep_search .func ( # type: ignore[attr-defined]
298245 pattern = r"def \w+\(\):" , output_mode = "content" , state = state
299246 )
300247
@@ -324,7 +271,7 @@ def test_grep_count_mode(self) -> None:
324271 },
325272 }
326273
327- result = middleware .grep_search .func (
274+ result = middleware .grep_search .func ( # type: ignore[attr-defined]
328275 pattern = r"TODO" , output_mode = "count" , state = state
329276 )
330277
@@ -353,7 +300,7 @@ def test_grep_with_include_filter(self) -> None:
353300 },
354301 }
355302
356- result = middleware .grep_search .func (
303+ result = middleware .grep_search .func ( # type: ignore[attr-defined]
357304 pattern = "import" , include = "*.py" , state = state
358305 )
359306
@@ -386,7 +333,7 @@ def test_grep_with_brace_expansion_filter(self) -> None:
386333 },
387334 }
388335
389- result = middleware .grep_search .func (
336+ result = middleware .grep_search .func ( # type: ignore[attr-defined]
390337 pattern = "const" , include = "*.{ts,tsx}" , state = state
391338 )
392339
@@ -415,7 +362,7 @@ def test_grep_with_base_path(self) -> None:
415362 },
416363 }
417364
418- result = middleware .grep_search .func (pattern = "import" , path = "/src" , state = state )
365+ result = middleware .grep_search .func (pattern = "import" , path = "/src" , state = state ) # type: ignore[attr-defined]
419366
420367 assert isinstance (result , str )
421368 assert "/src/main.py" in result
@@ -436,7 +383,7 @@ def test_grep_no_matches(self) -> None:
436383 },
437384 }
438385
439- result = middleware .grep_search .func (pattern = r"TODO" , state = state )
386+ result = middleware .grep_search .func (pattern = r"TODO" , state = state ) # type: ignore[attr-defined]
440387
441388 assert isinstance (result , str )
442389 assert result == "No matches found"
@@ -450,7 +397,7 @@ def test_grep_invalid_regex(self) -> None:
450397 "text_editor_files" : {},
451398 }
452399
453- result = middleware .grep_search .func (pattern = r"[unclosed" , state = state )
400+ result = middleware .grep_search .func (pattern = r"[unclosed" , state = state ) # type: ignore[attr-defined]
454401
455402 assert isinstance (result , str )
456403 assert "Invalid regex pattern" in result
@@ -481,7 +428,7 @@ def test_glob_default_backend(self) -> None:
481428 },
482429 }
483430
484- result = middleware .glob_search .func (pattern = "**/*" , state = state )
431+ result = middleware .glob_search .func (pattern = "**/*" , state = state ) # type: ignore[attr-defined]
485432
486433 assert isinstance (result , str )
487434 assert "/src/main.py" in result
@@ -510,7 +457,7 @@ def test_grep_default_backend(self) -> None:
510457 },
511458 }
512459
513- result = middleware .grep_search .func (pattern = r"TODO" , state = state )
460+ result = middleware .grep_search .func (pattern = r"TODO" , state = state ) # type: ignore[attr-defined]
514461
515462 assert isinstance (result , str )
516463 assert "/src/main.py" in result
@@ -539,7 +486,7 @@ def test_search_with_single_store(self) -> None:
539486 },
540487 }
541488
542- result = middleware .grep_search .func (pattern = r".*" , state = state )
489+ result = middleware .grep_search .func (pattern = r".*" , state = state ) # type: ignore[attr-defined]
543490
544491 assert isinstance (result , str )
545492 assert "/src/main.py" in result
0 commit comments