diff --git a/crates/zx_document_core/src/search.rs b/crates/zx_document_core/src/search.rs index d09a4c0..4f9ceb8 100644 --- a/crates/zx_document_core/src/search.rs +++ b/crates/zx_document_core/src/search.rs @@ -433,4 +433,89 @@ mod tests { }; assert!(!validate_search_result(&result, "test")); } + + #[test] + fn test_validate_search_result_empty_snippet() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: String::new(), match_start: 0, match_end: 0, + }; + assert!(!validate_search_result(&result, "hello")); + } + + #[test] + fn test_validate_search_result_match_at_snippet_end() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: "the end".into(), match_start: 4, match_end: 7, + }; + assert!(validate_search_result(&result, "end")); + } + + #[test] + fn test_validate_search_result_start_gt_end() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: "text".into(), match_start: 3, match_end: 1, + }; + assert!(!validate_search_result(&result, "test")); + } + + #[test] + fn test_validate_search_result_exact_bounds() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: "exact".into(), match_start: 0, match_end: 5, + }; + assert!(validate_search_result(&result, "exact")); + } + + #[test] + fn test_validate_search_result_query_longer_than_snippet() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: "hi".into(), match_start: 0, match_end: 2, + }; + assert!(!validate_search_result(&result, "hello")); + // match_end (2) == snippet.len() so bounds ok, but "hi" != "hello" + } + + #[test] + fn test_validate_search_result_unicode_snippet() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: "你好世界".into(), match_start: 0, match_end: 6, // "你好" = 6 bytes in UTF-8 + }; + assert!(validate_search_result(&result, "你好")); + } + + #[test] + fn test_validate_search_result_zero_length_match() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: "test".into(), match_start: 1, match_end: 1, + }; + // Zero-length match: start==end, query is empty string + // Empty query → early return false + assert!(!validate_search_result(&result, "")); + } + + #[test] + fn test_validate_search_result_match_end_equals_snippet_len() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: "match".into(), match_start: 0, match_end: 5, + }; + // match_end == snippet.len() is valid + assert!(validate_search_result(&result, "match")); + } + + #[test] + fn test_validate_search_result_query_mismatch() { + let result = SearchResult { + block_id: "b1".into(), line_number: None, page_number: None, chapter_id: None, + snippet: "hello world".into(), match_start: 0, match_end: 5, + }; + assert!(!validate_search_result(&result, "world")); + } }