#[cfg(test)]
mod tests {
use oxcache::Cache;
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct User {
id: u64,
name: String,
}
#[tokio::test]
async fn test_cache_set_and_get() -> anyhow::Result<()> {
let cache: Cache<String, User> = Cache::memory().await?;
let user = User {
id: 1,
name: "Alice".to_string(),
};
cache.set("user:1", &user).await?;
let retrieved: Option<User> = cache.get("user:1").await?;
assert!(retrieved.is_some());
assert_eq!(retrieved.unwrap().name, "Alice");
Ok(())
}
#[tokio::test]
async fn test_cache_delete() -> anyhow::Result<()> {
let cache: Cache<String, User> = Cache::memory().await?;
let user = User {
id: 1,
name: "Alice".to_string(),
};
cache.set("user:1", &user).await?;
let exists = cache.exists("user:1").await?;
assert!(exists);
cache.delete("user:1").await?;
let retrieved: Option<User> = cache.get("user:1").await?;
assert!(retrieved.is_none());
Ok(())
}
#[tokio::test]
async fn test_cache_expiration() -> anyhow::Result<()> {
let cache: Cache<String, User> = Cache::memory().await?;
let user = User {
id: 1,
name: "Alice".to_string(),
};
cache
.set_with_ttl("user:1", &user, Some(Duration::from_secs(1)))
.await?;
let exists = cache.exists("user:1").await?;
assert!(exists);
tokio::time::sleep(Duration::from_secs(2)).await;
let retrieved: Option<User> = cache.get("user:1").await?;
assert!(retrieved.is_none());
Ok(())
}
#[tokio::test]
async fn test_cache_get_or_fallback() -> anyhow::Result<()> {
let cache: Cache<String, User> = Cache::memory().await?;
let user: User = cache
.get_or("user:999", || async {
Ok(User {
id: 999,
name: "Fallback".to_string(),
})
})
.await?;
assert_eq!(user.name, "Fallback");
let user = User {
id: 999,
name: "Updated".to_string(),
};
cache.set("user:999", &user).await?;
let cached: User = cache
.get_or("user:999", || async {
Ok(User {
id: 999,
name: "Fallback".to_string(),
})
})
.await?;
assert_eq!(cached.name, "Updated");
Ok(())
}
#[tokio::test]
async fn test_cache批量_operations() -> anyhow::Result<()> {
let cache: Cache<String, User> = Cache::memory().await?;
let users = vec![
("user:1", User { id: 1, name: "Alice".to_string() }),
("user:2", User { id: 2, name: "Bob".to_string() }),
("user:3", User { id: 3, name: "Charlie".to_string() }),
];
cache.set_many(users).await?;
let keys = vec!["user:1", "user:2", "user:3"];
let results: std::collections::HashMap<String, User> =
cache.get_many(keys).await?;
assert_eq!(results.len(), 3);
assert_eq!(results.get("user:1").unwrap().name, "Alice");
assert_eq!(results.get("user:2").unwrap().name, "Bob");
assert_eq!(results.get("user:3").unwrap().name, "Charlie");
Ok(())
}
#[tokio::test]
async fn test_cache_clear() -> anyhow::Result<()> {
let cache: Cache<String, User> = Cache::memory().await?;
cache
.set_many(vec![
("user:1", User { id: 1, name: "Alice".to_string() }),
("user:2", User { id: 2, name: "Bob".to_string() }),
])
.await?;
cache.clear().await?;
let len = cache.len().await?;
assert_eq!(len, 0);
Ok(())
}
#[tokio::test]
async fn test_cache_stats() -> anyhow::Result<()> {
let cache: Cache<String, User> = Cache::memory().await?;
cache
.set_many(vec![
("user:1", User { id: 1, name: "Alice".to_string() }),
("user:2", User { id: 2, name: "Bob".to_string() }),
])
.await?;
let stats = cache.stats().await?;
assert!(!stats.is_empty());
Ok(())
}
}