use super::*;
#[test]
fn test_cache_new() {
let cache = QueryCache::new(100);
assert_eq!(cache.len(), 0);
assert!(cache.is_empty());
assert_eq!(cache.stats().hits, 0);
assert_eq!(cache.stats().misses, 0);
}
#[test]
fn test_cache_parse_miss() {
let cache = QueryCache::new(100);
let result = cache.parse("SELECT * FROM documents");
assert!(result.is_ok());
assert_eq!(cache.len(), 1);
assert_eq!(cache.stats().misses, 1);
assert_eq!(cache.stats().hits, 0);
}
#[test]
fn test_cache_parse_hit() {
let cache = QueryCache::new(100);
let query = "SELECT * FROM documents LIMIT 10";
let result1 = cache.parse(query);
let result2 = cache.parse(query);
assert!(result1.is_ok());
assert!(result2.is_ok());
assert_eq!(result1.unwrap(), result2.unwrap());
assert_eq!(cache.stats().hits, 1);
assert_eq!(cache.stats().misses, 1);
}
#[test]
fn test_cache_hit_rate() {
let cache = QueryCache::new(100);
let query = "SELECT * FROM test";
for _ in 0..10 {
let _ = cache.parse(query);
}
let stats = cache.stats();
assert_eq!(stats.hits, 9);
assert_eq!(stats.misses, 1);
assert!((stats.hit_rate() - 90.0).abs() < 0.01);
}
#[test]
fn test_cache_eviction() {
let cache = QueryCache::new(3);
let _ = cache.parse("SELECT * FROM a");
let _ = cache.parse("SELECT * FROM b");
let _ = cache.parse("SELECT * FROM c");
let _ = cache.parse("SELECT * FROM d");
assert_eq!(cache.len(), 3);
assert_eq!(cache.stats().evictions, 1);
}
#[test]
fn test_cache_clear() {
let cache = QueryCache::new(100);
let _ = cache.parse("SELECT * FROM test");
let _ = cache.parse("SELECT * FROM test");
cache.clear();
assert!(cache.is_empty());
assert_eq!(cache.stats().hits, 0);
assert_eq!(cache.stats().misses, 0);
}
#[test]
fn test_cache_invalid_query() {
let cache = QueryCache::new(100);
let result = cache.parse("INVALID QUERY");
assert!(result.is_err());
assert!(cache.is_empty()); }
#[test]
fn test_cache_different_queries() {
let cache = QueryCache::new(100);
let _ = cache.parse("SELECT * FROM a");
let _ = cache.parse("SELECT * FROM b");
let _ = cache.parse("SELECT id FROM c WHERE id = 1");
assert_eq!(cache.len(), 3);
assert_eq!(cache.stats().misses, 3);
assert_eq!(cache.stats().hits, 0);
}
#[test]
fn test_cache_min_size() {
let cache = QueryCache::new(0);
let _ = cache.parse("SELECT * FROM a");
let _ = cache.parse("SELECT * FROM b");
assert_eq!(cache.len(), 1); assert_eq!(cache.stats().evictions, 1);
}
#[test]
fn test_cache_thread_safety() {
use std::sync::Arc;
use std::thread;
let cache = Arc::new(QueryCache::new(100));
let query = "SELECT * FROM concurrent_test";
let handles: Vec<_> = (0..10)
.map(|_| {
let cache = Arc::clone(&cache);
let q = query.to_string();
thread::spawn(move || {
for _ in 0..100 {
let _ = cache.parse(&q);
}
})
})
.collect();
for h in handles {
h.join().expect("Thread panicked");
}
let stats = cache.stats();
assert!(stats.hit_rate() > 90.0);
assert_eq!(stats.hits + stats.misses, 1000);
}
#[test]
fn test_cache_stats_hit_rate_empty() {
let stats = CacheStats::default();
assert!(stats.hit_rate().abs() < f64::EPSILON);
}