Files
FreeCADWasmDev/tools/test_fast_source_search.py
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

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()