Skip to content

Commit 6e54901

Browse files
committed
test: add unit tests for cached site_packages path resolution
1 parent 4316780 commit 6e54901

1 file changed

Lines changed: 76 additions & 4 deletions

File tree

tests/test_code_utils.py

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import pytest
88

99
from codeflash.code_utils.code_utils import (
10+
_get_site_packages_paths,
1011
cleanup_paths,
1112
exit_with_message,
1213
file_name_from_test_module_name,
@@ -261,32 +262,39 @@ def test_get_run_tmp_file_reuses_temp_directory() -> None:
261262

262263

263264
def test_path_belongs_to_site_packages_with_site_package_path(monkeypatch: pytest.MonkeyPatch) -> None:
265+
_get_site_packages_paths.cache_clear()
264266
site_packages = [Path("/usr/local/lib/python3.9/site-packages").resolve()]
265267
monkeypatch.setattr(site, "getsitepackages", lambda: site_packages)
266268

267269
file_path = Path("/usr/local/lib/python3.9/site-packages/some_package")
268270
assert path_belongs_to_site_packages(file_path) is True
271+
_get_site_packages_paths.cache_clear()
269272

270273

271274
def test_path_belongs_to_site_packages_with_non_site_package_path(monkeypatch: pytest.MonkeyPatch) -> None:
275+
_get_site_packages_paths.cache_clear()
272276
site_packages = [Path("/usr/local/lib/python3.9/site-packages")]
273277
monkeypatch.setattr(site, "getsitepackages", lambda: site_packages)
274278

275279
file_path = Path("/usr/local/lib/python3.9/other_directory/some_package")
276280
assert path_belongs_to_site_packages(file_path) is False
281+
_get_site_packages_paths.cache_clear()
277282

278283

279284
def test_path_belongs_to_site_packages_with_relative_path(monkeypatch: pytest.MonkeyPatch) -> None:
285+
_get_site_packages_paths.cache_clear()
280286
site_packages = [Path("/usr/local/lib/python3.9/site-packages")]
281287
monkeypatch.setattr(site, "getsitepackages", lambda: site_packages)
282288

283289
file_path = Path("some_package")
284290
assert path_belongs_to_site_packages(file_path) is False
291+
_get_site_packages_paths.cache_clear()
285292

286293

287294
def test_path_belongs_to_site_packages_with_symlinked_site_packages(
288295
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
289296
) -> None:
297+
_get_site_packages_paths.cache_clear()
290298
real_site_packages = tmp_path / "real_site_packages"
291299
real_site_packages.mkdir()
292300

@@ -303,9 +311,11 @@ def test_path_belongs_to_site_packages_with_symlinked_site_packages(
303311

304312
symlinked_package_file = symlinked_site_packages / "some_package" / "__init__.py"
305313
assert path_belongs_to_site_packages(symlinked_package_file) is True
314+
_get_site_packages_paths.cache_clear()
306315

307316

308317
def test_path_belongs_to_site_packages_with_complex_symlinks(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
318+
_get_site_packages_paths.cache_clear()
309319
real_site_packages = tmp_path / "real" / "lib" / "python3.9" / "site-packages"
310320
real_site_packages.mkdir(parents=True)
311321

@@ -326,11 +336,13 @@ def test_path_belongs_to_site_packages_with_complex_symlinks(monkeypatch: pytest
326336

327337
file_via_links = site_packages_via_links / "test_package" / "module.py"
328338
assert path_belongs_to_site_packages(file_via_links) is True
339+
_get_site_packages_paths.cache_clear()
329340

330341

331342
def test_path_belongs_to_site_packages_resolved_paths_normalization(
332343
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
333344
) -> None:
345+
_get_site_packages_paths.cache_clear()
334346
site_packages_dir = tmp_path / "lib" / "python3.9" / "site-packages"
335347
site_packages_dir.mkdir(parents=True)
336348

@@ -346,6 +358,7 @@ def test_path_belongs_to_site_packages_resolved_paths_normalization(
346358

347359
complex_file_path = tmp_path / "lib" / "python3.9" / "site-packages" / "other" / ".." / "mypackage" / "module.py"
348360
assert path_belongs_to_site_packages(complex_file_path) is True
361+
_get_site_packages_paths.cache_clear()
349362

350363

351364
# tests for is_class_defined_in_file
@@ -380,7 +393,7 @@ def my_function():
380393

381394

382395
@pytest.fixture
383-
def mock_code_context():
396+
def mock_code_context() -> MagicMock:
384397
"""Mock CodeOptimizationContext for testing extract_dependent_function."""
385398
from unittest.mock import MagicMock
386399

@@ -391,7 +404,7 @@ def mock_code_context():
391404
return context
392405

393406

394-
def test_extract_dependent_function_sync_and_async(mock_code_context):
407+
def test_extract_dependent_function_sync_and_async(mock_code_context: MagicMock) -> None:
395408
"""Test extract_dependent_function with both sync and async functions."""
396409
# Test sync function extraction
397410
mock_code_context.testgen_context = CodeStringsMarkdown.parse_markdown_code("""```python:file.py
@@ -417,7 +430,7 @@ async def async_helper_function():
417430
assert extract_dependent_function("main_function", mock_code_context) == "async_helper_function"
418431

419432

420-
def test_extract_dependent_function_edge_cases(mock_code_context):
433+
def test_extract_dependent_function_edge_cases(mock_code_context: MagicMock) -> None:
421434
"""Test extract_dependent_function edge cases."""
422435
# No dependent functions
423436
mock_code_context.testgen_context = CodeStringsMarkdown.parse_markdown_code("""```python:file.py
@@ -441,7 +454,7 @@ async def helper2():
441454
assert extract_dependent_function("main_function", mock_code_context) is False
442455

443456

444-
def test_extract_dependent_function_mixed_scenarios(mock_code_context):
457+
def test_extract_dependent_function_mixed_scenarios(mock_code_context: MagicMock) -> None:
445458
"""Test extract_dependent_function with mixed sync/async scenarios."""
446459
# Async main with sync helper
447460
mock_code_context.testgen_context = CodeStringsMarkdown.parse_markdown_code("""```python:file.py
@@ -782,3 +795,62 @@ def test_no_xml_when_not_subagent(
782795
exit_with_message("Normal error", error_on_exit=True)
783796
captured = capsys.readouterr()
784797
assert "<codeflash-error>" not in captured.out
798+
799+
800+
def test_path_belongs_to_site_packages_true(tmp_path: Path) -> None:
801+
_get_site_packages_paths.cache_clear()
802+
site_packages_dir = (tmp_path / "lib" / "python3.9" / "site-packages").resolve()
803+
site_packages_dir.mkdir(parents=True)
804+
package_file = (site_packages_dir / "some_package" / "module.py")
805+
package_file.parent.mkdir()
806+
package_file.write_text("# module", encoding="utf-8")
807+
808+
with patch("codeflash.code_utils.code_utils.site.getsitepackages", return_value=[str(site_packages_dir)]):
809+
_get_site_packages_paths.cache_clear()
810+
assert path_belongs_to_site_packages(package_file.resolve()) is True
811+
_get_site_packages_paths.cache_clear()
812+
813+
814+
def test_path_belongs_to_site_packages_false(tmp_path: Path) -> None:
815+
_get_site_packages_paths.cache_clear()
816+
site_packages_dir = (tmp_path / "lib" / "python3.9" / "site-packages").resolve()
817+
site_packages_dir.mkdir(parents=True)
818+
other_dir = (tmp_path / "other" / "location").resolve()
819+
other_dir.mkdir(parents=True)
820+
other_file = other_dir / "module.py"
821+
other_file.write_text("# module", encoding="utf-8")
822+
823+
with patch("codeflash.code_utils.code_utils.site.getsitepackages", return_value=[str(site_packages_dir)]):
824+
_get_site_packages_paths.cache_clear()
825+
assert path_belongs_to_site_packages(other_file.resolve()) is False
826+
_get_site_packages_paths.cache_clear()
827+
828+
829+
def test_get_site_packages_paths_is_cached() -> None:
830+
_get_site_packages_paths.cache_clear()
831+
with patch("codeflash.code_utils.code_utils.site.getsitepackages", return_value=["/fake/site-packages"]) as mock_gsp:
832+
result1 = _get_site_packages_paths()
833+
result2 = _get_site_packages_paths()
834+
assert result1 == result2
835+
mock_gsp.assert_called_once()
836+
_get_site_packages_paths.cache_clear()
837+
838+
839+
def test_path_belongs_to_site_packages_with_symlink(tmp_path: Path) -> None:
840+
_get_site_packages_paths.cache_clear()
841+
real_site_packages = (tmp_path / "real_site_packages").resolve()
842+
real_site_packages.mkdir()
843+
package_file = real_site_packages / "pkg" / "mod.py"
844+
package_file.parent.mkdir()
845+
package_file.write_text("# mod", encoding="utf-8")
846+
847+
symlink_dir = tmp_path / "linked_site_packages"
848+
symlink_dir.symlink_to(real_site_packages)
849+
850+
with patch(
851+
"codeflash.code_utils.code_utils.site.getsitepackages", return_value=[str(real_site_packages)]
852+
):
853+
_get_site_packages_paths.cache_clear()
854+
symlinked_file = symlink_dir / "pkg" / "mod.py"
855+
assert path_belongs_to_site_packages(symlinked_file) is True
856+
_get_site_packages_paths.cache_clear()

0 commit comments

Comments
 (0)