use std::borrow::Borrow;
use ritecache::Cache;
use ritecache::LruCache;
use ritecache::Meter;
#[test]
fn test_put_and_get() {
let mut cache = LruCache::new(2);
cache.put(1, 10);
cache.put(2, 20);
assert_eq!(cache.get_mut(&1), Some(&mut 10));
assert_eq!(cache.get_mut(&2), Some(&mut 20));
assert_eq!(cache.len(), 2);
assert_eq!(cache.size(), 2);
}
#[test]
fn test_put_update() {
let mut cache = LruCache::new(1);
cache.put("1", 10);
cache.put("1", 19);
assert_eq!(cache.get_mut("1"), Some(&mut 19));
assert_eq!(cache.len(), 1);
}
#[test]
fn test_contains() {
let mut cache = LruCache::new(1);
cache.put("1", 10);
assert!(cache.contains("1"));
}
#[test]
fn test_expire_lru() {
let mut cache = LruCache::new(2);
cache.put("foo1", "bar1");
cache.put("foo2", "bar2");
cache.put("foo3", "bar3");
assert!(cache.get_mut("foo1").is_none());
cache.put("foo2", "bar2update");
cache.put("foo4", "bar4");
assert!(cache.get_mut("foo3").is_none());
}
#[test]
fn test_pop() {
let mut cache = LruCache::new(2);
cache.put(1, 10);
cache.put(2, 20);
assert_eq!(cache.len(), 2);
let opt1 = cache.pop(&1);
assert!(opt1.is_some());
assert_eq!(opt1.unwrap(), 10);
assert!(cache.get_mut(&1).is_none());
assert_eq!(cache.len(), 1);
}
#[test]
fn test_change_capacity() {
let mut cache = LruCache::new(2);
assert_eq!(cache.capacity(), 2);
cache.put(1, 10);
cache.put(2, 20);
cache.set_capacity(1);
assert!(cache.get_mut(&1).is_none());
assert_eq!(cache.capacity(), 1);
}
#[test]
fn test_debug() {
let mut cache = LruCache::new(3);
cache.put(1, 10);
cache.put(2, 20);
cache.put(3, 30);
assert_eq!(format!("{:?}", cache), "{3: 30, 2: 20, 1: 10}");
cache.put(2, 22);
assert_eq!(format!("{:?}", cache), "{2: 22, 3: 30, 1: 10}");
cache.put(6, 60);
assert_eq!(format!("{:?}", cache), "{6: 60, 2: 22, 3: 30}");
cache.get_mut(&3);
assert_eq!(format!("{:?}", cache), "{3: 30, 6: 60, 2: 22}");
cache.set_capacity(2);
assert_eq!(format!("{:?}", cache), "{3: 30, 6: 60}");
}
#[test]
fn test_remove() {
let mut cache = LruCache::new(3);
cache.put(1, 10);
cache.put(2, 20);
cache.put(3, 30);
cache.put(4, 40);
cache.put(5, 50);
cache.pop(&3);
cache.pop(&4);
assert!(cache.get_mut(&3).is_none());
assert!(cache.get_mut(&4).is_none());
cache.put(6, 60);
cache.put(7, 70);
cache.put(8, 80);
assert!(cache.get_mut(&5).is_none());
assert_eq!(cache.get_mut(&6), Some(&mut 60));
assert_eq!(cache.get_mut(&7), Some(&mut 70));
assert_eq!(cache.get_mut(&8), Some(&mut 80));
}
#[test]
fn test_clear() {
let mut cache = LruCache::new(2);
cache.put(1, 10);
cache.put(2, 20);
cache.clear();
assert!(cache.get_mut(&1).is_none());
assert!(cache.get_mut(&2).is_none());
assert_eq!(format!("{:?}", cache), "{}");
}
#[test]
fn test_iter() {
let mut cache = LruCache::new(3);
cache.put(1, 10);
cache.put(2, 20);
cache.put(3, 30);
cache.put(4, 40);
cache.put(5, 50);
assert_eq!(cache.iter().collect::<Vec<_>>(), [(&3, &30), (&4, &40), (&5, &50)]);
assert_eq!(cache.iter_mut().collect::<Vec<_>>(), [(&3, &mut 30), (&4, &mut 40), (&5, &mut 50)]);
assert_eq!(cache.iter().rev().collect::<Vec<_>>(), [(&5, &50), (&4, &40), (&3, &30)]);
assert_eq!(
cache.iter_mut().rev().collect::<Vec<_>>(),
[(&5, &mut 50), (&4, &mut 40), (&3, &mut 30)]
);
}
struct VecLen;
impl<K, T> Meter<K, Vec<T>> for VecLen {
type Measure = usize;
fn measure<Q: ?Sized>(&self, _: &Q, v: &Vec<T>) -> usize
where
K: Borrow<Q>,
{
v.len()
}
}
#[test]
fn test_metered_cache() {
let mut cache = LruCache::with_meter(5, VecLen);
cache.put("foo1", vec![1, 2]);
assert_eq!(cache.size(), 2);
cache.put("foo2", vec![3, 4]);
cache.put("foo3", vec![5, 6]);
assert_eq!(cache.size(), 4);
assert!(!cache.contains("foo1"));
cache.put("foo2", vec![7, 8]);
cache.put("foo4", vec![9, 10]);
assert_eq!(cache.size(), 4);
assert!(!cache.contains("foo3"));
assert_eq!(cache.get("foo2"), Some(&vec![7, 8]));
}
#[test]
fn test_metered_cache_reinsert_larger() {
let mut cache = LruCache::with_meter(5, VecLen);
cache.put("foo1", vec![1, 2]);
cache.put("foo2", vec![3, 4]);
assert_eq!(cache.size(), 4);
cache.put("foo2", vec![5, 6, 7, 8]);
assert_eq!(cache.size(), 4);
assert!(!cache.contains("foo1"));
}
#[test]
fn test_metered_cache_oversize() {
let mut cache = LruCache::with_meter(2, VecLen);
cache.put("foo1", vec![1, 2]);
cache.put("foo2", vec![3, 4, 5, 6]);
assert_eq!(cache.size(), 0);
assert!(!cache.contains("foo1"));
assert!(!cache.contains("foo2"));
}
#[cfg(feature = "heapsize")]
#[test]
fn test_heapsize_cache() {
use crate::HeapSize;
let mut cache = LruCache::<&str, (u8, u8, u8), _, _>::with_meter(8, HeapSize);
cache.put("foo1", (1, 2, 3));
cache.put("foo2", (4, 5, 6));
cache.put("foo3", (7, 8, 9));
assert!(!cache.contains("foo1"));
cache.put("foo2", (10, 11, 12));
cache.put("foo4", (13, 14, 15));
assert!(!cache.contains("foo3"));
}