use chrono::Utc;
use codex_memory::models::{Memory, SearchParams, SearchResult, SearchStrategy};
use uuid::Uuid;
#[test]
fn test_search_params_default() {
let params = SearchParams::default();
assert_eq!(params.query, "");
assert_eq!(params.tag_filter, None);
assert!(params.use_tag_embedding);
assert!(params.use_content_embedding);
assert_eq!(params.similarity_threshold, 0.7);
assert_eq!(params.max_results, 10);
assert!(matches!(params.search_strategy, SearchStrategy::Hybrid));
assert!(!params.boost_recent);
assert_eq!(params.tag_weight, 0.4);
assert_eq!(params.content_weight, 0.6);
}
#[test]
fn test_search_params_custom() {
let params = SearchParams {
query: "test query".to_string(),
tag_filter: Some(vec!["tag1".to_string(), "tag2".to_string()]),
use_tag_embedding: false,
use_content_embedding: true,
similarity_threshold: 0.8,
max_results: 5,
search_strategy: SearchStrategy::ContentFirst,
boost_recent: true,
tag_weight: 0.3,
content_weight: 0.7,
};
assert_eq!(params.query, "test query");
assert_eq!(
params.tag_filter,
Some(vec!["tag1".to_string(), "tag2".to_string()])
);
assert!(!params.use_tag_embedding);
assert!(params.use_content_embedding);
assert_eq!(params.similarity_threshold, 0.8);
assert_eq!(params.max_results, 5);
assert!(matches!(
params.search_strategy,
SearchStrategy::ContentFirst
));
assert!(params.boost_recent);
assert_eq!(params.tag_weight, 0.3);
assert_eq!(params.content_weight, 0.7);
}
#[test]
fn test_search_strategy_variants() {
let strategies = [
SearchStrategy::TagsFirst,
SearchStrategy::ContentFirst,
SearchStrategy::Hybrid,
];
assert_eq!(strategies.len(), 3);
}
#[test]
fn test_search_strategy_serialization() {
use serde_json;
assert_eq!(
serde_json::to_string(&SearchStrategy::TagsFirst).unwrap(),
"\"TagsFirst\""
);
assert_eq!(
serde_json::to_string(&SearchStrategy::ContentFirst).unwrap(),
"\"ContentFirst\""
);
assert_eq!(
serde_json::to_string(&SearchStrategy::Hybrid).unwrap(),
"\"Hybrid\""
);
assert!(matches!(
serde_json::from_str::<SearchStrategy>("\"TagsFirst\"").unwrap(),
SearchStrategy::TagsFirst
));
assert!(matches!(
serde_json::from_str::<SearchStrategy>("\"ContentFirst\"").unwrap(),
SearchStrategy::ContentFirst
));
assert!(matches!(
serde_json::from_str::<SearchStrategy>("\"Hybrid\"").unwrap(),
SearchStrategy::Hybrid
));
}
#[test]
fn test_search_result_scoring() {
let memory = create_test_memory();
let result = SearchResult::new(
memory.clone(),
Some(0.8), Some(0.9), Some(1), 0.4, 0.6, );
assert_eq!(result.tag_similarity, Some(0.8));
assert_eq!(result.content_similarity, Some(0.9));
assert_eq!(result.semantic_cluster, Some(1));
assert!((result.combined_score - 0.86).abs() < f64::EPSILON);
}
#[test]
fn test_search_result_scoring_tag_only() {
let memory = create_test_memory();
let result = SearchResult::new(
memory,
Some(0.8), None, None, 0.4, 0.6, );
assert_eq!(result.tag_similarity, Some(0.8));
assert_eq!(result.content_similarity, None);
assert_eq!(result.semantic_cluster, None);
assert!((result.combined_score - 0.32).abs() < f64::EPSILON);
}
#[test]
fn test_search_result_scoring_content_only() {
let memory = create_test_memory();
let result = SearchResult::new(
memory,
None, Some(0.9), None, 0.4, 0.6, );
assert_eq!(result.tag_similarity, None);
assert_eq!(result.content_similarity, Some(0.9));
assert!((result.combined_score - 0.54).abs() < f64::EPSILON);
}
#[test]
fn test_search_result_scoring_no_similarities() {
let memory = create_test_memory();
let result = SearchResult::new(
memory, None, None, None, 0.4, 0.6, );
assert_eq!(result.tag_similarity, None);
assert_eq!(result.content_similarity, None);
assert!((result.combined_score - 0.0).abs() < f64::EPSILON);
}
#[test]
fn test_search_result_weight_boundaries() {
let memory = create_test_memory();
let result = SearchResult::new(
memory.clone(),
Some(0.5),
Some(0.8),
None,
0.0, 1.0, );
assert!((result.combined_score - 0.8).abs() < f64::EPSILON);
let result2 = SearchResult::new(
memory,
Some(0.5),
Some(0.8),
None,
1.0, 0.0, );
assert!((result2.combined_score - 0.5).abs() < f64::EPSILON);
}
#[test]
fn test_search_params_serialization() {
let params = SearchParams {
query: "test query".to_string(),
tag_filter: Some(vec!["tag1".to_string()]),
use_tag_embedding: false,
use_content_embedding: true,
similarity_threshold: 0.8,
max_results: 5,
search_strategy: SearchStrategy::ContentFirst,
boost_recent: true,
tag_weight: 0.3,
content_weight: 0.7,
};
let json = serde_json::to_string(¶ms).unwrap();
assert!(json.contains("test query"));
assert!(json.contains("ContentFirst"));
let deserialized: SearchParams = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.query, params.query);
assert_eq!(deserialized.tag_filter, params.tag_filter);
assert_eq!(
deserialized.similarity_threshold,
params.similarity_threshold
);
assert_eq!(deserialized.max_results, params.max_results);
assert!(matches!(
deserialized.search_strategy,
SearchStrategy::ContentFirst
));
}
#[test]
fn test_search_result_serialization() {
let memory = create_test_memory();
let result = SearchResult::new(memory, Some(0.8), Some(0.9), Some(2), 0.4, 0.6);
let json = serde_json::to_string(&result).unwrap();
assert!(json.contains("test content"));
assert!(json.contains("0.8"));
assert!(json.contains("0.9"));
let deserialized: SearchResult = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.memory.content, "test content");
assert_eq!(deserialized.tag_similarity, Some(0.8));
assert_eq!(deserialized.content_similarity, Some(0.9));
assert_eq!(deserialized.semantic_cluster, Some(2));
}
#[test]
fn test_search_params_clone() {
let params = SearchParams {
query: "test".to_string(),
tag_filter: Some(vec!["tag".to_string()]),
..Default::default()
};
let cloned = params.clone();
assert_eq!(params.query, cloned.query);
assert_eq!(params.tag_filter, cloned.tag_filter);
assert_eq!(params.similarity_threshold, cloned.similarity_threshold);
}
#[test]
fn test_search_result_clone() {
let memory = create_test_memory();
let result = SearchResult::new(memory, Some(0.8), Some(0.9), Some(1), 0.4, 0.6);
let cloned = result.clone();
assert_eq!(result.memory.id, cloned.memory.id);
assert_eq!(result.tag_similarity, cloned.tag_similarity);
assert_eq!(result.content_similarity, cloned.content_similarity);
assert_eq!(result.combined_score, cloned.combined_score);
}
#[test]
fn test_search_params_debug() {
let params = SearchParams::default();
let debug_str = format!("{:?}", params);
assert!(debug_str.contains("SearchParams"));
assert!(debug_str.contains("similarity_threshold"));
assert!(debug_str.contains("0.7"));
}
#[test]
fn test_search_result_debug() {
let memory = create_test_memory();
let result = SearchResult::new(memory, Some(0.8), Some(0.9), Some(1), 0.4, 0.6);
let debug_str = format!("{:?}", result);
assert!(debug_str.contains("SearchResult"));
assert!(debug_str.contains("combined_score"));
assert!(debug_str.contains("0.86"));
}
fn create_test_memory() -> Memory {
Memory {
id: Uuid::new_v4(),
content: "test content".to_string(),
content_hash: "hash123".to_string(),
tags: vec!["tag1".to_string(), "tag2".to_string()],
context: "test context".to_string(),
summary: "test summary".to_string(),
chunk_index: None,
total_chunks: None,
parent_id: None,
created_at: Utc::now(),
updated_at: Utc::now(),
}
}