Spaces:
Build error
Build error
| """ | |
| Dev B Test Suite - Run with: .venv/Scripts/python test_devb.py | |
| """ | |
| import asyncio | |
| import sys | |
| sys.path.insert(0, '.') | |
| from app.llm import generate_documentation, synthesize_answer, get_embedding | |
| from app.vectorstore import init_vectorstore, add_embedding, search, count_embeddings, delete_by_project | |
| # Test counters | |
| passed = 0 | |
| failed = 0 | |
| def test(name, condition, details=""): | |
| global passed, failed | |
| if condition: | |
| print(f" [PASS] {name}") | |
| passed += 1 | |
| else: | |
| print(f" [FAIL] {name} - {details}") | |
| failed += 1 | |
| async def test_llm(): | |
| print("\n[1/4] Testing LLM Client (llm.py)") | |
| print("-" * 40) | |
| # Test 1: get_embedding | |
| try: | |
| emb = await get_embedding("test embedding") | |
| test("get_embedding returns list", isinstance(emb, list)) | |
| test("get_embedding returns 768 dims", len(emb) == 768, f"got {len(emb)}") | |
| test("get_embedding returns floats", isinstance(emb[0], float)) | |
| except Exception as e: | |
| test("get_embedding", False, str(e)) | |
| # Test 2: generate_documentation | |
| try: | |
| doc = await generate_documentation( | |
| task_title="Setup API", | |
| what_i_did="Created REST endpoints", | |
| code_snippet="@app.get('/api')" | |
| ) | |
| test("generate_documentation returns dict", isinstance(doc, dict)) | |
| test("generate_documentation has summary", "summary" in doc) | |
| test("generate_documentation has details", "details" in doc) | |
| test("generate_documentation has tags", "tags" in doc and isinstance(doc["tags"], list)) | |
| except Exception as e: | |
| test("generate_documentation", False, str(e)) | |
| # Test 3: synthesize_answer | |
| try: | |
| answer = await synthesize_answer( | |
| context="Task completed: Built login system with JWT authentication", | |
| query="What authentication was implemented?" | |
| ) | |
| test("synthesize_answer returns string", isinstance(answer, str)) | |
| test("synthesize_answer not empty", len(answer) > 0) | |
| except Exception as e: | |
| test("synthesize_answer", False, str(e)) | |
| async def test_vectorstore(): | |
| print("\n[2/4] Testing Vector Store (vectorstore.py)") | |
| print("-" * 40) | |
| # Test 1: init_vectorstore | |
| try: | |
| init_vectorstore() | |
| test("init_vectorstore succeeds", True) | |
| except Exception as e: | |
| test("init_vectorstore", False, str(e)) | |
| return # Can't continue without init | |
| # Clean up test data first | |
| try: | |
| delete_by_project("test-project-xyz") | |
| except: | |
| pass | |
| # Test 2: add_embedding | |
| try: | |
| emb = await get_embedding("Test document about Python programming") | |
| add_embedding( | |
| log_entry_id="test-entry-1", | |
| text="Test document about Python programming", | |
| embedding=emb, | |
| metadata={ | |
| "project_id": "test-project-xyz", | |
| "user_id": "test-user", | |
| "task_id": "test-task", | |
| "created_at": "2024-01-01T00:00:00" | |
| } | |
| ) | |
| test("add_embedding succeeds", True) | |
| except Exception as e: | |
| test("add_embedding", False, str(e)) | |
| # Test 3: count_embeddings | |
| try: | |
| count = count_embeddings("test-project-xyz") | |
| test("count_embeddings returns int", isinstance(count, int)) | |
| test("count_embeddings >= 1", count >= 1, f"got {count}") | |
| except Exception as e: | |
| test("count_embeddings", False, str(e)) | |
| # Test 4: search | |
| try: | |
| query_emb = await get_embedding("Python") | |
| results = search(query_emb, "test-project-xyz", n_results=5) | |
| test("search returns list", isinstance(results, list)) | |
| test("search finds results", len(results) > 0, "no results found") | |
| if results: | |
| test("search result has id", "id" in results[0]) | |
| test("search result has metadata", "metadata" in results[0]) | |
| test("search result has distance", "distance" in results[0]) | |
| except Exception as e: | |
| test("search", False, str(e)) | |
| # Test 5: delete_by_project | |
| try: | |
| delete_by_project("test-project-xyz") | |
| count_after = count_embeddings("test-project-xyz") | |
| test("delete_by_project removes data", count_after == 0, f"still has {count_after}") | |
| except Exception as e: | |
| test("delete_by_project", False, str(e)) | |
| async def test_full_pipeline(): | |
| print("\n[3/4] Testing Full Pipeline") | |
| print("-" * 40) | |
| project_id = "pipeline-test-proj" | |
| # Clean up first | |
| try: | |
| delete_by_project(project_id) | |
| except: | |
| pass | |
| try: | |
| # Step 1: Generate documentation | |
| doc = await generate_documentation( | |
| task_title="Implement user registration", | |
| what_i_did="Added signup endpoint with email validation and password hashing", | |
| code_snippet="def register(email, password): ..." | |
| ) | |
| test("Pipeline: doc generation", "summary" in doc and "details" in doc) | |
| # Step 2: Create embedding from doc | |
| text_to_embed = f"{doc['summary']} {doc['details']}" | |
| embedding = await get_embedding(text_to_embed) | |
| test("Pipeline: embedding created", len(embedding) == 768) | |
| # Step 3: Store in vectorstore | |
| add_embedding( | |
| log_entry_id="pipeline-log-1", | |
| text=text_to_embed, | |
| embedding=embedding, | |
| metadata={"project_id": project_id, "user_id": "dev1"} | |
| ) | |
| test("Pipeline: stored in vectorstore", count_embeddings(project_id) == 1) | |
| # Step 4: Search for it | |
| query_emb = await get_embedding("user registration signup") | |
| results = search(query_emb, project_id) | |
| test("Pipeline: search finds it", len(results) > 0) | |
| # Step 5: Synthesize answer | |
| if results: | |
| context = results[0]["metadata"]["text"] | |
| answer = await synthesize_answer(context, "What was done for user registration?") | |
| test("Pipeline: answer synthesized", len(answer) > 20) | |
| # Cleanup | |
| delete_by_project(project_id) | |
| except Exception as e: | |
| test("Pipeline", False, str(e)) | |
| async def test_edge_cases(): | |
| print("\n[4/4] Testing Edge Cases") | |
| print("-" * 40) | |
| # Test empty search | |
| try: | |
| init_vectorstore() | |
| emb = await get_embedding("random query") | |
| results = search(emb, "nonexistent-project-12345") | |
| test("Empty search returns empty list", results == []) | |
| except Exception as e: | |
| test("Empty search", False, str(e)) | |
| # Test long text embedding | |
| try: | |
| long_text = "word " * 1000 # ~5000 chars | |
| emb = await get_embedding(long_text) | |
| test("Long text embedding works", len(emb) == 768) | |
| except Exception as e: | |
| test("Long text embedding", False, str(e)) | |
| # Test special characters | |
| try: | |
| special_text = "Code: `const x = 'hello';` // comment <script>alert('xss')</script>" | |
| emb = await get_embedding(special_text) | |
| test("Special chars embedding works", len(emb) == 768) | |
| except Exception as e: | |
| test("Special chars embedding", False, str(e)) | |
| async def main(): | |
| print("=" * 50) | |
| print(" DEV B TEST SUITE - Intelligence Layer") | |
| print("=" * 50) | |
| await test_llm() | |
| await test_vectorstore() | |
| await test_full_pipeline() | |
| await test_edge_cases() | |
| print("\n" + "=" * 50) | |
| print(f" RESULTS: {passed} passed, {failed} failed") | |
| print("=" * 50) | |
| if failed > 0: | |
| sys.exit(1) | |
| if __name__ == "__main__": | |
| asyncio.run(main()) | |