import pytest
import os
import tempfile
from pathlib import Path
def test_import():
import loregrep
assert hasattr(loregrep, 'LoreGrep')
assert hasattr(loregrep, 'LoreGrepBuilder')
assert hasattr(loregrep, 'ScanResult')
assert hasattr(loregrep, 'ToolResult')
assert hasattr(loregrep, 'ToolSchema')
assert hasattr(loregrep, 'IndexCoverage')
def test_builder_creation():
import loregrep
builder = loregrep.LoreGrep.builder()
assert builder is not None
def test_builder_configuration():
import loregrep
builder = (loregrep.LoreGrep.builder()
.with_rust_analyzer() .with_python_analyzer() .optimize_for_performance() .exclude_test_dirs() .max_file_size(1024 * 1024) .max_depth(10)
.file_patterns(["*.py", "*.rs", "*.js"])
.exclude_patterns(["target/", "node_modules/"])
.respect_gitignore(True))
assert builder is not None
def test_loregrep_build():
import loregrep
loregrep_instance = (loregrep.LoreGrep.builder()
.max_file_size(1024 * 1024)
.max_depth(5)
.file_patterns(["*.py"])
.build())
assert loregrep_instance is not None
def test_enhanced_api_methods():
import loregrep
try:
auto_instance = loregrep.LoreGrep.auto_discover(".")
assert auto_instance is not None
except Exception:
pass
presets = [
loregrep.LoreGrep.rust_project,
loregrep.LoreGrep.python_project,
loregrep.LoreGrep.polyglot_project,
]
preset_successes = 0
for preset_func in presets:
try:
preset_instance = preset_func(".")
assert preset_instance is not None
preset_successes += 1
except Exception:
pass
assert preset_successes >= 0
def test_enhanced_builder_methods():
import loregrep
try:
enhanced_instance = (loregrep.LoreGrep.builder()
.with_all_analyzers()
.comprehensive_analysis()
.exclude_vendor_dirs()
.include_source_files()
.include_config_files()
.build())
assert enhanced_instance is not None
except Exception:
builder = loregrep.LoreGrep.builder()
try:
builder.with_all_analyzers()
builder.comprehensive_analysis()
builder.exclude_vendor_dirs()
builder.include_source_files()
builder.include_config_files()
except AttributeError:
pytest.fail("Enhanced builder methods should exist")
except Exception:
pass
@pytest.mark.asyncio
async def test_basic_scanning():
import loregrep
with tempfile.TemporaryDirectory() as temp_dir:
test_file = Path(temp_dir) / "test.py"
test_file.write_text("""
def hello_world():
'''A simple hello world function.'''
print("Hello, World!")
return "greeting"
class TestClass:
'''A simple test class.'''
def __init__(self):
self.value = 42
def get_value(self):
return self.value
""")
loregrep_instance = (loregrep.LoreGrep.builder()
.with_python_analyzer()
.max_file_size(1024 * 1024)
.file_patterns(["*.py"])
.build())
try:
result = await loregrep_instance.scan(temp_dir)
assert hasattr(result, 'files_scanned') assert hasattr(result, 'functions_found')
assert hasattr(result, 'structs_found')
assert hasattr(result, 'duration_ms')
assert result.files_scanned >= 1
except Exception as e:
pytest.skip(f"Scanning test skipped due to: {e}")
def test_tool_definitions():
import loregrep
tools = loregrep.LoreGrep.get_tool_definitions()
assert isinstance(tools, list)
if len(tools) > 0:
tool = tools[0]
assert hasattr(tool, 'name')
assert hasattr(tool, 'description')
assert hasattr(tool, 'parameters')
assert isinstance(tool.name, str)
assert isinstance(tool.description, str)
def test_version_access():
import loregrep
version = loregrep.LoreGrep.version()
assert isinstance(version, str)
assert len(version) > 0
def test_package_metadata():
import loregrep
assert hasattr(loregrep, '__version__')
assert hasattr(loregrep, '__author__')
assert isinstance(loregrep.__version__, str)
assert isinstance(loregrep.__author__, str)
def test_version_has_single_source_of_truth():
import loregrep
assert loregrep.__version__ == loregrep.LoreGrep.version()
assert loregrep.__version__ == loregrep.loregrep.__version__
init_source = Path(loregrep.__file__).read_text()
assert '__version__ = "' not in init_source
assert "__version__ = '" not in init_source
def test_builder_direct_construction():
import loregrep
builder = loregrep.LoreGrepBuilder()
assert builder is not None
assert builder.max_depth(3).build() is not None
def test_builder_full_surface():
import loregrep
instance = (loregrep.LoreGrep.builder()
.with_rust_analyzer()
.with_python_analyzer()
.with_typescript_analyzer()
.with_all_analyzers()
.configure_patterns_for_languages(["rust", "python"])
.include_patterns(["*.py", "*.rs"])
.file_patterns(["*.py", "*.rs"])
.exclude_patterns(["target/"])
.max_files(1000)
.max_file_size(1024 * 1024)
.max_depth(5)
.unlimited_depth()
.follow_symlinks(False)
.respect_gitignore(True)
.optimize_for_performance()
.comprehensive_analysis()
.exclude_common_build_dirs()
.exclude_test_dirs()
.exclude_vendor_dirs()
.include_source_files()
.include_config_files()
.build())
assert instance is not None
def _python_repo(tmp_path: Path, count: int = 3) -> Path:
for i in range(count):
(tmp_path / f"mod_{i}.py").write_text(
f"def fn_{i}():\n return {i}\n\n\nclass Cls_{i}:\n pass\n"
)
return tmp_path
@pytest.mark.asyncio
async def test_index_lifecycle_methods():
import loregrep
with tempfile.TemporaryDirectory() as temp_dir:
repo = _python_repo(Path(temp_dir))
lg = (loregrep.LoreGrep.builder()
.with_python_analyzer()
.file_patterns(["*.py"])
.build())
assert lg.is_scanned() is False
result = await lg.scan(str(repo))
assert result.files_scanned == 3
assert isinstance(result.languages, list)
assert lg.is_scanned() is True
stats = lg.get_stats()
assert stats.files_scanned == result.files_scanned
assert stats.functions_found == result.functions_found
assert stats.structs_found == result.structs_found
assert stats.duration_ms == 0
assert lg.first_missing_indexed_path() is None
(repo / "mod_0.py").unlink()
assert lg.first_missing_indexed_path() is not None
lg.set_scan_root(str(repo))
lg.clear_index()
assert lg.is_scanned() is False
assert lg.get_stats().files_scanned == 0
@pytest.mark.asyncio
async def test_index_coverage_reports_truncation():
import loregrep
with tempfile.TemporaryDirectory() as temp_dir:
repo = _python_repo(Path(temp_dir), count=5)
full = (loregrep.LoreGrep.builder()
.with_python_analyzer()
.file_patterns(["*.py"])
.build())
await full.scan(str(repo))
coverage = full.index_coverage()
assert coverage.truncated is False
assert coverage.note is None
assert coverage.files_indexed == coverage.files_discovered == 5
limited = (loregrep.LoreGrep.builder()
.with_python_analyzer()
.file_patterns(["*.py"])
.max_files(2)
.build())
await limited.scan(str(repo))
coverage = limited.index_coverage()
assert coverage.truncated is True
assert coverage.files_indexed == 2
assert coverage.files_discovered == 5
assert isinstance(coverage.note, str) and coverage.note
if __name__ == "__main__":
pytest.main([__file__])