use hypen_engine::lifecycle::resource::{Resource, ResourceCache};
use std::sync::{Arc, Mutex};
#[test]
fn test_resource_new() {
let data = vec![1, 2, 3, 4, 5];
let resource = Resource::new(data.clone(), "image/png");
assert_eq!(*resource.data, data);
assert_eq!(resource.mime_type, "image/png");
assert!(resource.fingerprint.is_none());
}
#[test]
fn test_resource_with_fingerprint() {
let resource = Resource::new(vec![1, 2, 3], "text/plain");
let resource_with_fp = resource.with_fingerprint("abc123hash");
assert_eq!(resource_with_fp.fingerprint, Some("abc123hash".to_string()));
assert_eq!(resource_with_fp.mime_type, "text/plain");
}
#[test]
fn test_cache_insert_and_get() {
let mut cache = ResourceCache::new();
let resource = Resource::new(vec![10, 20, 30], "image/jpeg");
cache.insert("photo.jpg", resource.clone());
let retrieved = cache.get("photo.jpg").unwrap();
assert_eq!(*retrieved.data, vec![10, 20, 30]);
assert_eq!(retrieved.mime_type, "image/jpeg");
}
#[test]
fn test_cache_get_nonexistent_resource() {
let mut cache = ResourceCache::new();
let result = cache.get("missing.png");
assert!(result.is_none());
}
#[test]
fn test_cache_remove_resource() {
let mut cache = ResourceCache::new();
cache.insert("test.png", Resource::new(vec![1, 2, 3], "image/png"));
assert_eq!(cache.size(), 1);
let removed = cache.remove("test.png");
assert!(removed.is_some());
assert_eq!(*removed.unwrap().data, vec![1, 2, 3]);
assert_eq!(cache.size(), 0);
}
#[test]
fn test_cache_clear() {
let mut cache = ResourceCache::new();
cache.insert("img1.png", Resource::new(vec![1], "image/png"));
cache.insert("img2.jpg", Resource::new(vec![2], "image/jpeg"));
cache.insert("font.woff", Resource::new(vec![3], "font/woff"));
assert_eq!(cache.size(), 3);
cache.clear();
assert_eq!(cache.size(), 0);
assert!(cache.get("img1.png").is_none());
assert!(cache.get("img2.jpg").is_none());
assert!(cache.get("font.woff").is_none());
}
#[test]
fn test_cache_size() {
let mut cache = ResourceCache::new();
assert_eq!(cache.size(), 0);
cache.insert("res1", Resource::new(vec![1], "image/png"));
assert_eq!(cache.size(), 1);
cache.insert("res2", Resource::new(vec![2], "image/png"));
assert_eq!(cache.size(), 2);
cache.remove("res1");
assert_eq!(cache.size(), 1);
cache.clear();
assert_eq!(cache.size(), 0);
}
#[test]
fn test_cache_with_custom_fetcher() {
let mut cache = ResourceCache::new();
cache.set_fetcher(|url| {
if url.starts_with("http://") {
Some(Resource::new(vec![1, 2, 3], "text/html"))
} else {
None
}
});
let resource = cache.get("http://example.com");
assert!(resource.is_some());
assert_eq!(*resource.unwrap().data, vec![1, 2, 3]);
assert_eq!(cache.size(), 1);
}
#[test]
fn test_fetcher_caches_result() {
let mut cache = ResourceCache::new();
let fetch_count = Arc::new(Mutex::new(0));
let fetch_count_clone = Arc::clone(&fetch_count);
cache.set_fetcher(move |url| {
if url == "counted.txt" {
*fetch_count_clone.lock().unwrap() += 1;
Some(Resource::new(vec![99], "text/plain"))
} else {
None
}
});
cache.get("counted.txt");
cache.get("counted.txt");
assert_eq!(*fetch_count.lock().unwrap(), 1);
assert_eq!(cache.size(), 1);
}
#[test]
fn test_fetcher_returns_none_for_unknown_url() {
let mut cache = ResourceCache::new();
cache.set_fetcher(|url| {
if url == "known.png" {
Some(Resource::new(vec![5, 6, 7], "image/png"))
} else {
None
}
});
let result = cache.get("unknown.png");
assert!(result.is_none());
assert_eq!(cache.size(), 0);
}
#[test]
fn test_cache_default() {
let cache = ResourceCache::default();
assert_eq!(cache.size(), 0);
}
#[test]
fn test_resource_clone() {
let original = Resource::new(vec![1, 2, 3], "image/png").with_fingerprint("hash123");
let cloned = original.clone();
assert_eq!(*cloned.data, vec![1, 2, 3]);
assert_eq!(cloned.mime_type, "image/png");
assert_eq!(cloned.fingerprint, Some("hash123".to_string()));
assert!(Arc::ptr_eq(&original.data, &cloned.data));
}
#[test]
fn test_cache_overwrites_on_duplicate_insert() {
let mut cache = ResourceCache::new();
cache.insert("image.png", Resource::new(vec![1, 2, 3], "image/png"));
cache.insert("image.png", Resource::new(vec![4, 5, 6], "image/jpeg"));
let resource = cache.get("image.png").unwrap();
assert_eq!(*resource.data, vec![4, 5, 6]);
assert_eq!(resource.mime_type, "image/jpeg");
assert_eq!(cache.size(), 1); }
#[test]
fn test_remove_nonexistent_resource_returns_none() {
let mut cache = ResourceCache::new();
let result = cache.remove("nonexistent.png");
assert!(result.is_none());
}
#[test]
fn test_cache_preserves_insertion_order() {
let mut cache = ResourceCache::new();
cache.insert("first.png", Resource::new(vec![1], "image/png"));
cache.insert("second.jpg", Resource::new(vec![2], "image/jpeg"));
cache.insert("third.gif", Resource::new(vec![3], "image/gif"));
let first = cache.get("first.png").unwrap();
let second = cache.get("second.jpg").unwrap();
let third = cache.get("third.gif").unwrap();
assert_eq!(*first.data, vec![1]);
assert_eq!(*second.data, vec![2]);
assert_eq!(*third.data, vec![3]);
}
#[test]
fn test_resource_with_large_data() {
let large_data = vec![0u8; 1024 * 1024];
let resource = Resource::new(large_data.clone(), "application/octet-stream");
assert_eq!(resource.data.len(), 1024 * 1024);
assert_eq!(resource.mime_type, "application/octet-stream");
}
#[test]
fn test_fetcher_with_different_mime_types() {
let mut cache = ResourceCache::new();
cache.set_fetcher(|url| match url {
url if url.ends_with(".png") => Some(Resource::new(vec![1], "image/png")),
url if url.ends_with(".jpg") => Some(Resource::new(vec![2], "image/jpeg")),
url if url.ends_with(".txt") => Some(Resource::new(vec![3], "text/plain")),
_ => None,
});
let png = cache.get("image.png").unwrap();
let jpg = cache.get("photo.jpg").unwrap();
let txt = cache.get("file.txt").unwrap();
assert_eq!(png.mime_type, "image/png");
assert_eq!(jpg.mime_type, "image/jpeg");
assert_eq!(txt.mime_type, "text/plain");
}