"""Robot Framework helper for repo indexing CLI integration tests. Provides end-to-end test scenarios that exercise the RepoIndexingService and CLI wiring together, using an in-memory SQLite database. """ from __future__ import annotations import tempfile from pathlib import Path from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from cleveragents.application.services.repo_indexing_service import ( RepoIndexingService, ) from cleveragents.application.services.resource_registry_service import ( ResourceRegistryService, ) from cleveragents.infrastructure.database.models import Base def _make_services() -> tuple[ResourceRegistryService, RepoIndexingService]: """Create fresh services backed by an in-memory database.""" engine = create_engine("sqlite:///:memory:", echo=False) Base.metadata.create_all(engine) factory = sessionmaker(bind=engine, expire_on_commit=False) resource_svc = ResourceRegistryService(session_factory=factory) resource_svc.bootstrap_builtin_types() indexing_svc = RepoIndexingService(session_factory=factory) return resource_svc, indexing_svc def test_e2e_add_index_status() -> str: """End-to-end: add resource -> index -> check status.""" resource_svc, indexing_svc = _make_services() # Create a temp directory with sample files tmp_dir = tempfile.mkdtemp() readme = Path(tmp_dir) / "README.md" readme.write_text("# Test\nSample content.\n") main_py = Path(tmp_dir) / "main.py" main_py.write_text("print('hello')\n") # Register resource resource = resource_svc.register_resource( type_name="git-checkout", name="local/e2e-repo", location=tmp_dir, properties={"path": tmp_dir}, ) # Index repo_index = indexing_svc.index_resource(resource.resource_id, tmp_dir) assert repo_index.metadata.status.value == "ready" assert repo_index.metadata.file_count >= 2 # Check status status = indexing_svc.get_index_status(resource.resource_id) assert status is not None assert status.status.value == "ready" assert status.file_count == repo_index.metadata.file_count return "E2E add-index-status PASSED" def test_incremental_reindex_after_change() -> str: """Incremental re-index after file change.""" resource_svc, indexing_svc = _make_services() tmp_dir = tempfile.mkdtemp() readme = Path(tmp_dir) / "README.md" readme.write_text("# Original\n") resource = resource_svc.register_resource( type_name="git-checkout", name="local/incr-repo", location=tmp_dir, properties={"path": tmp_dir}, ) # Initial index idx1 = indexing_svc.index_resource(resource.resource_id, tmp_dir) count1 = idx1.metadata.file_count # Add a new file new_file = Path(tmp_dir) / "app.py" new_file.write_text("x = 1\n") # Incremental refresh idx2 = indexing_svc.refresh_index(resource.resource_id, tmp_dir) assert idx2.metadata.file_count == count1 + 1 assert idx2.metadata.status.value == "ready" return "Incremental reindex PASSED" def test_full_reindex() -> str: """Full re-index replaces the entire index.""" resource_svc, indexing_svc = _make_services() tmp_dir = tempfile.mkdtemp() readme = Path(tmp_dir) / "README.md" readme.write_text("# Test\n") resource = resource_svc.register_resource( type_name="git-checkout", name="local/full-repo", location=tmp_dir, properties={"path": tmp_dir}, ) # Initial index idx1 = indexing_svc.index_resource(resource.resource_id, tmp_dir) # Full re-index idx2 = indexing_svc.index_resource(resource.resource_id, tmp_dir) assert idx2.metadata.status.value == "ready" assert idx2.metadata.file_count == idx1.metadata.file_count return "Full reindex PASSED" def test_status_no_index() -> str: """Status returns None when no index exists.""" resource_svc, indexing_svc = _make_services() tmp_dir = tempfile.mkdtemp() resource = resource_svc.register_resource( type_name="git-checkout", name="local/no-index-repo", location=tmp_dir, properties={"path": tmp_dir}, ) status = indexing_svc.get_index_status(resource.resource_id) assert status is None return "Status no-index PASSED" def test_remove_index() -> str: """Remove index cleans up all data.""" resource_svc, indexing_svc = _make_services() tmp_dir = tempfile.mkdtemp() readme = Path(tmp_dir) / "README.md" readme.write_text("# Test\n") resource = resource_svc.register_resource( type_name="git-checkout", name="local/remove-repo", location=tmp_dir, properties={"path": tmp_dir}, ) indexing_svc.index_resource(resource.resource_id, tmp_dir) assert indexing_svc.get_index_status(resource.resource_id) is not None removed = indexing_svc.remove_index(resource.resource_id) assert removed is True assert indexing_svc.get_index_status(resource.resource_id) is None return "Remove index PASSED" if __name__ == "__main__": import sys _dispatch = { "e2e": test_e2e_add_index_status, "incremental": test_incremental_reindex_after_change, "full": test_full_reindex, "no-index": test_status_no_index, "remove": test_remove_index, } if len(sys.argv) < 2 or sys.argv[1] not in _dispatch: # Run all tests for fn in _dispatch.values(): print(fn()) else: print(_dispatch[sys.argv[1]]())