Files
semantic-memory-mcp/tests/advanced_features.rs
Sienna Meridian Satterwhite 6a6a2ade32 initial commit
Signed-off-by: Sienna Meridian Satterwhite <sienna@r3t.io>
2026-03-06 22:43:25 +00:00

95 lines
3.3 KiB
Rust

use mcp_server::semantic::store::SemanticStore;
use mcp_server::semantic::SemanticConfig;
#[tokio::test]
async fn test_hybrid_search_combines_keyword_and_vector() {
let config = SemanticConfig {
base_dir: "./tests/data/test_hybrid_data".to_string(),
dimension: 768,
model_name: "bge-base-en-v1.5".to_string(),
};
let store = SemanticStore::new(&config).await.unwrap();
let embedding1 = vec![1.0_f32; 768];
let embedding2 = vec![0.0_f32; 768];
let embedding3 = {
let mut v = vec![0.0_f32; 768];
v[767] = 1.0;
v
};
store.add_fact("test_namespace", "Rust programming language", &embedding1, None).await.unwrap();
store.add_fact("test_namespace", "Python programming language", &embedding2, None).await.unwrap();
store.add_fact("test_namespace", "JavaScript programming language", &embedding3, None).await.unwrap();
store.add_fact("other_namespace", "Rust programming is great", &embedding1, None).await.unwrap();
// Query similar to embedding1 (all 1s)
let query_embedding = vec![1.0_f32; 768];
let results = store.hybrid_search("Rust", &query_embedding, 2).await.unwrap();
assert_eq!(results.len(), 2);
assert!(results[0].content.contains("Rust"));
assert!(results[1].content.contains("Rust"));
}
#[tokio::test]
async fn test_hybrid_search_with_no_keyword_matches() {
let config = SemanticConfig {
base_dir: "./tests/data/test_hybrid_no_keyword".to_string(),
dimension: 3,
model_name: "test".to_string(),
};
let store = SemanticStore::new(&config).await.unwrap();
let embedding = vec![1.0_f32, 0.0, 0.0];
store.add_fact("test", "Content without keyword", &embedding, None).await.unwrap();
// Keyword has no matches — falls back to vector search, so results are non-empty
let query_embedding = vec![1.0_f32, 0.0, 0.0];
let results = store.hybrid_search("Nonexistent", &query_embedding, 1).await.unwrap();
assert!(!results.is_empty(), "Should fall back to vector search when keyword matches nothing");
}
#[tokio::test]
async fn test_hybrid_search_with_no_vector_matches() {
let config = SemanticConfig {
base_dir: "./tests/data/test_hybrid_no_vector".to_string(),
dimension: 3,
model_name: "test".to_string(),
};
let store = SemanticStore::new(&config).await.unwrap();
let embedding = vec![1.0_f32, 0.0, 0.0];
store.add_fact("test", "Rust programming", &embedding, None).await.unwrap();
// Orthogonal query vector — keyword still matches
let query_embedding = vec![0.0_f32, 0.0, 1.0];
let results = store.hybrid_search("Rust", &query_embedding, 1).await.unwrap();
assert_eq!(results.len(), 1);
assert!(results[0].content.contains("Rust"));
}
#[tokio::test]
async fn test_logging_in_unauthenticated_mode() {
use mcp_server::logging::FileLogger;
use std::fs;
let log_path = "./test_unauth_log.txt";
let _ = fs::remove_file(log_path);
let logger = FileLogger::new(log_path.to_string());
logger.log("GET", "/health", "200");
assert!(fs::metadata(log_path).is_ok());
let log_content = fs::read_to_string(log_path).unwrap();
assert!(log_content.contains("GET /health"));
assert!(log_content.contains("200"));
fs::remove_file(log_path).ok();
}