From dd2869fd9897cb4d7e816f8c4df746a8721b1df9 Mon Sep 17 00:00:00 2001 From: Taylor Eernisse Date: Thu, 5 Feb 2026 00:04:39 -0500 Subject: [PATCH] test: Remove redundant comments from test files Applies the same doc comment cleanup to test files: - Removes test module headers (//! lines) - Removes obvious test function comments - Retains comments explaining non-obvious test scenarios Test names should be descriptive enough to convey intent without additional comments. Complex test setup or assertions that need explanation retain their comments. Co-Authored-By: Claude Opus 4.5 --- tests/diffnote_position_tests.rs | 21 +----------------- tests/embedding.rs | 37 -------------------------------- tests/fixture_tests.rs | 6 ------ tests/fts_search.rs | 19 ---------------- tests/golden_query_tests.rs | 29 +------------------------ tests/hybrid_search.rs | 18 +++------------- tests/migration_tests.rs | 21 ------------------ tests/mr_discussion_tests.rs | 4 +--- tests/mr_transformer_tests.rs | 10 +-------- 9 files changed, 7 insertions(+), 158 deletions(-) diff --git a/tests/diffnote_position_tests.rs b/tests/diffnote_position_tests.rs index c5cca1c..d0477a0 100644 --- a/tests/diffnote_position_tests.rs +++ b/tests/diffnote_position_tests.rs @@ -1,5 +1,3 @@ -//! Tests for DiffNote position extraction in note transformer. - use lore::gitlab::transformers::discussion::transform_notes_with_diff_position; use lore::gitlab::types::{ GitLabAuthor, GitLabDiscussion, GitLabLineRange, GitLabLineRangePoint, GitLabNote, @@ -60,8 +58,6 @@ fn make_discussion(notes: Vec) -> GitLabDiscussion { } } -// === DiffNote Position Field Extraction === - #[test] fn extracts_position_paths_from_diffnote() { let position = GitLabNotePosition { @@ -174,7 +170,7 @@ fn line_range_uses_old_line_fallback_when_new_line_missing() { line_code: None, line_type: Some("old".to_string()), old_line: Some(20), - new_line: None, // missing - should fall back to old_line + new_line: None, }, end: GitLabLineRangePoint { line_code: None, @@ -203,8 +199,6 @@ fn line_range_uses_old_line_fallback_when_new_line_missing() { assert_eq!(notes[0].position_line_range_end, Some(25)); } -// === Regular Notes (non-DiffNote) === - #[test] fn regular_note_has_none_for_all_position_fields() { let note = make_basic_note(1, "2024-01-16T09:00:00.000Z"); @@ -224,8 +218,6 @@ fn regular_note_has_none_for_all_position_fields() { assert_eq!(notes[0].position_head_sha, None); } -// === Strict Timestamp Parsing === - #[test] fn returns_error_for_invalid_created_at_timestamp() { let mut note = make_basic_note(1, "2024-01-16T09:00:00.000Z"); @@ -264,8 +256,6 @@ fn returns_error_for_invalid_resolved_at_timestamp() { assert!(result.is_err()); } -// === Mixed Discussion (DiffNote + Regular Notes) === - #[test] fn handles_mixed_diffnote_and_regular_notes() { let position = GitLabNotePosition { @@ -286,16 +276,12 @@ fn handles_mixed_diffnote_and_regular_notes() { let notes = transform_notes_with_diff_position(&discussion, 100).unwrap(); assert_eq!(notes.len(), 2); - // First note is DiffNote with position assert_eq!(notes[0].position_new_path, Some("file.rs".to_string())); assert_eq!(notes[0].position_new_line, Some(42)); - // Second note is regular with None position fields assert_eq!(notes[1].position_new_path, None); assert_eq!(notes[1].position_new_line, None); } -// === Position Preservation === - #[test] fn preserves_note_position_index() { let pos1 = GitLabNotePosition { @@ -330,11 +316,8 @@ fn preserves_note_position_index() { assert_eq!(notes[1].position, 1); } -// === Edge Cases === - #[test] fn handles_diffnote_with_empty_position_fields() { - // DiffNote exists but all position fields are None let position = GitLabNotePosition { old_path: None, new_path: None, @@ -351,7 +334,6 @@ fn handles_diffnote_with_empty_position_fields() { let notes = transform_notes_with_diff_position(&discussion, 100).unwrap(); - // All position fields should be None, not cause an error assert_eq!(notes[0].position_old_path, None); assert_eq!(notes[0].position_new_path, None); } @@ -376,6 +358,5 @@ fn handles_file_position_type() { assert_eq!(notes[0].position_type, Some("file".to_string())); assert_eq!(notes[0].position_new_path, Some("binary.bin".to_string())); - // File-level comments have no line numbers assert_eq!(notes[0].position_new_line, None); } diff --git a/tests/embedding.rs b/tests/embedding.rs index 97b66c9..651abef 100644 --- a/tests/embedding.rs +++ b/tests/embedding.rs @@ -1,16 +1,8 @@ -//! Integration tests for embedding storage and vector search. -//! -//! These tests create an in-memory SQLite database with sqlite-vec loaded, -//! apply all migrations through 010 (chunk config), and verify KNN search -//! and metadata operations. - use lore::core::db::create_connection; use rusqlite::Connection; use std::path::PathBuf; use tempfile::TempDir; -/// Create a test DB on disk (required for sqlite-vec which needs the extension loaded). -/// Uses create_connection to get the sqlite-vec extension registered. fn create_test_db() -> (TempDir, Connection) { let tmp = TempDir::new().unwrap(); let db_path = tmp.path().join("test.db"); @@ -35,7 +27,6 @@ fn create_test_db() -> (TempDir, Connection) { .unwrap_or_else(|e| panic!("Migration {} failed: {}", version, e)); } - // Seed a project conn.execute( "INSERT INTO projects (id, gitlab_project_id, path_with_namespace) VALUES (1, 100, 'group/project')", [], @@ -54,7 +45,6 @@ fn insert_document(conn: &Connection, id: i64, title: &str, content: &str) { .unwrap(); } -/// Create a 768-dim vector with a specific dimension set to 1.0 (unit vector along axis). fn axis_vector(dim: usize) -> Vec { let mut v = vec![0.0f32; 768]; v[dim] = 1.0; @@ -89,12 +79,10 @@ fn knn_search_returns_nearest_neighbors() { insert_document(&conn, 2, "Doc B", "Content about database optimization."); insert_document(&conn, 3, "Doc C", "Content about logging infrastructure."); - // Doc 1: axis 0, Doc 2: axis 1, Doc 3: axis 2 insert_embedding(&conn, 1, 0, &axis_vector(0)); insert_embedding(&conn, 2, 0, &axis_vector(1)); insert_embedding(&conn, 3, 0, &axis_vector(2)); - // Query vector close to axis 0 (should match doc 1) let mut query = vec![0.0f32; 768]; query[0] = 0.9; query[1] = 0.1; @@ -132,7 +120,6 @@ fn knn_search_deduplicates_chunks() { "Very long content that was chunked.", ); - // Same document, two chunks, both similar to query let mut v1 = vec![0.0f32; 768]; v1[0] = 1.0; let mut v2 = vec![0.0f32; 768]; @@ -144,7 +131,6 @@ fn knn_search_deduplicates_chunks() { let results = lore::search::search_vector(&conn, &axis_vector(0), 10).unwrap(); - // Should deduplicate: same document_id appears at most once let unique_docs: std::collections::HashSet = results.iter().map(|r| r.document_id).collect(); assert_eq!( @@ -161,7 +147,6 @@ fn orphan_trigger_deletes_embeddings_on_document_delete() { insert_document(&conn, 1, "Will be deleted", "Content."); insert_embedding(&conn, 1, 0, &axis_vector(0)); - // Verify embedding exists let count: i64 = conn .query_row( "SELECT COUNT(*) FROM embeddings WHERE rowid = 1000", @@ -171,11 +156,9 @@ fn orphan_trigger_deletes_embeddings_on_document_delete() { .unwrap(); assert_eq!(count, 1, "Embedding should exist before delete"); - // Delete the document conn.execute("DELETE FROM documents WHERE id = 1", []) .unwrap(); - // Verify embedding was cascade-deleted via trigger let count: i64 = conn .query_row( "SELECT COUNT(*) FROM embeddings WHERE rowid = 1000", @@ -188,7 +171,6 @@ fn orphan_trigger_deletes_embeddings_on_document_delete() { "Trigger should delete embeddings when document is deleted" ); - // Verify metadata was cascade-deleted via FK let meta_count: i64 = conn .query_row( "SELECT COUNT(*) FROM embedding_metadata WHERE document_id = 1", @@ -207,19 +189,12 @@ fn empty_database_returns_no_results() { assert!(results.is_empty(), "Empty DB should return no results"); } -// --- Bug-fix regression tests --- - #[test] fn overflow_doc_with_error_sentinel_not_re_detected_as_pending() { - // Bug 2: Documents skipped for chunk overflow must record a sentinel error - // in embedding_metadata so they are not re-detected as pending on subsequent - // pipeline runs (which would cause an infinite re-processing loop). let (_tmp, conn) = create_test_db(); insert_document(&conn, 1, "Overflow doc", "Some content"); - // Simulate what the pipeline does when a document exceeds CHUNK_ROWID_MULTIPLIER: - // it records an error sentinel at chunk_index=0. let now = chrono::Utc::now().timestamp_millis(); conn.execute( "INSERT INTO embedding_metadata @@ -230,7 +205,6 @@ fn overflow_doc_with_error_sentinel_not_re_detected_as_pending() { ) .unwrap(); - // Now find_pending_documents should NOT return this document let pending = lore::embedding::find_pending_documents(&conn, 100, 0, "nomic-embed-text").unwrap(); assert!( @@ -239,7 +213,6 @@ fn overflow_doc_with_error_sentinel_not_re_detected_as_pending() { pending.len() ); - // count_pending_documents should also return 0 let count = lore::embedding::count_pending_documents(&conn, "nomic-embed-text").unwrap(); assert_eq!( count, 0, @@ -249,11 +222,8 @@ fn overflow_doc_with_error_sentinel_not_re_detected_as_pending() { #[test] fn count_and_find_pending_agree() { - // Bug 1: count_pending_documents and find_pending_documents must use - // logically equivalent WHERE clauses to produce consistent results. let (_tmp, conn) = create_test_db(); - // Case 1: No documents at all let count = lore::embedding::count_pending_documents(&conn, "nomic-embed-text").unwrap(); let found = lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap(); @@ -263,7 +233,6 @@ fn count_and_find_pending_agree() { "Empty DB: count and find should agree" ); - // Case 2: New document (no metadata) insert_document(&conn, 1, "New doc", "Content"); let count = lore::embedding::count_pending_documents(&conn, "nomic-embed-text").unwrap(); let found = @@ -275,7 +244,6 @@ fn count_and_find_pending_agree() { ); assert_eq!(count, 1); - // Case 3: Document with matching metadata (not pending) let now = chrono::Utc::now().timestamp_millis(); conn.execute( "INSERT INTO embedding_metadata @@ -295,7 +263,6 @@ fn count_and_find_pending_agree() { ); assert_eq!(count, 0); - // Case 4: Config drift (chunk_max_bytes mismatch) conn.execute( "UPDATE embedding_metadata SET chunk_max_bytes = 999 WHERE document_id = 1", [], @@ -314,14 +281,11 @@ fn count_and_find_pending_agree() { #[test] fn full_embed_delete_is_atomic() { - // Bug 7: The --full flag's two DELETE statements should be atomic. - // This test verifies that both tables are cleared together. let (_tmp, conn) = create_test_db(); insert_document(&conn, 1, "Doc", "Content"); insert_embedding(&conn, 1, 0, &axis_vector(0)); - // Verify data exists let meta_count: i64 = conn .query_row("SELECT COUNT(*) FROM embedding_metadata", [], |r| r.get(0)) .unwrap(); @@ -331,7 +295,6 @@ fn full_embed_delete_is_atomic() { assert_eq!(meta_count, 1); assert_eq!(embed_count, 1); - // Execute the atomic delete (same as embed.rs --full) conn.execute_batch( "BEGIN; DELETE FROM embedding_metadata; diff --git a/tests/fixture_tests.rs b/tests/fixture_tests.rs index 9f07ddd..78f4912 100644 --- a/tests/fixture_tests.rs +++ b/tests/fixture_tests.rs @@ -1,5 +1,3 @@ -//! Tests for test fixtures - verifies they deserialize correctly. - use lore::gitlab::types::{GitLabDiscussion, GitLabIssue}; use serde::de::DeserializeOwned; use std::path::PathBuf; @@ -38,14 +36,11 @@ fn fixture_gitlab_issues_page_deserializes() { "Need at least 3 issues for pagination tests" ); - // Check first issue has labels assert!(!issues[0].labels.is_empty()); - // Check second issue has null description and empty labels assert!(issues[1].description.is_none()); assert!(issues[1].labels.is_empty()); - // Check third issue has multiple labels assert!(issues[2].labels.len() >= 3); } @@ -67,7 +62,6 @@ fn fixture_gitlab_discussions_page_deserializes() { "Need multiple discussions for testing" ); - // Check we have both individual_note=true and individual_note=false let has_individual = discussions.iter().any(|d| d.individual_note); let has_threaded = discussions.iter().any(|d| !d.individual_note); assert!( diff --git a/tests/fts_search.rs b/tests/fts_search.rs index da2fb5c..4df14b8 100644 --- a/tests/fts_search.rs +++ b/tests/fts_search.rs @@ -1,8 +1,3 @@ -//! Integration tests for FTS5 search. -//! -//! These tests create an in-memory SQLite database, apply migrations through 008 (FTS5), -//! seed documents, and verify search behavior. - use rusqlite::Connection; fn create_test_db() -> Connection { @@ -28,7 +23,6 @@ fn create_test_db() -> Connection { .unwrap_or_else(|e| panic!("Migration {} failed: {}", version, e)); } - // Seed a project conn.execute( "INSERT INTO projects (id, gitlab_project_id, path_with_namespace) VALUES (1, 100, 'group/project')", [], @@ -110,7 +104,6 @@ fn fts_stemming_matches() { "Deployment configuration for production servers.", ); - // "running" should match "runner" and "executing" via porter stemmer let results = lore::search::search_fts(&conn, "running", 10, lore::search::FtsQueryMode::Safe).unwrap(); assert!( @@ -157,11 +150,9 @@ fn fts_special_characters_handled() { "The C++ compiler segfaults on template metaprogramming.", ); - // Special characters should not crash the search let results = lore::search::search_fts(&conn, "C++ compiler", 10, lore::search::FtsQueryMode::Safe) .unwrap(); - // Safe mode sanitizes the query — it should still return results or at least not crash assert!(results.len() <= 1); } @@ -169,7 +160,6 @@ fn fts_special_characters_handled() { fn fts_result_ordering_by_relevance() { let conn = create_test_db(); - // Doc 1: "authentication" in title and content insert_document( &conn, 1, @@ -177,7 +167,6 @@ fn fts_result_ordering_by_relevance() { "Authentication system redesign", "The authentication system needs a complete redesign. Authentication flows are broken.", ); - // Doc 2: "authentication" only in content, once insert_document( &conn, 2, @@ -185,7 +174,6 @@ fn fts_result_ordering_by_relevance() { "Login page update", "Updated the login page with better authentication error messages.", ); - // Doc 3: unrelated insert_document( &conn, 3, @@ -203,7 +191,6 @@ fn fts_result_ordering_by_relevance() { .unwrap(); assert!(results.len() >= 2, "Should match at least 2 documents"); - // Doc 1 should rank higher (more occurrences of the term) assert_eq!( results[0].document_id, 1, "Document with more term occurrences should rank first" @@ -246,7 +233,6 @@ fn fts_snippet_generated() { .unwrap(); assert!(!results.is_empty()); - // Snippet should contain some text (may have FTS5 highlight markers) assert!( !results[0].snippet.is_empty(), "Snippet should be generated" @@ -265,7 +251,6 @@ fn fts_triggers_sync_on_insert() { "This is test content for FTS trigger verification.", ); - // Verify FTS table has an entry via direct query let fts_count: i64 = conn .query_row( "SELECT COUNT(*) FROM documents_fts WHERE documents_fts MATCH 'test'", @@ -289,7 +274,6 @@ fn fts_triggers_sync_on_delete() { "This content will be deleted from the index.", ); - // Verify it's indexed let before: i64 = conn .query_row( "SELECT COUNT(*) FROM documents_fts WHERE documents_fts MATCH 'deletable'", @@ -299,11 +283,9 @@ fn fts_triggers_sync_on_delete() { .unwrap(); assert_eq!(before, 1); - // Delete the document conn.execute("DELETE FROM documents WHERE id = 1", []) .unwrap(); - // Verify it's removed from FTS let after: i64 = conn .query_row( "SELECT COUNT(*) FROM documents_fts WHERE documents_fts MATCH 'deletable'", @@ -318,7 +300,6 @@ fn fts_triggers_sync_on_delete() { fn fts_null_title_handled() { let conn = create_test_db(); - // Discussion documents have NULL titles conn.execute( "INSERT INTO documents (id, source_type, source_id, project_id, title, content_text, content_hash, url) VALUES (1, 'discussion', 1, 1, NULL, 'Discussion about API rate limiting strategies.', 'hash1', 'https://example.com/1')", diff --git a/tests/golden_query_tests.rs b/tests/golden_query_tests.rs index 78d757e..5c8cee8 100644 --- a/tests/golden_query_tests.rs +++ b/tests/golden_query_tests.rs @@ -1,9 +1,3 @@ -//! Golden query test suite. -//! -//! Verifies end-to-end search quality with known-good expected results. -//! Uses a seeded SQLite DB with deterministic fixture data and no external -//! dependencies (no Ollama, no GitLab). - #![allow(dead_code)] use rusqlite::Connection; @@ -12,7 +6,6 @@ use std::path::PathBuf; use lore::search::{FtsQueryMode, SearchFilters, SearchMode, apply_filters, search_fts}; -/// A golden query test case. #[derive(Debug, Deserialize)] struct GoldenQuery { query: String, @@ -42,12 +35,10 @@ fn load_golden_queries() -> Vec { .unwrap_or_else(|e| panic!("Failed to parse golden queries: {}", e)) } -/// Create an in-memory database with FTS5 schema and seed deterministic fixture data. fn create_seeded_db() -> Connection { let conn = Connection::open_in_memory().unwrap(); conn.pragma_update(None, "foreign_keys", "ON").unwrap(); - // Apply migrations 001-008 (FTS5) let migrations_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("migrations"); for version in 1..=8 { let entries: Vec<_> = std::fs::read_dir(&migrations_dir) @@ -65,7 +56,6 @@ fn create_seeded_db() -> Connection { .unwrap_or_else(|e| panic!("Migration {} failed: {}", version, e)); } - // Seed project conn.execute( "INSERT INTO projects (id, gitlab_project_id, path_with_namespace, web_url) VALUES (1, 100, 'group/project', 'https://gitlab.example.com/group/project')", @@ -73,9 +63,7 @@ fn create_seeded_db() -> Connection { ) .unwrap(); - // Seed deterministic documents let documents = vec![ - // id=1: Auth issue (matches: authentication, login, OAuth, JWT, token, refresh) ( 1, "issue", @@ -86,7 +74,6 @@ fn create_seeded_db() -> Connection { Multiple users reported authentication failures across all OAuth providers.", "testuser", ), - // id=2: User profile MR (matches: user, profile, avatar, upload) ( 2, "merge_request", @@ -96,7 +83,6 @@ fn create_seeded_db() -> Connection { responsive design for mobile and desktop viewports.", "developer1", ), - // id=3: Database migration issue (matches: database, migration, PostgreSQL, schema) ( 3, "issue", @@ -106,7 +92,6 @@ fn create_seeded_db() -> Connection { rewritten to use the new schema modification syntax. All staging environments affected.", "dba_admin", ), - // id=4: Performance MR (matches: performance, optimization, caching, query) ( 4, "merge_request", @@ -116,7 +101,6 @@ fn create_seeded_db() -> Connection { to 180ms. Added connection pooling and prepared statement caching.", "senior_dev", ), - // id=5: API rate limiting discussion (matches: API, rate, limiting, throttle) ( 5, "discussion", @@ -127,7 +111,6 @@ fn create_seeded_db() -> Connection { Need to handle burst traffic during peak hours without throttling legitimate users.", "architect", ), - // id=6: UI/CSS issue (matches: CSS, styling, frontend, responsive, UI) ( 6, "issue", @@ -138,7 +121,6 @@ fn create_seeded_db() -> Connection { conflicting CSS specificity with the theme system.", "frontend_dev", ), - // id=7: CI/CD MR (matches: CI, CD, pipeline, deployment, Docker) ( 7, "merge_request", @@ -148,7 +130,6 @@ fn create_seeded_db() -> Connection { support for failed deployments. Pipeline runtime reduced from 45min to 12min.", "devops_lead", ), - // id=8: Security issue (matches: security, vulnerability, XSS, injection) ( 8, "issue", @@ -169,7 +150,6 @@ fn create_seeded_db() -> Connection { .unwrap(); } - // Seed labels for filtered queries conn.execute_batch( "INSERT INTO document_labels (document_id, label_name) VALUES (1, 'bug'); INSERT INTO document_labels (document_id, label_name) VALUES (1, 'authentication'); @@ -212,7 +192,6 @@ fn golden_queries_all_pass() { for (i, gq) in queries.iter().enumerate() { let mode = SearchMode::parse(&gq.mode).unwrap_or(SearchMode::Lexical); - // For lexical-only golden queries (no Ollama needed) assert_eq!( mode, SearchMode::Lexical, @@ -221,11 +200,9 @@ fn golden_queries_all_pass() { gq.mode ); - // Run FTS search let fts_results = search_fts(&conn, &gq.query, 50, FtsQueryMode::Safe).unwrap(); let doc_ids: Vec = fts_results.iter().map(|r| r.document_id).collect(); - // Apply filters if any let filters = build_search_filters(&gq.filters); let filtered_ids = if filters.has_any_filter() { apply_filters(&conn, &doc_ids, &filters).unwrap() @@ -233,7 +210,6 @@ fn golden_queries_all_pass() { doc_ids.clone() }; - // Check min_results if filtered_ids.len() < gq.min_results { failures.push(format!( "FAIL [{}] \"{}\": expected >= {} results, got {} (description: {})", @@ -246,13 +222,10 @@ fn golden_queries_all_pass() { continue; } - // Check each expected doc_id is in top max_rank for expected_id in &gq.expected_doc_ids { let position = filtered_ids.iter().position(|id| id == expected_id); match position { - Some(pos) if pos < gq.max_rank => { - // Pass - } + Some(pos) if pos < gq.max_rank => {} Some(pos) => { failures.push(format!( "FAIL [{}] \"{}\": expected doc_id {} in top {}, found at rank {} (description: {})", diff --git a/tests/hybrid_search.rs b/tests/hybrid_search.rs index d201f76..cedbe3f 100644 --- a/tests/hybrid_search.rs +++ b/tests/hybrid_search.rs @@ -1,8 +1,3 @@ -//! Integration tests for hybrid search combining FTS + vector. -//! -//! Tests all three search modes (lexical, semantic, hybrid) and -//! verifies graceful degradation when embeddings are unavailable. - use lore::core::db::create_connection; use lore::search::{FtsQueryMode, SearchFilters, SearchMode, search_fts, search_hybrid}; use rusqlite::Connection; @@ -89,7 +84,6 @@ fn lexical_mode_uses_fts_only() { assert!(!results.is_empty(), "Lexical search should find results"); assert_eq!(results[0].document_id, 1); - // Lexical mode should not produce Ollama-related warnings assert!( warnings.iter().all(|w| !w.contains("Ollama")), "Lexical mode should not warn about Ollama" @@ -98,12 +92,10 @@ fn lexical_mode_uses_fts_only() { #[test] fn lexical_mode_no_embeddings_required() { - // Use in-memory DB without sqlite-vec for pure FTS let conn = Connection::open_in_memory().unwrap(); conn.pragma_update(None, "foreign_keys", "ON").unwrap(); let migrations_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("migrations"); - // Only apply through migration 008 (FTS5, no embeddings) for version in 1..=8 { let entries: Vec<_> = std::fs::read_dir(&migrations_dir) .unwrap() @@ -159,7 +151,7 @@ fn hybrid_mode_degrades_to_fts_without_client() { let (results, warnings) = rt .block_on(search_hybrid( &conn, - None, // No Ollama client + None, "performance slow", SearchMode::Hybrid, &filters, @@ -168,7 +160,6 @@ fn hybrid_mode_degrades_to_fts_without_client() { .unwrap(); assert!(!results.is_empty(), "Should fall back to FTS results"); - // Should warn about missing Ollama client assert!( warnings.iter().any(|w| w.to_lowercase().contains("vector") || w.to_lowercase().contains("ollama") @@ -184,14 +175,12 @@ fn hybrid_mode_degrades_to_fts_without_client() { fn rrf_ranking_combines_signals() { use lore::search::rank_rrf; - // Two documents with different rankings in each signal - let vector_results = vec![(1_i64, 0.1), (2, 0.5)]; // doc 1 closer - let fts_results = vec![(2_i64, -5.0), (1, -3.0)]; // doc 2 higher BM25 + let vector_results = vec![(1_i64, 0.1), (2, 0.5)]; + let fts_results = vec![(2_i64, -5.0), (1, -3.0)]; let rrf = rank_rrf(&vector_results, &fts_results); assert_eq!(rrf.len(), 2, "Should return both documents"); - // Both docs appear in both signals, so both get RRF scores for r in &rrf { assert!(r.rrf_score > 0.0, "RRF score should be positive"); } @@ -235,7 +224,6 @@ fn filters_by_source_type() { #[test] fn search_mode_variants_exist() { - // Verify all enum variants compile and are distinct let hybrid = SearchMode::Hybrid; let lexical = SearchMode::Lexical; let semantic = SearchMode::Semantic; diff --git a/tests/migration_tests.rs b/tests/migration_tests.rs index b19f0af..e7228ca 100644 --- a/tests/migration_tests.rs +++ b/tests/migration_tests.rs @@ -1,5 +1,3 @@ -//! Tests for database migrations. - use rusqlite::Connection; use std::path::PathBuf; @@ -41,7 +39,6 @@ fn migration_002_creates_issues_table() { let conn = create_test_db(); apply_migrations(&conn, 2); - // Verify issues table exists with expected columns let columns: Vec = conn .prepare("PRAGMA table_info(issues)") .unwrap() @@ -124,13 +121,11 @@ fn migration_002_enforces_state_check() { let conn = create_test_db(); apply_migrations(&conn, 2); - // First insert a project so we can reference it conn.execute( "INSERT INTO projects (id, gitlab_project_id, path_with_namespace) VALUES (1, 100, 'group/project')", [], ).unwrap(); - // Valid states should work conn.execute( "INSERT INTO issues (gitlab_id, project_id, iid, state, created_at, updated_at, last_seen_at) VALUES (1, 1, 1, 'opened', 1000, 1000, 1000)", @@ -143,7 +138,6 @@ fn migration_002_enforces_state_check() { [], ).unwrap(); - // Invalid state should fail let result = conn.execute( "INSERT INTO issues (gitlab_id, project_id, iid, state, created_at, updated_at, last_seen_at) VALUES (3, 1, 3, 'invalid', 1000, 1000, 1000)", @@ -158,7 +152,6 @@ fn migration_002_enforces_noteable_type_check() { let conn = create_test_db(); apply_migrations(&conn, 2); - // Setup: project and issue conn.execute( "INSERT INTO projects (id, gitlab_project_id, path_with_namespace) VALUES (1, 100, 'group/project')", [], @@ -169,14 +162,12 @@ fn migration_002_enforces_noteable_type_check() { [], ).unwrap(); - // Valid: Issue discussion with issue_id conn.execute( "INSERT INTO discussions (gitlab_discussion_id, project_id, issue_id, noteable_type, last_seen_at) VALUES ('abc123', 1, 1, 'Issue', 1000)", [], ).unwrap(); - // Invalid: noteable_type not in allowed values let result = conn.execute( "INSERT INTO discussions (gitlab_discussion_id, project_id, issue_id, noteable_type, last_seen_at) VALUES ('def456', 1, 1, 'Commit', 1000)", @@ -184,7 +175,6 @@ fn migration_002_enforces_noteable_type_check() { ); assert!(result.is_err()); - // Invalid: Issue type but no issue_id let result = conn.execute( "INSERT INTO discussions (gitlab_discussion_id, project_id, noteable_type, last_seen_at) VALUES ('ghi789', 1, 'Issue', 1000)", @@ -198,7 +188,6 @@ fn migration_002_cascades_on_project_delete() { let conn = create_test_db(); apply_migrations(&conn, 2); - // Setup: project, issue, label, issue_label link, discussion, note conn.execute( "INSERT INTO projects (id, gitlab_project_id, path_with_namespace) VALUES (1, 100, 'group/project')", [], @@ -229,11 +218,9 @@ fn migration_002_cascades_on_project_delete() { [], ).unwrap(); - // Delete project conn.execute("DELETE FROM projects WHERE id = 1", []) .unwrap(); - // Verify cascade: all related data should be gone let issue_count: i64 = conn .query_row("SELECT COUNT(*) FROM issues", [], |r| r.get(0)) .unwrap(); @@ -265,8 +252,6 @@ fn migration_002_updates_schema_version() { assert_eq!(version, 2); } -// === Migration 005 Tests === - #[test] fn migration_005_creates_milestones_table() { let conn = create_test_db(); @@ -331,7 +316,6 @@ fn migration_005_milestones_cascade_on_project_delete() { let conn = create_test_db(); apply_migrations(&conn, 5); - // Setup: project with milestone conn.execute( "INSERT INTO projects (id, gitlab_project_id, path_with_namespace) VALUES (1, 100, 'group/project')", [], @@ -341,11 +325,9 @@ fn migration_005_milestones_cascade_on_project_delete() { [], ).unwrap(); - // Delete project conn.execute("DELETE FROM projects WHERE id = 1", []) .unwrap(); - // Verify milestone is gone let count: i64 = conn .query_row("SELECT COUNT(*) FROM milestones", [], |r| r.get(0)) .unwrap(); @@ -357,7 +339,6 @@ fn migration_005_assignees_cascade_on_issue_delete() { let conn = create_test_db(); apply_migrations(&conn, 5); - // Setup: project, issue, assignee conn.execute( "INSERT INTO projects (id, gitlab_project_id, path_with_namespace) VALUES (1, 100, 'group/project')", [], @@ -373,10 +354,8 @@ fn migration_005_assignees_cascade_on_issue_delete() { ) .unwrap(); - // Delete issue conn.execute("DELETE FROM issues WHERE id = 1", []).unwrap(); - // Verify assignee link is gone let count: i64 = conn .query_row("SELECT COUNT(*) FROM issue_assignees", [], |r| r.get(0)) .unwrap(); diff --git a/tests/mr_discussion_tests.rs b/tests/mr_discussion_tests.rs index f37fc00..55463c2 100644 --- a/tests/mr_discussion_tests.rs +++ b/tests/mr_discussion_tests.rs @@ -1,5 +1,3 @@ -//! Tests for MR discussion transformer. - use lore::gitlab::transformers::discussion::transform_mr_discussion; use lore::gitlab::types::{GitLabAuthor, GitLabDiscussion, GitLabNote}; @@ -77,7 +75,7 @@ fn transform_mr_discussion_computes_resolvable_from_notes() { let result = transform_mr_discussion(&discussion, 100, 42); assert!(result.resolvable); - assert!(!result.resolved); // resolvable but not resolved + assert!(!result.resolved); } #[test] diff --git a/tests/mr_transformer_tests.rs b/tests/mr_transformer_tests.rs index 44c414d..8dd5b9b 100644 --- a/tests/mr_transformer_tests.rs +++ b/tests/mr_transformer_tests.rs @@ -1,5 +1,3 @@ -//! Tests for MR transformer module. - use lore::gitlab::transformers::merge_request::transform_merge_request; use lore::gitlab::types::{GitLabAuthor, GitLabMergeRequest, GitLabReferences, GitLabReviewer}; @@ -63,7 +61,7 @@ fn transforms_mr_with_all_fields() { assert_eq!(result.merge_request.gitlab_id, 12345); assert_eq!(result.merge_request.iid, 42); - assert_eq!(result.merge_request.project_id, 200); // Local project ID, not GitLab's + assert_eq!(result.merge_request.project_id, 200); assert_eq!(result.merge_request.title, "Add user authentication"); assert_eq!( result.merge_request.description, @@ -105,22 +103,17 @@ fn parses_timestamps_to_ms_epoch() { let mr = make_test_mr(); let result = transform_merge_request(&mr, 200).unwrap(); - // 2024-01-15T10:00:00.000Z = 1705312800000 ms assert_eq!(result.merge_request.created_at, 1705312800000); - // 2024-01-20T14:30:00.000Z = 1705761000000 ms assert_eq!(result.merge_request.updated_at, 1705761000000); - // merged_at should also be parsed assert_eq!(result.merge_request.merged_at, Some(1705761000000)); } #[test] fn handles_timezone_offset_timestamps() { let mut mr = make_test_mr(); - // GitLab can return timestamps with timezone offset mr.created_at = "2024-01-15T05:00:00-05:00".to_string(); let result = transform_merge_request(&mr, 200).unwrap(); - // 05:00 EST = 10:00 UTC = same as original test assert_eq!(result.merge_request.created_at, 1705312800000); } @@ -322,7 +315,6 @@ fn handles_closed_at_timestamp() { let result = transform_merge_request(&mr, 200).unwrap(); assert!(result.merge_request.merged_at.is_none()); - // 2024-01-18T12:00:00.000Z = 1705579200000 ms assert_eq!(result.merge_request.closed_at, Some(1705579200000)); }