#![cfg(feature = "image")]
use std::io::Write;
use rust_widgets::image::cache::{self, stats};
fn png_fixture() -> Vec<u8> {
vec![
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44,
0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f,
0x15, 0xc4, 0x89, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0xf8,
0xcf, 0xc0, 0xf0, 0x1f, 0x00, 0x05, 0x00, 0x01, 0xff, 0x89, 0x99, 0x3d, 0x1d, 0x00, 0x00,
0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
]
}
#[test]
fn a_shared_icon_decodes_once_for_the_whole_toolbar() {
let path = std::env::temp_dir().join("rw_cache_check_icon.png");
std::fs::File::create(&path)
.and_then(|mut file| file.write_all(&png_fixture()))
.expect("write the fixture");
cache::clear();
let before = stats();
let mut first: Option<usize> = None;
for _ in 0..12 {
let pixels = cache::file_rgba8_or_none(&path).expect("the icon loads");
let address = std::sync::Arc::as_ptr(&pixels) as usize;
assert_eq!(*first.get_or_insert(address), address, "one allocation for twelve buttons");
}
let after = stats();
let requests = after.requests - before.requests;
let misses = after.misses - before.misses;
let hits = after.hits - before.hits;
println!("twelve buttons on one icon: requests={requests} misses={misses} hits={hits}");
assert_eq!(requests, 12, "twelve requests");
assert_eq!(misses, 1, "one decode, not twelve");
assert_eq!(hits, 11, "eleven saved");
let mid = stats();
let _ = rust_widgets::image::Image::from_bytes_rgba8_shared(&png_fixture())
.expect("the image decodes");
let end = stats();
println!(
"one image-view request: requests={} misses={}",
end.requests - mid.requests,
end.misses - mid.misses
);
assert_eq!(end.hits + end.misses, end.requests, "the books must balance");
assert!(end.bytes > 0, "the cache reports what it holds");
cache::set_budget_bytes(0);
cache::clear();
let before = stats();
for _ in 0..3 {
let _ = cache::file_rgba8_or_none(&path).expect("still decodes");
}
let after = stats();
println!(
"with a zero budget: misses={} hits={}",
after.misses - before.misses,
after.hits - before.hits
);
assert_eq!(after.misses - before.misses, 3, "a disabled cache decodes every time");
assert_eq!(after.hits - before.hits, 0, "and claims no saves");
let _ = std::fs::remove_file(&path);
println!("decode cache checks passed.");
}