81 lines
3.7 KiB
Python
81 lines
3.7 KiB
Python
import contextlib
|
|
import io
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
import fast_source_search as search
|
|
|
|
|
|
class FastSourceSearchTests(unittest.TestCase):
|
|
def setUp(self):
|
|
self.temp = tempfile.TemporaryDirectory()
|
|
self.addCleanup(self.temp.cleanup)
|
|
self.root = Path(self.temp.name)
|
|
self.batch = self.root / "batch.json"
|
|
self.real_rg = shutil.which("rg")
|
|
self.enterContext(patch.object(search, "ROOT", self.root))
|
|
self.enterContext(patch.object(search, "BATCH", self.batch))
|
|
self.enterContext(patch.dict(os.environ, {"FREECAD_REAL_RG": self.real_rg, "FREECAD_SOURCE_BUDGET_MARKER": ""}))
|
|
|
|
def file(self, name, content="needle\n"):
|
|
target = self.root / name
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_text(content)
|
|
return target
|
|
|
|
def test_batch_resolves_both_repository_and_desktop_source_paths(self):
|
|
web = self.file("web/src/techdraw.worker.ts")
|
|
native = self.file("freecad-source/src/Mod/TechDraw/App/DrawPage.cpp")
|
|
tool = self.file("tools/cases.mjs")
|
|
self.batch.write_text(json.dumps({"records": [["a", "b", "c", p] for p in [
|
|
"web/src/techdraw.worker.ts", "src/Mod/TechDraw/App/DrawPage.cpp", "tools/cases.mjs", "../../outside.cpp",
|
|
]]}))
|
|
self.assertEqual(search.batch_paths(), sorted([web, native, tool]))
|
|
|
|
def test_scoped_search_bypasses_scheduler_wrapper_and_does_not_omit_late_files(self):
|
|
wrapper = self.file("tools/scheduler-bin/rg", "#!/bin/sh\nexit 2\n")
|
|
wrapper.chmod(0o755)
|
|
for index in range(205):
|
|
self.file(f"web/src/a{index:03}.ts", "irrelevant\n")
|
|
target = self.file("web/src/techdraw.worker.ts")
|
|
output = io.StringIO()
|
|
with patch.dict(os.environ, {"PATH": str(wrapper.parent) + os.pathsep + os.environ["PATH"]}), patch(
|
|
"sys.argv", ["fast_source_search.py", "needle", "--path", "web/src"]
|
|
), contextlib.redirect_stdout(output), contextlib.redirect_stderr(io.StringIO()):
|
|
self.assertEqual(search.main(), 0)
|
|
self.assertIn(str(target), output.getvalue())
|
|
with patch.dict(os.environ, {"FREECAD_REAL_RG": ""}):
|
|
self.assertNotEqual(search.ripgrep(), str(wrapper))
|
|
|
|
def test_oversized_scope_is_reported_instead_of_silently_truncated(self):
|
|
self.file("web/a.ts")
|
|
self.file("web/z.ts")
|
|
with self.assertRaisesRegex(SystemExit, "narrower --path"):
|
|
search.list_source_files(self.root / "web", limit=1)
|
|
|
|
def test_named_pattern_uses_existing_scoped_file(self):
|
|
target = self.file("web/src/draft.ts")
|
|
output = io.StringIO()
|
|
with patch("sys.argv", ["fast_source_search.py", "--pattern", "needle", "--path", "web/src/draft.ts"]), \
|
|
contextlib.redirect_stdout(output), contextlib.redirect_stderr(io.StringIO()):
|
|
self.assertEqual(search.main(), 0)
|
|
self.assertIn(str(target), output.getvalue())
|
|
|
|
def test_isolated_packet_search_includes_native_support_paths(self):
|
|
worker = self.file("web/src/draft.worker.ts", "dispatch(request)\n")
|
|
native = self.file("freecad-source/src/WebAssembly/Draft.cpp", "draft.formatBatch\n")
|
|
self.batch.write_text(json.dumps({"records": [["Draft:format", "format", "pending", "web/src/draft.worker.ts"]],
|
|
"sourcePaths": ["freecad-source/src/WebAssembly/Draft.cpp", "../outside.cpp"]}))
|
|
self.assertEqual(search.batch_paths(), sorted([worker, native]))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|